3 * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
4 * Modified: Frank Pfenning <fp@cs.cmu.edu>
9 (* for simplicity, we only mark expressions, not statements *)
11 (* mark e with region (left, right) in source file *)
12 fun mark (e, (left, right)) = A.Marked (Mark.mark' (e, ParseState.ext (left, right)))
14 (* create lval from expression; here just an id *)
15 (* generates error if not an identifier *)
16 fun make_lval (A.Var(id)) ext = id
17 | make_lval (A.Marked(marked_exp)) ext =
18 make_lval (Mark.data marked_exp) (Mark.ext marked_exp)
19 | make_lval _ ext = ( ErrorMsg.error ext "not a variable" ;
22 (* expand_asnop (exp1, "op=", exp2) region = "exp1 = exp1 op exps"
23 * or = "exp1 = exp2" if asnop is "="
24 * generates error if exp1 is an lval (identifier)
25 * syntactically expands a compound assignment operator
27 fun expand_asnop (exp1, NONE, exp2) (left, right) =
28 A.Assign(make_lval exp1 NONE, exp2)
29 | expand_asnop (exp1, SOME(oper), exp2) (left, right) =
30 A.Assign(make_lval exp1 NONE,
31 mark(A.OpExp(oper, [exp1, exp2]), (left, right)))
34 %header (functor L1LrValsFn (structure Token : TOKEN))
39 | INTNUM of Word32.word
40 | IDENT of Symbol.symbol
42 | PLUS | MINUS | STAR | SLASH | PERCENT
43 | ASSIGN | PLUSEQ | MINUSEQ | STAREQ | SLASHEQ | PERCENTEQ
46 | UNARY | ASNOP (* dummy *)
55 | asnop of A.oper option
57 %verbose (* print summary of errors *)
58 %pos int (* positions *)
66 %left STAR SLASH PERCENT
72 program : LBRACE stms return RBRACE
75 return : RETURN exp SEMI (A.Return exp)
78 | stm stms (stm :: stms)
80 stm : simp SEMI (simp)
81 simp : exp asnop exp %prec ASNOP
82 (expand_asnop (exp1, asnop, exp2) (exp1left, exp2right))
84 exp : LPAREN exp RPAREN (exp)
85 | INTNUM (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright)))
86 | IDENT (mark (A.Var(IDENT), (IDENTleft,IDENTright)))
87 | exp PLUS exp (mark (A.OpExp (A.PLUS, [exp1,exp2]), (exp1left,exp2right)))
88 | exp MINUS exp (mark (A.OpExp (A.MINUS, [exp1,exp2]), (exp1left,exp2right)))
89 | exp STAR exp (mark (A.OpExp (A.TIMES, [exp1,exp2]), (exp1left,exp2right)))
90 | exp SLASH exp (mark (A.OpExp (A.DIVIDEDBY, [exp1,exp2]), (exp1left,exp2right)))
91 | exp PERCENT exp (mark (A.OpExp (A.MODULO, [exp1,exp2]), (exp1left,exp2right)))
92 | MINUS exp %prec UNARY (mark (A.OpExp (A.NEGATIVE, [exp]), (MINUSleft,expright)))
95 | PLUSEQ (SOME(A.PLUS))
96 | MINUSEQ (SOME(A.MINUS))
97 | STAREQ (SOME(A.TIMES))
98 | SLASHEQ (SOME(A.DIVIDEDBY))
99 | PERCENTEQ (SOME(A.MODULO))