%{ (* Peter Sewell 2003 *) (* thanks to Mark Shinwell for mosmlyac expertise *) open Syntax; exception BUG; fun convert [] = raise BUG | convert [expr] = expr | convert (expr::exprs) = App_raw (convert exprs, expr); %} %token INT UNIT BOOL ARROW %token INTEGER %token IDENT %token TRUE FALSE %token PLUS GTEQT %token IF THEN ELSE %token ASSIGN DEREF %token SKIP SEQ %token WHILE DO %token FN COLON DOUBLEARROW %token LET VAL IN END REC %token LPAREN RPAREN %token EOF %token EQUALS COMMA %right ARROW %start main %start store %type seqexp_1 %type seqexp_2 %type main %type expr %type appexpr %type atexpr %type type %type <(string*int) list> store %% main: expr EOF { $1 } ; seqexp_1: expr SEQ seqexp_1 { Seq_raw ($1, $3) } | expr { $1 } ; seqexp_2: expr SEQ seqexp_1 { Seq_raw ($1, $3) } ; atexpr: IDENT { Var_raw $1 } | TRUE { Boolean_raw true } | FALSE { Boolean_raw false } | INTEGER { Integer_raw $1 } | SKIP { Skip_raw } | LPAREN seqexp_2 RPAREN { $2 } | LPAREN expr RPAREN { $2 } | DEREF IDENT { Deref_raw $2 } | LET VAL IDENT COLON type EQUALS expr IN expr END { Let_raw ($3,$5,$7,$9) } | LET VAL REC IDENT COLON type EQUALS FN IDENT COLON type DOUBLEARROW expr IN expr END { Letrecfn_raw ($4,$6,$9,$11,$13,$15) } | LET VAL REC IDENT COLON type EQUALS LPAREN FN IDENT COLON type DOUBLEARROW expr RPAREN IN expr END { Letrecfn_raw ($4,$6,$10,$12,$14,$17) } ; appexpr: atexpr { [$1] } | appexpr atexpr { $2 :: $1 } ; expr: appexpr { convert $1 } | IDENT ASSIGN expr { Assign_raw ($1, $3) } | WHILE expr DO expr { While_raw ($2, $4) } | FN IDENT COLON type DOUBLEARROW expr { Fn_raw ($2, $4, $6) } | IF expr THEN expr ELSE expr { If_raw ($2,$4,$6) } | atexpr PLUS expr { Op_raw ($1, Plus, $3) } | atexpr GTEQT expr { Op_raw ($1, GTEQ, $3) } ; type: LPAREN type RPAREN { $2 } | INT { int } | UNIT { unit } | BOOL { bool } | type ARROW type { func ( $1, $3) } ; store: EOF { [] }; | IDENT EQUALS INTEGER EOF { [ ($1, $3) ] } | IDENT EQUALS INTEGER COMMA store { ($1, $3) :: $5 } ;