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 EndProcedure
We 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