(***************************************************** ** IMPLEMENTS THE GRAMMAR RULE A -> idt assignop E ** ** includes type checking code ** *****************************************************) procedure A; var ptr : EntryPtr; etype : vartypes; begin ptr:=lookup(Lexeme); {save value for later use} if (ptr^.class = constClass) then begin error('Attempt to modify constant value'); halt; end; if (ptr^.class = procclass) then begin error('Illegal value on left side of assignment'); halt; end; match(idt); match(assignop); E(etype); {synthesize type of the expression} if (ptr^.varType <> etype) then begin error('Destination type does not match type of expression'); halt; end; end; {A} procedure E(var etype:varTypes); (***************************************************** ** IMPLEMENTS THE GRAMMAR RULE E -> T R ** ** Expression = Term RestOfExpression ** ** includes type checking code ** *****************************************************) var rin : varTypes; ttyp : varTypes; begin T(ttyp); {synthsize type of term} rin := ttyp; {now R must inherit type of first term } R(rin); etype := ttyp; {return back the syntesized type } end; {E} procedure T(var ttyp : varTypes); (***************************************************** ** IMPLEMENTS THE GRAMMAR RULE T -> idt | ** ** numt| ** ** ( E ) ** ** includes type checking code ** *****************************************************) begin if token = idt then begin ptr:=lookup(Lexeme); if ptr = nil then begin error('undeclared variable'); halt; end else begin ttyp := ptr^.varType; match(idt); end; end {token = idt} else if token = num then begin if pos(".",lexeme)=0 then begin ttyp := integert else ttyp := floatt; match(numt); end else begin match(lparen); E(ttyp); {ttyp will be synthesized later!} match(rparen); end; end; {T} procedure R(rin : varTypes); (***************************************************** ** IMPLEMENTS THE GRAMMAR RULE R -> addop T R | ** ** epsilon ** ** RestOfExpression = addop Term RestOfExpression | ** ** nothing else!! ** ** includes type checking code ** *****************************************************) var ttyp : varTypes; begin if token = addop then begin match(addop); T(ttyp); {synthesize ttyp } typecheck(rin, ttyp); {check for same valid types} R(ttyp); {Again let R inherit a type using shorter version} end; end; {R} procedure typecheck(a,b : varTypes); (* IMPLEMENTS OUR TYPE SYSTEM *) begin if (a=chart) or ( b = chart) then begin error('Characters cannot be used in arithmetic expressions'); halt; end else if b <> a then begin error('Type mismatch error'); halt; end; end; {Typecheck}