; symsimple.pb IncludeFile "..\base2.pb" IncludeFile "..\labels.pb" IncludeFile "..\symboltable.pb" Procedure.s VarRef(*V.SVariable) Select *V\RefKind Case #Ref_Global ProcedureReturn "[v_" + *V\Name + "]" Default Error("Unknown variable scope kind") EndSelect EndProcedure ; Return the asm for accessing the value of a variable Procedure.s VarValue(Name.s) *V = LookupSymbol(Name) If *V ProcedureReturn VarRef(*V) Else ; Here we can either give an error message saying ; that the variable isn't declared, or automatically ; declare it, depending on how we want our language ; to work Error("Undeclared variable: " + Name) EndIf EndProcedure Procedure Value() ; value ::= | | '(' ')' If IsDigit(Look) Emit("mov eax, " + GetInteger()) ElseIf IsAlpha(Look) Emit("mov eax, " + VarValue(GetName())) Else Expected("value") EndIf EndProcedure Procedure Expression() ; expression ::= Value() EndProcedure Procedure Assignment(Name.s) ; assignment ::= = MatchWhite('=') Expression() Emit2("mov ", VarValue(Name), "eax") EndProcedure Procedure VariableDeclaration() ; vardecl ::= var as Protected Name.s Protected TypeS.s, TypeI.i Protected *V.SVariable ; Get name and type Name = GetName() If GetName() <> "as" Expected("as") EndIf TypeS = GetName() AddVariable(Name, TypeS, #Ref_Global, 0) EndProcedure Procedure Statement() Protected N.s N = GetName() Select N Case "var": VariableDeclaration() Default: Assignment(N) EndSelect EndProcedure Procedure Program() ; program ::= { } EatWhiteNewlines() While Look Statement() EatWhiteNewlines() Wend EndProcedure Procedure GlobalAsmDefinition(ScopedName.s, *V.SVariable) If *V\Kind = #SKind_Variable If *V\RefKind = #Ref_Global Emit("v_" + *v\Name + " dd 0") EndIf EndIf EndProcedure Procedure Footer() Emit("push 0") Emit("call _ExitProcess") Emit("; Global variables: ") EnumerateSymbols(@GlobalAsmDefinition()) EndProcedure InitMulti() Program() Footer() Input()