; fcallparm.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) Protected *V.SSymbol = LookupSymbol(Name) If *V And *V\Kind = #SKind_Variable ProcedureReturn VarRef(*V) Else Error("Undeclared variable: " + Name) EndIf EndProcedure Declare Expression() Procedure FunctionParameters(*F.SFunction) Protected ParamStackSize = *F\ParamCount*4 ; Note, it's 4 because we use longs. Doubles and quads would be 8! Protected I Emit2("sub ", "esp", Str(ParamStackSize)) ; Make room on the stack for the parameters For I = 0 To *F\ParamCount-1 Expression() Emit("mov [esp+" + Str(I*4) + "], eax") If I <> *F\ParamCount-1 ; If the current parameter is NOT the last one MatchWhite(',') ; Get a comma and whitespace to prepare for the next parameter EndIf Next EndProcedure Procedure FunctionCall(Name.s) Protected *F.SFunction = LookupSymbolNoScopeResolve(Name) If *F And *F\Kind = #SKind_Function If *F\ParamCount > 0 FunctionParameters(*F) EndIf Emit("call " + *F\Ref) Else Error("Undeclared function: " + Name) EndIf EndProcedure Procedure Value() ; value ::= | | | '(' ')' Protected Name.s If IsDigit(Look) Emit("mov eax, " + GetInteger()) ElseIf IsAlpha(Look) Name = GetName() If Look = '(' Match('(') FunctionCall(Name) Match(')') Else Emit("mov eax, " + VarValue(Name)) EndIf 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() If Look = '(' Match('(') FunctionCall(N) Match(')') Else Select N Case "var": VariableDeclaration() Default: Assignment(N) EndSelect EndIf 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("") Emit("push 0") Emit("call _ExitProcess") Emit("; Global variables: ") EnumerateSymbols(@GlobalAsmDefinition()) EndProcedure ; Add a few functions to the symbol table so we can call them *F.SFunction = AddFunction("MyFunc") *F\Type = #TyLong *F\ParamCount = 1 *F\ParamTypes[0] = #TyLong *F.SFunction = AddFunction("DoCoolStuff") *F\Type = #TyLong *f\ParamCount = 3 *f\ParamTypes[0] = #TyLong *f\ParamTypes[1] = #TyLong *f\ParamTypes[2] = #TyLong InitMulti() Program() Footer() Input() ; IDE Options = PureBasic 5.31 (Windows - x64) ; CursorPosition = 156 ; FirstLine = 96 ; Folding = --- ; EnableXP ; EnableUser ; EnableCompileCount = 0 ; EnableBuildCount = 0