working on symbol table

This commit is contained in:
Irmen de Jong 2022-03-04 22:26:46 +01:00
parent 094ecceaac
commit a03c4c3659
7 changed files with 196 additions and 18 deletions

View File

@ -12,6 +12,10 @@ class AsmGen(internal val program: Program,
println("\n** experimental 65(c)02 code generator **\n")
val stMaker = SymbolTableMaker()
val symbolTable = stMaker.make(program)
symbolTable.print()
println("..todo: create assembly code into ${options.outputDir.toAbsolutePath()}..")
return AssemblyProgram("dummy")
}

View File

@ -0,0 +1,82 @@
package prog8.codegen.experimental6502
import prog8.ast.base.DataType
import prog8.ast.base.Position
import prog8.ast.toHex
enum class StNodeType {
GLOBAL,
// MODULE, // not used with current scoping rules
BLOCK,
SUBROUTINE,
LABEL,
VARIABLE,
MEMVAR,
CONSTANT,
BUILTINFUNC
}
open class StNode(val name: String,
val type: StNodeType,
val position: Position,
val children: MutableMap<String, StNode> = mutableMapOf()
) {
lateinit var parent: StNode
val scopedName: List<String> by lazy {
if(type==StNodeType.GLOBAL)
emptyList()
else
parent.scopedName + name
}
fun printIndented(indent: Int) {
print(" ".repeat(indent))
when(type) {
StNodeType.GLOBAL -> print("SYMBOL-TABLE:")
StNodeType.BLOCK -> print("[B] ")
StNodeType.SUBROUTINE -> print("[S] ")
StNodeType.LABEL -> print("[L] ")
StNodeType.VARIABLE -> print("[V] ")
StNodeType.MEMVAR -> print("[M] ")
StNodeType.CONSTANT -> print("[C] ")
StNodeType.BUILTINFUNC -> print("[F] ")
}
printProperties()
println(" pos=$position sn=$scopedName")
children.forEach { (_, node) -> node.printIndented(indent+1) }
}
open fun printProperties() {
print("$name ")
}
}
class SymbolTable() : StNode("", StNodeType.GLOBAL, Position.DUMMY) {
fun print() = printIndented(0)
override fun printProperties() { }
}
class StVariable(name: String, val dt: DataType, position: Position) : StNode(name, StNodeType.VARIABLE, position) {
override fun printProperties() {
print("dt=$dt")
}
}
class StConstant(name: String, val dt: DataType, val value: Double, position: Position) :
StNode(name, StNodeType.CONSTANT, position) {
override fun printProperties() {
print("dt=$dt value=$value")
}
}
class StMemVar(name: String, val dt: DataType, val address: UInt, position: Position) :
StNode(name, StNodeType.MEMVAR, position
) {
override fun printProperties() {
print("dt=$dt address=${address.toHex()}")
}
}

View File

@ -0,0 +1,65 @@
package prog8.codegen.experimental6502
import prog8.ast.Program
import prog8.ast.base.Position
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.NumericLiteral
import prog8.ast.statements.Block
import prog8.ast.statements.Label
import prog8.ast.statements.Subroutine
import prog8.ast.statements.VarDecl
import prog8.ast.walk.IAstVisitor
import java.util.*
class SymbolTableMaker: IAstVisitor {
private val st = SymbolTable()
private val scopestack = Stack<StNode>()
fun make(program: Program): SymbolTable {
scopestack.clear()
st.children.clear()
this.visit(program)
program.builtinFunctions.names.forEach {
val node = StNode(it, StNodeType.BUILTINFUNC, Position.DUMMY)
node.parent = st
st.children[it] = node
}
return st
}
override fun visit(block: Block) {
val node = StNode(block.name, StNodeType.BLOCK, block.position)
node.parent = st
scopestack.push(node)
super.visit(block)
scopestack.pop()
st.children[node.name] = node
}
override fun visit(subroutine: Subroutine) {
val node = StNode(subroutine.name, StNodeType.SUBROUTINE, subroutine.position)
node.parent = scopestack.peek()
scopestack.push(node)
super.visit(subroutine)
scopestack.pop()
scopestack.peek().children[node.name] = node
}
override fun visit(decl: VarDecl) {
val node =
when(decl.type) {
VarDeclType.VAR -> StVariable(decl.name, decl.datatype, decl.position)
VarDeclType.CONST -> StConstant(decl.name, decl.datatype, (decl.value as NumericLiteral).number, decl.position)
VarDeclType.MEMORY -> StMemVar(decl.name, decl.datatype, (decl.value as NumericLiteral).number.toUInt(), decl.position)
}
node.parent = scopestack.peek()
node.parent.children[node.name] = node
}
override fun visit(label: Label) {
val node = StNode(label.name, StNodeType.LABEL, label.position)
node.parent = scopestack.peek()
node.parent.children[node.name] = node
}
}

View File

@ -60,7 +60,7 @@ class CX16MachineDefinition: IMachineDefinition {
zeropage = CX16Zeropage(compilerOptions)
}
// 6502 opcodes (including aliases and illegal opcodes), these cannot be used as variable or label names
// 65c02 opcodes, these cannot be used as variable or label names
override val opcodeNames = setOf("adc", "and", "asl", "bcc", "bcs",
"beq", "bge", "bit", "blt", "bmi", "bne", "bpl", "brk", "bvc", "bvs", "clc",
"cld", "cli", "clv", "cmp", "cpx", "cpy", "dec", "dex", "dey",

View File

@ -1 +1 @@
7.9
7.10-dev

View File

@ -23,7 +23,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
data class ZpAllocation(val address: UInt,
val dt: DataType,
val size: Int,
val originalScope: INameScope,
val originalScope: INameScope, // TODO try to get rid of this reference
val initialStringValue: StringLiteral?,
val initialArrayValue: ArrayLiteral?)

View File

@ -1,27 +1,54 @@
%import textio
%import floats
%import test_stack
%zeropage basicsafe
; Note: this program is compatible with C64 and CX16.
main {
ubyte[256] sieve
ubyte candidate_prime = 2 ; is increased in the loop
sub start() {
get_player(1)
|> determine_score()
|> add_bonus()
|> txt.print_uw()
}
sys.memset(sieve, 256, false) ; clear the sieve, to reset starting situation on subsequent runs
sub get_player(ubyte xx) -> ubyte {
return xx+33
}
; calculate primes
txt.print("prime numbers up to 255:\n\n")
ubyte amount=0
repeat {
ubyte prime = find_next_prime()
if prime==0
break
txt.print_ub(prime)
txt.print(", ")
amount++
}
txt.nl()
txt.print("number of primes (expected 54): ")
txt.print_ub(amount)
txt.nl()
sub determine_score(ubyte zz) -> ubyte {
return zz+22
}
sub add_bonus(ubyte qq) -> ubyte {
return qq+1
; test_stack.test()
}
sub find_next_prime() -> ubyte {
while sieve[candidate_prime] {
candidate_prime++
if candidate_prime==0
return 0 ; we wrapped; no more primes available in the sieve
}
; found next one, mark the multiples and return it.
sieve[candidate_prime] = true
uword multiple = candidate_prime
while multiple < len(sieve) {
sieve[lsb(multiple)] = true
multiple += candidate_prime
}
return candidate_prime
}
}