import ErrM
}
-%name pStms Stms
-%name pExp Exp
+%name pProgram Program
-- no lexer declaration
%monad { Err } { thenM } { returnM }
'--' { PT _ (TS "--") }
'-' { PT _ (TS "-") }
'!' { PT _ (TS "!") }
+ ',' { PT _ (TS ",") }
'<' { PT _ (TS "<") }
'<=' { PT _ (TS "<=") }
'>' { PT _ (TS ">") }
'print' { PT _ (TS "print") }
'readBool' { PT _ (TS "readBool") }
'readInt' { PT _ (TS "readInt") }
+ 'return' { PT _ (TS "return") }
'true' { PT _ (TS "true") }
'while' { PT _ (TS "while") }
| 'bool' { TBool }
-Stms :: { Stms }
-Stms : ListStm { Program (reverse $1) }
+Program :: { Program }
+Program : ListFuncStm { Program (reverse $1) }
Stm :: { Stm }
Stm : Exp ';' { SExp $1 }
| '{' ListStm '}' { SBlock (reverse $2) }
- | 'int' Ident '=' Exp ';' { declIntE_ $2 $4 }
- | 'bool' Ident '=' Exp ';' { declBoolE_ $2 $4 }
- | 'int' Ident ';' { declInt_ $2 }
- | 'bool' Ident ';' { declBool_ $2 }
+ | Type Ident '=' Exp ';' { SDecl $1 $2 $4 }
+ | Type Ident ';' { SDeclD $1 $2 }
| 'while' '(' Exp ')' Stm { SWhile $3 $5 }
| 'if' '(' Exp ')' Stm 'else' Stm { SIf $3 $5 $7 }
| 'if' '(' Exp ')' Stm { if_ $3 $5 }
| 'print' Exp ';' { SPrint $2 }
+ | 'return' Exp ';' { SReturn $2 }
Exp :: { Exp }
| '!' Exp3 { ENot $2 }
| 'readInt' { EReadI }
| 'readBool' { EReadB }
+ | Ident '(' ListExp ')' { EFunc $1 $3 }
| '(' Exp ')' { $2 }
| ListStm Stm { flip (:) $1 $2 }
+ListExp :: { [Exp] }
+ListExp : {- empty -} { [] }
+ | Exp { (:[]) $1 }
+ | Exp ',' ListExp { (:) $1 $3 }
+
+
+Decl :: { Decl }
+Decl : Type Ident { Decl $1 $2 }
+
+
+ListDecl :: { [Decl] }
+ListDecl : {- empty -} { [] }
+ | Decl { (:[]) $1 }
+ | Decl ',' ListDecl { (:) $1 $3 }
+
+
+Func :: { Func }
+Func : Type Ident '(' ListDecl ')' '{' ListStm '}' { Func $1 $2 $4 (reverse $7) }
+
+
+ListFunc :: { [Func] }
+ListFunc : {- empty -} { [] }
+ | ListFunc Func { flip (:) $1 $2 }
+
+
+FuncStm :: { FuncStm }
+FuncStm : Stm { S $1 }
+ | Func { F $1 }
+
+
+ListFuncStm :: { [FuncStm] }
+ListFuncStm : {- empty -} { [] }
+ | ListFuncStm FuncStm { flip (:) $1 $2 }
+
+
Op0 :: { Op }
Op0 : '<' { Lt }
| '<=' { ELt }
Bad $ "syntax error at " ++ tokenPos ts ++ if null ts then [] else (" before " ++ unwords (map prToken (take 4 ts)))
myLexer = tokens
-declIntE_ x_ e_ = SDecl TInt x_ e_
-declBoolE_ x_ e_ = SDecl TBool x_ e_
-declInt_ x_ = SDecl TInt x_ (EInt 0)
-declBool_ x_ = SDecl TBool x_ (EBool False)
if_ e_ s_ = SIf e_ s_ SNoop
compExp_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_
op1_ e1_ o_ e2_ = BiOpExp e1_ o_ e2_