An interpreted, lazy lisp.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

111 lines
3.3 KiB

||| Defines parsing rules for literals of the Rose language.
module Rose.Parser.Literal
import Text.Parser
import Text.Parser.Core
import Text.Lexer
import Rose.Lexer
import Rose.Parser.Core
import Rose.Data.Atom
import Rose.Data.SExpression
import Rose.Data.Form
||| Parses a symbol token, returning the SE representation of the symbol.
export
symbol : Rule SE
symbol = (terminal
(\x => case (tok x) of
(TkSymbol s) => pure $ MkAtom (MkSymbol s)
_ => Nothing)) </> NotASymbol
where NotASymbol : String
NotASymbol = "Expected a symbol, such as x, y, or z."
||| atoms is a rule for parsing atoms of the Rose language.
export total
atoms : Rule SE
atoms = terminal
(\x => untok (tok x)) </> NotAnAtom
where untok : Token -> Maybe SE
untok (TkNum i) = Just $ MkAtom (MkInteger i)
untok (TkChar c) = Just $ MkAtom (MkChar c)
untok (TkString s) = Just $ MkAtom (MkString s)
untok (TkSymbol s) = Just $ MkAtom (MkSymbol s)
untok (TkBool b) = Just $ MkAtom (MkBool b)
untok _ = Nothing
NotAnAtom : String
NotAnAtom = "Expected a value or symbol, such as 1, x, or \"foo\"."
||| punct defines a punctuation rule for the Rose language.
||| Used to define rules for parens, brackets, etc.
export
punct : Token -> Rule ()
punct t = terminal
(\x => if (tok x) == t
then Just ()
else Nothing) </> NotPunctuation
where NotPunctuation : String
NotPunctuation = "Expected the start or close of a bracket or list, (, ), [, or, ]."
||| Parses a left bracket.
export
lbrack : Rule ()
lbrack = punct LBracket </> ExpectedLeftBracket
where ExpectedLeftBracket : String
ExpectedLeftBracket = "Expected ["
||| Parses a right bracket.
export
rbrack : Rule ()
rbrack = punct RBracket </> ExpectedRightBracket
where ExpectedRightBracket : String
ExpectedRightBracket = "Expected ]"
||| Parses a left parentheses.
export
lparen : Rule ()
lparen = punct LParen </> ExpectedLeftParenthesis
where ExpectedLeftParenthesis : String
ExpectedLeftParenthesis = "Expected ("
||| Parses a right parentheses.
export
rparen : Rule ()
rparen = punct RParen </> ExpectedRightParenthesis
where ExpectedRightParenthesis : String
ExpectedRightParenthesis = "Expected )"
||| Parses a finite list.
||| This function is required to parse lists within lists:
||| e.g. ((a b) c)
finite : Rule SE
finite =
(lparen <|> lbrack)
>>= \_ => many (atoms <|> finite)
>>= \result => (rparen <|> rbrack)
>>= \_ => pure $ fromList result
mutual
||| list is a rule for parsing lists in the Rose language
||| (y . (x . ())
export
list : Rule SE
list =
between lparen rparen
$ many (atoms <|> finite)
>>= \as => many (list <|> array)
>>= \rest => pure $ fromList (as ++ rest)
||| array is a rule for parsing 'arrays' in the Rose language
||| [y . [x . []]]
||| arrays and lists are alternative syntax for the same underlying form
||| an s-expression. In Rose, brackets and parens may be used interchangeably.
export
array : Rule SE
array =
between lbrack rbrack
$ many (atoms <|> finite) >>= \as => many (list <|> array)
>>= \rest => pure $ fromList (as ++ rest)
||| Parses an s-expression surrounded in either parentheses or brackets.
export
expression : Rule SE
expression = (list <|> array)