All pastes #1590600 Raw Copy code Copy link Edit

symsimple.pb

public unlisted text v1 · immutable
#1590600 ·published 2009-10-03 14:07 UTC
rendered paste body
; 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		::= <integer> | <variable> | '(' <expression> ')'
  If IsDigit(Look)
    Emit("mov  eax, " + GetInteger())
  ElseIf IsAlpha(Look)
    Emit("mov  eax, " + VarValue(GetName()))
  Else
    Expected("value")
  EndIf
EndProcedure

Procedure Expression()
  ; expression ::= <value>
  Value()
EndProcedure

Procedure Assignment(Name.s)
  ; assignment ::= <name> = <expression>
  MatchWhite('=')
  Expression()
  Emit2("mov  ", VarValue(Name), "eax")
EndProcedure

Procedure VariableDeclaration()
  ; vardecl ::= var <name> as <type>
  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    ::= { <assignment> }
  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()