Skip to content

Commit

Permalink
Separate simple Ast and Symboltable from codeCore into new simpleAst …
Browse files Browse the repository at this point in the history
…module. VirtualMachine and Intermediate do not need them, just codeCore.
  • Loading branch information
irmen committed Feb 24, 2025
1 parent ae04f5a commit 3e2b2a6
Show file tree
Hide file tree
Showing 43 changed files with 295 additions and 216 deletions.
1 change: 1 addition & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions codeCore/src/prog8/code/Globals.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package prog8.code


// the automatically generated module where all string literals are interned to:
const val INTERNED_STRINGS_MODULENAME = "prog8_interned_strings"

// all automatically generated labels everywhere need to have the same label name prefix:
const val GENERATED_LABEL_PREFIX = "p8_label_gen_"
1 change: 1 addition & 0 deletions codeGenCpu6502/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {

dependencies {
implementation(project(":codeCore"))
implementation(project(":simpleAst"))
// implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// implementation "org.jetbrains.kotlin:kotlin-reflect"
implementation("com.michael-bull.kotlin-result:kotlin-result-jvm:2.0.1")
Expand Down
1 change: 1 addition & 0 deletions codeGenCpu6502/codeGenCpu6502.iml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="module" module-name="codeCore" />
<orderEntry type="module" module-name="simpleAst" />
<orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" />
<orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" />
<orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" />
Expand Down
11 changes: 7 additions & 4 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package prog8.codegen.cpu6502

import com.github.michaelbull.result.fold
import prog8.code.GENERATED_LABEL_PREFIX
import prog8.code.IAssemblyProgram
import prog8.code.ICodeGeneratorBackend
import prog8.code.StNode
import prog8.code.StNodeType
import prog8.code.SymbolTable
Expand Down Expand Up @@ -39,7 +42,7 @@ class AsmGen6502(val prefixSymbols: Boolean, private val lastGeneratedLabelSeque
when(node) {
is PtAsmSub, is PtSub -> node.name = "p8s_${node.name}"
is PtBlock -> node.name = "p8b_${node.name}"
is PtLabel -> if(!node.name.startsWith(PtLabel.GENERATED_LABEL_PREFIX)) node.name = "p8l_${node.name}" // don't prefix autogenerated labels
is PtLabel -> if(!node.name.startsWith(GENERATED_LABEL_PREFIX)) node.name = "p8l_${node.name}" // don't prefix autogenerated labels
is PtConstant -> node.name = "p8c_${node.name}"
is PtVariable, is PtMemMapped, is PtSubroutineParameter -> node.name = "p8v_${node.name}"
}
Expand Down Expand Up @@ -121,14 +124,14 @@ class AsmGen6502(val prefixSymbols: Boolean, private val lastGeneratedLabelSeque

private fun prefixScopedName(name: String, type: Char): String {
if('.' !in name) {
if(name.startsWith(PtLabel.GENERATED_LABEL_PREFIX))
if(name.startsWith(GENERATED_LABEL_PREFIX))
return name
return "p8${type}_$name"
}
val parts = name.split('.')
val firstPrefixed = "p8b_${parts[0]}"
val lastPart = parts.last()
val lastPrefixed = if(lastPart.startsWith(PtLabel.GENERATED_LABEL_PREFIX)) lastPart else "p8${type}_$lastPart"
val lastPrefixed = if(lastPart.startsWith(GENERATED_LABEL_PREFIX)) lastPart else "p8${type}_$lastPart"
// the parts in between are assumed to be subroutine scopes.
val inbetweenPrefixed = parts.drop(1).dropLast(1).map{ "p8s_$it" }
val prefixed = listOf(firstPrefixed) + inbetweenPrefixed + listOf(lastPrefixed)
Expand Down Expand Up @@ -1502,7 +1505,7 @@ $repeatLabel""")

internal fun makeLabel(postfix: String): String {
generatedLabelSequenceNumber++
return "${PtLabel.GENERATED_LABEL_PREFIX}${generatedLabelSequenceNumber}_$postfix"
return "$GENERATED_LABEL_PREFIX${generatedLabelSequenceNumber}_$postfix"
}

internal fun assignConstFloatToPointerAY(number: PtNumber) {
Expand Down
4 changes: 2 additions & 2 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package prog8.codegen.cpu6502

import prog8.code.GENERATED_LABEL_PREFIX
import prog8.code.StConstant
import prog8.code.StMemVar
import prog8.code.SymbolTable
import prog8.code.ast.PtLabel
import prog8.code.core.ICompilationTarget


Expand Down Expand Up @@ -362,7 +362,7 @@ or *_afterif labels.
This gets generated after certain if conditions, and only the branch instruction is needed in these cases.
*/

val autoLabelPrefix = PtLabel.GENERATED_LABEL_PREFIX
val autoLabelPrefix = GENERATED_LABEL_PREFIX
if(first=="beq +" && second=="lda #1" && third=="+") {
if((fourth.startsWith("beq $autoLabelPrefix") || fourth.startsWith("bne $autoLabelPrefix")) &&
(fourth.endsWith("_shortcut") || fourth.endsWith("_afterif") || fourth.endsWith("_shortcut:") || fourth.endsWith("_afterif:"))) {
Expand Down
5 changes: 3 additions & 2 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package prog8.codegen.cpu6502

import prog8.code.ast.PtLabel
import prog8.code.GENERATED_LABEL_PREFIX
import prog8.code.IAssemblyProgram
import prog8.code.core.*
import prog8.code.target.C128Target
import prog8.code.target.C64Target
Expand Down Expand Up @@ -131,7 +132,7 @@ internal class AssemblyProgram(
}

private fun removeGeneratedLabelsFromMonlist() {
val pattern = Regex("""al (\w+) \S+${PtLabel.GENERATED_LABEL_PREFIX}.+?""")
val pattern = Regex("""al (\w+) \S+$GENERATED_LABEL_PREFIX.+?""")
val lines = viceMonListFile.toFile().readLines()
viceMonListFile.toFile().outputStream().bufferedWriter().use {
for (line in lines) {
Expand Down
1 change: 1 addition & 0 deletions codeGenExperimental/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {

dependencies {
implementation(project(":codeCore"))
implementation(project(":simpleAst"))
implementation(project(":intermediate"))
implementation(project(":codeGenIntermediate"))
// implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
Expand Down
1 change: 1 addition & 0 deletions codeGenExperimental/codeGenExperimental.iml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
<orderEntry type="module" module-name="codeGenIntermediate" />
<orderEntry type="module" module-name="intermediate" />
<orderEntry type="module" module-name="codeCore" />
<orderEntry type="module" module-name="simpleAst" />
</component>
</module>
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package prog8.codegen.experimental
import prog8.code.SymbolTable
import prog8.code.ast.PtProgram
import prog8.code.core.CompilationOptions
import prog8.code.core.IAssemblyProgram
import prog8.code.core.ICodeGeneratorBackend
import prog8.code.IAssemblyProgram
import prog8.code.ICodeGeneratorBackend
import prog8.code.core.IErrorReporter
import prog8.codegen.intermediate.IRCodeGen
import prog8.intermediate.IRFileWriter
Expand Down
1 change: 1 addition & 0 deletions codeGenIntermediate/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {

dependencies {
implementation(project(":codeCore"))
implementation(project(":simpleAst"))
implementation(project(":intermediate"))
// implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// implementation "org.jetbrains.kotlin:kotlin-reflect"
Expand Down
1 change: 1 addition & 0 deletions codeGenIntermediate/codeGenIntermediate.iml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="module" module-name="codeCore" />
<orderEntry type="module" module-name="simpleAst" />
<orderEntry type="module" module-name="intermediate" />
<orderEntry type="library" name="io.kotest.assertions.core.jvm" level="project" />
<orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class IRCodeGen(
verifyNameScoping(program, symbolTable)
changeGlobalVarInits(symbolTable)

val irSymbolTable = IRSymbolTable.fromAstSymboltable(symbolTable)
val irSymbolTable = convertStToIRSt(symbolTable)
val irProg = IRProgram(program.name, irSymbolTable, options, program.encoding)

// collect global variables initializers
Expand Down Expand Up @@ -1899,7 +1899,7 @@ class IRCodeGen(
private var labelSequenceNumber = 0
internal fun createLabelName(): String {
labelSequenceNumber++
return "${PtLabel.GENERATED_LABEL_PREFIX}$labelSequenceNumber"
return "${GENERATED_LABEL_PREFIX}$labelSequenceNumber"
}

internal fun translateBuiltinFunc(call: PtBuiltinFunctionCall): ExpressionCodeResult
Expand Down
146 changes: 146 additions & 0 deletions codeGenIntermediate/src/prog8/codegen/intermediate/StConvert.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package prog8.codegen.intermediate

import prog8.code.StArrayElement
import prog8.code.StConstant
import prog8.code.StMemVar
import prog8.code.StMemorySlab
import prog8.code.StNodeType
import prog8.code.StStaticVariable
import prog8.code.SymbolTable
import prog8.code.core.DataType
import prog8.intermediate.IRStArrayElement
import prog8.intermediate.IRStConstant
import prog8.intermediate.IRStMemVar
import prog8.intermediate.IRStMemorySlab
import prog8.intermediate.IRStStaticVariable
import prog8.intermediate.IRSymbolTable


fun convertStToIRSt(sourceSt: SymbolTable?): IRSymbolTable {
val st = IRSymbolTable()
if (sourceSt != null) {
sourceSt.flat.forEach {
when(it.value.type) {
StNodeType.STATICVAR -> st.add(convert(it.value as StStaticVariable))
StNodeType.MEMVAR -> st.add(convert(it.value as StMemVar))
StNodeType.CONSTANT -> st.add(convert(it.value as StConstant))
StNodeType.MEMORYSLAB -> st.add(convert(it.value as StMemorySlab))
else -> { }
}
}

st.validate()

st.allVariables().forEach { variable ->
variable.onetimeInitializationArrayValue?.let {
it.forEach { arrayElt ->
val addrOfSymbol = arrayElt.addressOfSymbol
if (addrOfSymbol != null) {
require(addrOfSymbol.contains('.')) {
"pointer var in array should be properly scoped: ${addrOfSymbol} in ${variable.name}"
}
}
}
}
}
}
return st
}


private fun convert(variable: StStaticVariable): IRStStaticVariable {

fun convertArrayElt(elt: StArrayElement): IRStArrayElement = if(elt.boolean!=null)
IRStArrayElement(elt.boolean, null, elt.addressOfSymbol)
else
IRStArrayElement(null, elt.number, elt.addressOfSymbol)

val scopedName: String
if('.' in variable.name) {
scopedName = variable.name
return IRStStaticVariable(variable.name,
variable.dt,
variable.initializationNumericValue,
variable.initializationStringValue,
variable.initializationArrayValue?.map { convertArrayElt(it) },
variable.length,
variable.zpwish,
variable.align)
} else {
fun fixupAddressOfInArray(array: List<StArrayElement>?): List<IRStArrayElement>? {
if(array==null)
return null
val newArray = mutableListOf<IRStArrayElement>()
array.forEach {
if(it.addressOfSymbol!=null) {
val target = variable.lookup(it.addressOfSymbol!!) ?: throw NoSuchElementException("can't find variable ${it.addressOfSymbol}")
newArray.add(IRStArrayElement(null, null, target.scopedName))
} else {
newArray.add(convertArrayElt(it))
}
}
return newArray
}
scopedName = variable.scopedName
return IRStStaticVariable(scopedName,
variable.dt,
variable.initializationNumericValue,
variable.initializationStringValue,
fixupAddressOfInArray(variable.initializationArrayValue),
variable.length,
variable.zpwish,
variable.align
)
}
}


private fun convert(variable: StMemVar): IRStMemVar {
val scopedName: String
if('.' in variable.name) {
scopedName = variable.name
return IRStMemVar(
variable.name,
variable.dt,
variable.address,
variable.length
)
} else {
scopedName = try {
variable.scopedName
} catch (_: UninitializedPropertyAccessException) {
variable.name
}
return IRStMemVar(scopedName, variable.dt, variable.address, variable.length)
}
}


private fun convert(constant: StConstant): IRStConstant {
val dt = DataType.forDt(constant.dt)
val scopedName = if('.' in constant.name) {
constant.name
} else {
try {
constant.scopedName
} catch (_: UninitializedPropertyAccessException) {
constant.name
}
}
return IRStConstant(scopedName, dt, constant.value)
}


private fun convert(variable: StMemorySlab): IRStMemorySlab {
return if('.' in variable.name)
IRStMemorySlab(variable.name, variable.size, variable.align)
else
IRStMemorySlab("prog8_slabs.${variable.name}", variable.size, variable.align)
}

/*
*/
4 changes: 2 additions & 2 deletions codeGenIntermediate/src/prog8/codegen/vm/VmCodeGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package prog8.codegen.vm
import prog8.code.SymbolTable
import prog8.code.ast.PtProgram
import prog8.code.core.CompilationOptions
import prog8.code.core.IAssemblyProgram
import prog8.code.core.ICodeGeneratorBackend
import prog8.code.IAssemblyProgram
import prog8.code.ICodeGeneratorBackend
import prog8.code.core.IErrorReporter
import prog8.codegen.intermediate.IRCodeGen
import prog8.intermediate.IRFileWriter
Expand Down
4 changes: 2 additions & 2 deletions codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.code.core.ICompilationTarget
import prog8.code.core.IErrorReporter
import prog8.code.internedStringsModuleName
import prog8.code.INTERNED_STRINGS_MODULENAME
import prog8.compiler.CallGraph


Expand Down Expand Up @@ -93,7 +93,7 @@ class UnusedCodeRemover(private val program: Program,
override fun after(block: Block, parent: Node): Iterable<IAstModification> {
if("force_output" !in block.options()) {
if (block.containsNoCodeNorVars) {
if (block.name != internedStringsModuleName && "ignore_unused" !in block.options()) {
if (block.name != INTERNED_STRINGS_MODULENAME && "ignore_unused" !in block.options()) {
if (!block.statements.any { it is Subroutine && it.hasBeenInlined })
errors.info("removing unused block '${block.name}'", block.position)
}
Expand Down
1 change: 1 addition & 0 deletions compiler/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ plugins {

dependencies {
implementation(project(":codeCore"))
implementation(project(":simpleAst"))
implementation(project(":codeOptimizers"))
implementation(project(":compilerAst"))
implementation(project(":codeGenCpu6502"))
Expand Down
3 changes: 2 additions & 1 deletion compiler/compiler.iml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
<orderEntry type="library" name="io.kotest.runner.junit5.jvm" level="project" />
<orderEntry type="library" name="io.kotest.framework.datatest" level="project" />
<orderEntry type="module" module-name="codeCore" />
<orderEntry type="module" module-name="simpleAst" />
<orderEntry type="module" module-name="compilerAst" />
<orderEntry type="module" module-name="codeOptimizers" />
<orderEntry type="module" module-name="codeGenCpu6502" />
<orderEntry type="module" module-name="codeGenExperimental" />
<orderEntry type="module" module-name="codeGenIntermediate" />
<orderEntry type="module" module-name="virtualmachine" />
<orderEntry type="module" module-name="intermediate" scope="TEST" />
<orderEntry type="module" module-name="intermediate" />
<orderEntry type="library" name="antlr.antlr4" level="project" />
</component>
</module>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
import prog8.code.core.*
import prog8.code.internedStringsModuleName
import prog8.code.INTERNED_STRINGS_MODULENAME

internal class VerifyFunctionArgTypes(val program: Program, val options: CompilationOptions, val errors: IErrorReporter) : IAstVisitor {

Expand All @@ -22,7 +22,7 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila
}

// remove unused strings from interned strings block
val internedBlock = program.allBlocks.singleOrNull { it.name == internedStringsModuleName }
val internedBlock = program.allBlocks.singleOrNull { it.name == INTERNED_STRINGS_MODULENAME }
internedBlock?.statements?.withIndex()?.reversed()?.forEach { (index, st) ->
if(st is VarDecl && st.scopedName !in allStringRefs) {
internedBlock.statements.removeAt(index)
Expand Down
Loading

0 comments on commit 3e2b2a6

Please sign in to comment.