lamb/parser2.hs

120 lines
2.5 KiB
Haskell
Raw Normal View History

2013-11-02 01:53:36 +00:00
{-# Language TemplateHaskell, QuasiQuotes, FlexibleContexts #-}
import Text.Peggy hiding (space)
2013-11-02 01:53:36 +00:00
import AST
[peggy|
2013-11-02 02:10:02 +00:00
top :: [AST] = statements !.
lineComment :: () = '--' (!'\n' .)* '\n' { () }
space :: () = [ \r\n\t] { () } / lineComment
2013-11-02 03:16:41 +00:00
statements :: [AST] = statement+
2013-11-02 02:10:02 +00:00
2013-11-02 03:16:41 +00:00
statement :: AST = expr "."
2013-11-02 01:53:36 +00:00
2013-11-02 03:34:46 +00:00
semistatements :: [AST]
= expr ";" semistatements { $1 : $2 }
/ expr { [$1] }
2013-11-02 02:17:09 +00:00
args :: AST
= expr ("," expr)+ { TupleConst ($1 : $2) }
/ expr? { case $1 of
Just x -> x
Nothing -> UnitConst }
2013-11-02 03:30:46 +00:00
patternlist :: Pattern
= pattern ("," pattern)+ { ListP ($1 : $2) }
/ pattern? { case $1 of
Just x -> ListP [x]
Nothing -> ListP [] }
2013-11-02 04:08:38 +00:00
patterntuple :: Pattern
= "(" "," ")" { TupleP [] }
/ "(" pattern ("," pattern)+ ")" { TupleP ($1 : $2) }
/ "(" pattern "," ")" { TupleP [$1] }
pattern :: Pattern
2013-11-02 03:30:46 +00:00
= pattern "::" pattern { ConsP $1 $2 }
/ "[" patternlist "]"
2013-11-02 04:08:38 +00:00
/ patterntuple
/ identifier { VarP $1 }
2013-11-02 03:16:41 +00:00
/ stringlit { StrP $1 }
/ integer { IntP $1 }
funpattern :: Pattern
= pattern ("," pattern)+ { TupleP ($1 : $2) }
/ pattern? { case $1 of
Just x -> x
Nothing -> UnitP }
2013-11-02 02:17:09 +00:00
2013-11-02 03:30:46 +00:00
listseq :: AST
= expr ("," expr)+ { ListConst ($1 : $2) }
/ expr? { case $1 of
Just x -> ListConst [x]
Nothing -> ListConst [] }
2013-11-02 04:08:38 +00:00
tuple :: AST
= "(" "," ")" { TupleConst [] }
/ "(" expr ("," expr)+ ")" { TupleConst ($1 : $2) }
/ "(" expr "," ")" { TupleConst [$1] }
2013-11-02 03:34:46 +00:00
doblock :: AST
= "do" semistatements "end" { Block $1 }
2013-11-02 04:17:36 +00:00
lambda :: AST
= "\\" funpattern "->" expr { Lambda [($1, $2)] }
def :: AST
= pattern "=" expr { Def $1 $2 }
2013-11-02 01:53:36 +00:00
expr :: AST
2013-11-02 02:17:09 +00:00
= expr "(" args ")" { Call $1 $2 }
2013-11-02 03:30:46 +00:00
/ expr "::" expr { Cons $1 $2 }
2013-11-02 02:10:02 +00:00
/ expr "+" fact { Add $1 $2 }
2013-11-02 01:53:36 +00:00
/ expr "-" fact { Sub $1 $2 }
2013-11-02 04:17:36 +00:00
/ def
/ lambda
/ identifier "(" funpattern ")" "->" expr { Defun $1 (Lambda [($2, $3)]) }
2013-11-02 01:53:36 +00:00
/ fact
fact :: AST
= fact "*" term { Mul $1 $2 }
/ fact "/" term { Div $1 $2 }
/ term
term :: AST
2013-11-02 04:08:38 +00:00
= tuple
/ "(" expr ")"
/ "[" listseq "]"
2013-11-02 03:34:46 +00:00
/ doblock
2013-11-02 03:16:41 +00:00
/ stringlit { StrConst $1 }
/ integer { IntConst $1 }
2013-11-02 02:10:02 +00:00
/ identifier { Var $1 }
2013-11-02 03:16:41 +00:00
stringlit ::: String = '\"' charlit* '\"'
charlit :: Char
= '\\' escChar
/ [^\"\\]
escChar :: Char
= '\"' { '\"' }
/ '\\' { '\\' }
/ '/' { '/' }
/ 'b' { '\b' }
/ 'f' { '\f' }
/ 'n' { '\n' }
/ 'r' { '\r' }
/ 't' { '\t' }
2013-11-02 02:10:02 +00:00
identifier ::: String
= [a-zA-Z_] [a-zA-Z0-9_'?!]* { $1 : $2 }
2013-11-02 01:53:36 +00:00
integer ::: Integer
= [0-9] [0-9]* { read ($1 : $2) }
2013-11-02 01:53:36 +00:00
|]
main :: IO ()
main = print . parseString top "<stdin>" =<< getContents