mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
working on symbol table
This commit is contained in:
parent
094ecceaac
commit
a03c4c3659
@ -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")
|
||||
}
|
||||
|
@ -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()}")
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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",
|
||||
|
@ -1 +1 @@
|
||||
7.9
|
||||
7.10-dev
|
||||
|
@ -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?)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user