digit ::= 0..9
integer ::= <digit> {<digit>}
value ::= <integer> | '(' <expression> ')'
mulop ::= * | /
addop ::= + | -
mulexp ::= <value> { <mulop> <value> }
addexp ::= <mulexp> { <addop> <mulexp> }
expression ::= <addexp>A variable can represent a value, right? In fact, we don't actually want the variable itself, we want the value stored in that variable.So we can add a bit to our grammar:
name ::= <alpha> { <alpha> | <digit> }
variable ::= <name>
value ::= <integer> | <variable> | '(' <expression> ')'Adding support for this in Value() should be easy:
Procedure Value()
; value ::= <integer> | <variable> | '(' <expression> ')'
If IsDigit(Look)
Emit("mov eax, " + GetInteger())
ElseIf IsAlpha(Look)
Emit("mov eax, " + VarValue(GetName()))
ElseIf Look = '('
MatchWhite('(')
Expression()
MatchWhite(')')
EndIf
EndProcedureWe can see an extra procedure here: VarValue(). What this does is to generate asm code to get the value of a variable by using a memory reference (the square brackets around the name). I have chosen to prefix all global variable names with v_ to avoid name collisions with internal labels (which we need when generating if's and so on).
Procedure.s VarValue(Var.s) ProcedureReturn "[v_" + Var + "]" EndProcedure
Done. This isn't getting any harder, is it? Of course we need to register all variables in a symbol table and actually allocate space for them, but that's easy anyways. Maybe I'll show it later.
No comments:
Post a Comment