mirror of
https://github.com/irmen/prog8.git
synced 2025-04-07 16:41:46 +00:00
Separate simple Ast and Symboltable from codeCore into new simpleAst module. VirtualMachine and Intermediate do not need them, just codeCore.
This commit is contained in:
parent
ae04f5aee8
commit
3e2b2a698d
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
@ -17,6 +17,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/intermediate/intermediate.iml" filepath="$PROJECT_DIR$/intermediate/intermediate.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/parser/parser.iml" filepath="$PROJECT_DIR$/parser/parser.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/prog8.iml" filepath="$PROJECT_DIR$/.idea/modules/prog8.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/simpleAst/simpleAst.iml" filepath="$PROJECT_DIR$/simpleAst/simpleAst.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/virtualmachine/virtualmachine.iml" filepath="$PROJECT_DIR$/virtualmachine/virtualmachine.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
|
8
codeCore/src/prog8/code/Globals.kt
Normal file
8
codeCore/src/prog8/code/Globals.kt
Normal file
@ -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_"
|
@ -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")
|
||||
|
@ -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" />
|
||||
|
@ -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
|
||||
@ -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}"
|
||||
}
|
||||
@ -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)
|
||||
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
||||
@ -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:"))) {
|
||||
|
@ -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
|
||||
@ -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) {
|
||||
|
@ -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")
|
||||
|
@ -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>
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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" />
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
146
codeGenIntermediate/src/prog8/codegen/intermediate/StConvert.kt
Normal file
146
codeGenIntermediate/src/prog8/codegen/intermediate/StConvert.kt
Normal file
@ -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)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":codeCore"))
|
||||
implementation(project(":simpleAst"))
|
||||
implementation(project(":codeOptimizers"))
|
||||
implementation(project(":compilerAst"))
|
||||
implementation(project(":codeGenCpu6502"))
|
||||
|
@ -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>
|
@ -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 {
|
||||
|
||||
@ -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)
|
||||
|
@ -12,7 +12,7 @@ import io.kotest.matchers.string.shouldContain
|
||||
import prog8.ast.Program
|
||||
import prog8.code.core.IErrorReporter
|
||||
import prog8.code.source.SourceCode
|
||||
import prog8.code.internedStringsModuleName
|
||||
import prog8.code.INTERNED_STRINGS_MODULENAME
|
||||
import prog8.compiler.ModuleImporter
|
||||
import prog8.parser.ParseError
|
||||
import prog8tests.helpers.*
|
||||
@ -176,7 +176,7 @@ class TestModuleImporter: FunSpec({
|
||||
}
|
||||
}
|
||||
withClue("imported module with error in it should not be present") { program.modules.size shouldBe 1 }
|
||||
program.modules[0].name shouldBe internedStringsModuleName
|
||||
program.modules[0].name shouldBe INTERNED_STRINGS_MODULENAME
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +258,7 @@ class TestModuleImporter: FunSpec({
|
||||
}
|
||||
}
|
||||
withClue("imported module with error in it should not be present") { program.modules.size shouldBe 1 }
|
||||
program.modules[0].name shouldBe internedStringsModuleName
|
||||
program.modules[0].name shouldBe INTERNED_STRINGS_MODULENAME
|
||||
importer.errors.report()
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
import io.kotest.matchers.string.shouldStartWith
|
||||
import prog8.code.core.ZeropageType
|
||||
import prog8.code.internedStringsModuleName
|
||||
import prog8.code.INTERNED_STRINGS_MODULENAME
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.Cx16Target
|
||||
import prog8.code.target.VMTarget
|
||||
@ -40,7 +40,7 @@ main {
|
||||
}
|
||||
withClue("module order in parse tree") {
|
||||
moduleNames.drop(1) shouldBe listOf(
|
||||
internedStringsModuleName,
|
||||
INTERNED_STRINGS_MODULENAME,
|
||||
"textio",
|
||||
"syslib",
|
||||
"conv",
|
||||
@ -101,7 +101,7 @@ main {
|
||||
withClue("module order in parse tree") {
|
||||
program.modules.map { it.name } shouldBe
|
||||
listOf(
|
||||
internedStringsModuleName,
|
||||
INTERNED_STRINGS_MODULENAME,
|
||||
filenameBase,
|
||||
"textio", "syslib", "conv", "shared_cbm_textio_functions", "floats", "shared_floats_functions", "prog8_math", "prog8_lib"
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ import prog8.ast.AstToSourceTextConverter
|
||||
import prog8.ast.Module
|
||||
import prog8.ast.Program
|
||||
import prog8.code.source.SourceCode
|
||||
import prog8.code.internedStringsModuleName
|
||||
import prog8.code.INTERNED_STRINGS_MODULENAME
|
||||
import prog8.parser.ParseError
|
||||
import prog8.parser.Prog8Parser.parseModule
|
||||
import prog8tests.helpers.DummyFunctions
|
||||
@ -42,7 +42,7 @@ class TestAstToSourceText: AnnotationSpec() {
|
||||
fun testMentionsInternedStringsModule() {
|
||||
val orig = SourceCode.Text("\n")
|
||||
val (txt, _) = roundTrip(parseModule(orig))
|
||||
txt shouldContain Regex(";.*$internedStringsModuleName")
|
||||
txt shouldContain Regex(";.*$INTERNED_STRINGS_MODULENAME")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -15,7 +15,7 @@ import prog8.ast.statements.Block
|
||||
import prog8.code.ast.PtBlock
|
||||
import prog8.code.core.Position
|
||||
import prog8.code.source.SourceCode
|
||||
import prog8.code.internedStringsModuleName
|
||||
import prog8.code.INTERNED_STRINGS_MODULENAME
|
||||
import prog8.code.target.C64Target
|
||||
import prog8tests.helpers.DummyFunctions
|
||||
import prog8tests.helpers.DummyMemsizer
|
||||
@ -28,7 +28,7 @@ class TestProgram: FunSpec({
|
||||
test("withNameBuiltinsAndMemsizer") {
|
||||
val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
|
||||
program.modules.size shouldBe 1
|
||||
program.modules[0].name shouldBe internedStringsModuleName
|
||||
program.modules[0].name shouldBe INTERNED_STRINGS_MODULENAME
|
||||
program.modules[0].program shouldBeSameInstanceAs program
|
||||
program.modules[0].parent shouldBeSameInstanceAs program.namespace
|
||||
}
|
||||
@ -64,7 +64,7 @@ class TestProgram: FunSpec({
|
||||
test("withInternedStringsModule") {
|
||||
val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
|
||||
val m = program.modules[0]
|
||||
m.name shouldBe internedStringsModuleName
|
||||
m.name shouldBe INTERNED_STRINGS_MODULENAME
|
||||
|
||||
val retVal = program.moveModuleToFront(m)
|
||||
retVal shouldBeSameInstanceAs program
|
||||
|
@ -4,9 +4,9 @@ import prog8.ast.expressions.IdentifierReference
|
||||
import prog8.ast.expressions.StringLiteral
|
||||
import prog8.ast.statements.*
|
||||
import prog8.ast.walk.IAstVisitor
|
||||
import prog8.code.ast.PtLabel
|
||||
import prog8.code.GENERATED_LABEL_PREFIX
|
||||
import prog8.code.INTERNED_STRINGS_MODULENAME
|
||||
import prog8.code.core.*
|
||||
import prog8.code.internedStringsModuleName
|
||||
import prog8.code.source.SourceCode
|
||||
|
||||
/*********** Everything starts from here, the Program; zero or more modules *************/
|
||||
@ -23,8 +23,8 @@ class Program(val name: String,
|
||||
|
||||
init {
|
||||
// insert a container module for all interned strings later
|
||||
val internedStringsModule = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated(internedStringsModuleName))
|
||||
val block = Block(internedStringsModuleName, null, mutableListOf(), true, Position.DUMMY)
|
||||
val internedStringsModule = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated(INTERNED_STRINGS_MODULENAME))
|
||||
val block = Block(INTERNED_STRINGS_MODULENAME, null, mutableListOf(), true, Position.DUMMY)
|
||||
val directive = Directive("%option", listOf(DirectiveArg("no_symbol_prefixing", null, Position.DUMMY)), Position.DUMMY)
|
||||
block.statements.add(directive)
|
||||
directive.linkParents(block)
|
||||
@ -67,7 +67,7 @@ class Program(val name: String,
|
||||
}
|
||||
|
||||
val toplevelModule: Module
|
||||
get() = modules.first { it.name!= internedStringsModuleName }
|
||||
get() = modules.first { it.name!= INTERNED_STRINGS_MODULENAME }
|
||||
|
||||
private val internedStringsReferenceCounts = mutableMapOf<VarDecl, Int>()
|
||||
|
||||
@ -81,8 +81,8 @@ class Program(val name: String,
|
||||
}
|
||||
|
||||
val internedStringsBlock = modules
|
||||
.first { it.name == internedStringsModuleName }.statements
|
||||
.first { it is Block && it.name == internedStringsModuleName } as Block
|
||||
.first { it.name == INTERNED_STRINGS_MODULENAME }.statements
|
||||
.first { it is Block && it.name == INTERNED_STRINGS_MODULENAME } as Block
|
||||
|
||||
fun addNewInternedStringvar(string: StringLiteral): Pair<List<String>, VarDecl> {
|
||||
val varName = "string_${internedStringsBlock.statements.size}"
|
||||
@ -93,7 +93,7 @@ class Program(val name: String,
|
||||
)
|
||||
internedStringsBlock.statements.add(decl)
|
||||
decl.linkParents(internedStringsBlock)
|
||||
return Pair(listOf(internedStringsModuleName, decl.name), decl)
|
||||
return Pair(listOf(INTERNED_STRINGS_MODULENAME, decl.name), decl)
|
||||
}
|
||||
|
||||
val existingDecl = internedStringsBlock.statements.filterIsInstance<VarDecl>().singleOrNull {
|
||||
@ -133,8 +133,8 @@ class Program(val name: String,
|
||||
fun removeStrings(modules: List<Module>) {
|
||||
if(removals.isNotEmpty()) {
|
||||
val internedStringsBlock = modules
|
||||
.first { it.name == internedStringsModuleName }.statements
|
||||
.first { it is Block && it.name == internedStringsModuleName } as Block
|
||||
.first { it.name == INTERNED_STRINGS_MODULENAME }.statements
|
||||
.first { it is Block && it.name == INTERNED_STRINGS_MODULENAME } as Block
|
||||
removals.forEach { scopedname ->
|
||||
val decl = internedStringsBlock.statements.filterIsInstance<VarDecl>().single { decl -> decl.scopedName == scopedname }
|
||||
val numRefs = program.internedStringsReferenceCounts.getValue(decl) - 1
|
||||
@ -151,7 +151,7 @@ class Program(val name: String,
|
||||
|
||||
fun makeLabel(postfix: String): String {
|
||||
generatedLabelSequenceNumber++
|
||||
return "${PtLabel.GENERATED_LABEL_PREFIX}${generatedLabelSequenceNumber}_$postfix"
|
||||
return "$GENERATED_LABEL_PREFIX${generatedLabelSequenceNumber}_$postfix"
|
||||
}
|
||||
|
||||
fun makeLabel(postfix: String, position: Position): Label {
|
||||
|
@ -9,7 +9,7 @@ import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstVisitor
|
||||
import prog8.code.core.*
|
||||
import prog8.code.internedStringsModuleName
|
||||
import prog8.code.INTERNED_STRINGS_MODULENAME
|
||||
import prog8.code.target.encodings.JapaneseCharacterConverter
|
||||
import java.io.CharConversionException
|
||||
import java.util.*
|
||||
@ -1250,7 +1250,7 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
||||
return false
|
||||
|
||||
val scope=decl.definingModule
|
||||
return scope.name==internedStringsModuleName
|
||||
return scope.name==INTERNED_STRINGS_MODULENAME
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ Future Things and Ideas
|
||||
|
||||
IR/VM
|
||||
-----
|
||||
- Split the simplified AST and Symboltable from codeCore. VirtualMachine and Intermediate should not need those. (maybe others too?)
|
||||
- can onetimeInitializationNumericValue be removed from IRStStaticVariable?
|
||||
- getting it in shape for code generation...: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
||||
- fix call() return value handling
|
||||
- proper code gen for the CALLI instruction and that it (optionally) returns a word value that needs to be assigned to a reg
|
||||
|
@ -1,4 +1,4 @@
|
||||
package prog8.code
|
||||
package prog8
|
||||
|
||||
/**
|
||||
* By convention, the right side of an `Either` is used to hold successful values.
|
@ -1,6 +1,5 @@
|
||||
package prog8.intermediate
|
||||
|
||||
import prog8.code.*
|
||||
import prog8.code.core.*
|
||||
import prog8.code.target.VMTarget
|
||||
import prog8.code.target.getCompilationTargetByName
|
||||
@ -154,7 +153,7 @@ class IRFileReader {
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseVarsWithoutInit(reader: XMLEventReader): List<StStaticVariable> {
|
||||
private fun parseVarsWithoutInit(reader: XMLEventReader): List<IRStStaticVariable> {
|
||||
skipText(reader)
|
||||
val start = reader.nextEvent().asStartElement()
|
||||
require(start.name.localPart=="VARIABLESNOINIT") { "missing VARIABLESNOINIT" }
|
||||
@ -165,7 +164,7 @@ class IRFileReader {
|
||||
emptyList()
|
||||
else {
|
||||
val varPattern = Regex("(?<type>.+?)(?<arrayspec>\\[.+?\\])? (?<name>.+) zp=(?<zp>.+?)\\s?(split=(?<split>.+?))?\\s?(align=(?<align>.+?))?")
|
||||
val variables = mutableListOf<StStaticVariable>()
|
||||
val variables = mutableListOf<IRStStaticVariable>()
|
||||
text.lineSequence().forEach { line ->
|
||||
// example: uword main.start.qq2 zp=DONTCARE
|
||||
val match = varPattern.matchEntire(line) ?: throw IRParseException("invalid VARIABLESNOINIT $line")
|
||||
@ -182,14 +181,14 @@ class IRFileReader {
|
||||
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
||||
// val isSplit = if(split.isBlank()) false else split.toBoolean()
|
||||
val align = if(alignment.isBlank()) 0u else alignment.toUInt()
|
||||
val newVar = StStaticVariable(name, dt, null, null, arraysize, zp, align.toInt(), null)
|
||||
val newVar = IRStStaticVariable(name, dt, null, null, null, arraysize, zp, align.toInt())
|
||||
variables.add(newVar)
|
||||
}
|
||||
return variables
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseConstants(reader: XMLEventReader): List<StConstant> {
|
||||
private fun parseConstants(reader: XMLEventReader): List<IRStConstant> {
|
||||
skipText(reader)
|
||||
val start = reader.nextEvent().asStartElement()
|
||||
require(start.name.localPart=="CONSTANTS") { "missing CONSTANTS" }
|
||||
@ -200,7 +199,7 @@ class IRFileReader {
|
||||
emptyList()
|
||||
else {
|
||||
val constantPattern = Regex("(.+?) (.+)=(.*?)")
|
||||
val constants = mutableListOf<StConstant>()
|
||||
val constants = mutableListOf<IRStConstant>()
|
||||
text.lineSequence().forEach { line ->
|
||||
// examples:
|
||||
// uword main.start.qq2=0
|
||||
@ -210,13 +209,13 @@ class IRFileReader {
|
||||
throw IRParseException("unscoped name: $name")
|
||||
val dt = parseDatatype(type, false)
|
||||
val value = parseIRValue(valueStr)
|
||||
constants.add(StConstant(name, dt.base, value, null))
|
||||
constants.add(IRStConstant(name, dt, value))
|
||||
}
|
||||
return constants
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseVariables(reader: XMLEventReader): List<StStaticVariable> {
|
||||
private fun parseVariables(reader: XMLEventReader): List<IRStStaticVariable> {
|
||||
skipText(reader)
|
||||
val start = reader.nextEvent().asStartElement()
|
||||
require(start.name.localPart=="VARIABLESWITHINIT") { "missing VARIABLESWITHINIT" }
|
||||
@ -227,7 +226,7 @@ class IRFileReader {
|
||||
emptyList()
|
||||
else {
|
||||
val varPattern = Regex("(?<type>.+?)(?<arrayspec>\\[.+?\\])? (?<name>.+)=(?<value>.*?) zp=(?<zp>.+?)\\s?(split=(?<split>.+?))?\\s?(align=(?<align>.+?))?")
|
||||
val variables = mutableListOf<StStaticVariable>()
|
||||
val variables = mutableListOf<IRStStaticVariable>()
|
||||
text.lineSequence().forEach { line ->
|
||||
// examples:
|
||||
// uword main.start.qq2=0 zp=REQUIRE_ZP
|
||||
@ -248,21 +247,21 @@ class IRFileReader {
|
||||
if(split.isBlank()) false else split.toBoolean()
|
||||
val align = if(alignment.isBlank()) 0u else alignment.toUInt()
|
||||
var initNumeric: Double? = null
|
||||
var initArray: StArray? = null
|
||||
var initArray: IRStArray? = null
|
||||
when {
|
||||
dt.isNumericOrBool -> initNumeric = parseIRValue(value)
|
||||
dt.isBoolArray -> {
|
||||
initArray = value.split(',').map {
|
||||
val boolean = parseIRValue(it) != 0.0
|
||||
StArrayElement(null, null, boolean)
|
||||
IRStArrayElement(boolean, null, null)
|
||||
}
|
||||
}
|
||||
dt.isArray -> {
|
||||
initArray = value.split(',').map {
|
||||
if (it.startsWith('@'))
|
||||
StArrayElement(null, it.drop(1), null)
|
||||
IRStArrayElement(null, null, it.drop(1))
|
||||
else
|
||||
StArrayElement(parseIRValue(it), null, null)
|
||||
IRStArrayElement(null, parseIRValue(it), null)
|
||||
}
|
||||
}
|
||||
dt.isString -> throw IRParseException("STR should have been converted to byte array")
|
||||
@ -271,16 +270,14 @@ class IRFileReader {
|
||||
if(arraysize!=null && initArray!=null && initArray.all { it.number==0.0 }) {
|
||||
initArray=null // arrays with just zeros can be left uninitialized
|
||||
}
|
||||
val stVar = StStaticVariable(name, dt, null, initArray, arraysize, zp, align.toInt(), null)
|
||||
if(initNumeric!=null)
|
||||
stVar.setOnetimeInitNumeric(initNumeric)
|
||||
val stVar = IRStStaticVariable(name, dt, initNumeric, null, initArray, arraysize, zp, align.toInt())
|
||||
variables.add(stVar)
|
||||
}
|
||||
return variables
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseMemMapped(reader: XMLEventReader): List<StMemVar> {
|
||||
private fun parseMemMapped(reader: XMLEventReader): List<IRStMemVar> {
|
||||
skipText(reader)
|
||||
val start = reader.nextEvent().asStartElement()
|
||||
require(start.name.localPart=="MEMORYMAPPEDVARIABLES") { "missing MEMORYMAPPEDVARIABLES" }
|
||||
@ -290,7 +287,7 @@ class IRFileReader {
|
||||
return if(text.isBlank())
|
||||
emptyList()
|
||||
else {
|
||||
val memvars = mutableListOf<StMemVar>()
|
||||
val memvars = mutableListOf<IRStMemVar>()
|
||||
val mappedPattern = Regex("@(.+?)(\\[.+?\\])? (.+)=(.+)")
|
||||
text.lineSequence().forEach { line ->
|
||||
// examples:
|
||||
@ -300,13 +297,13 @@ class IRFileReader {
|
||||
val (type, arrayspec, name, address) = match.destructured
|
||||
val arraysize = if(arrayspec.isNotBlank()) arrayspec.substring(1, arrayspec.length-1).toInt() else null
|
||||
val dt = parseDatatype(type, arraysize!=null)
|
||||
memvars.add(StMemVar(name, dt, parseIRValue(address).toUInt(), arraysize, null))
|
||||
memvars.add(IRStMemVar(name, dt, parseIRValue(address).toUInt(), arraysize))
|
||||
}
|
||||
memvars
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseSlabs(reader: XMLEventReader): List<StMemorySlab> {
|
||||
private fun parseSlabs(reader: XMLEventReader): List<IRStMemorySlab> {
|
||||
skipText(reader)
|
||||
val start = reader.nextEvent().asStartElement()
|
||||
require(start.name.localPart=="MEMORYSLABS") { "missing MEMORYSLABS" }
|
||||
@ -316,13 +313,13 @@ class IRFileReader {
|
||||
return if(text.isBlank())
|
||||
emptyList()
|
||||
else {
|
||||
val slabs = mutableListOf<StMemorySlab>()
|
||||
val slabs = mutableListOf<IRStMemorySlab>()
|
||||
val slabPattern = Regex("(.+) (.+) (.+)")
|
||||
text.lineSequence().forEach { line ->
|
||||
// example: "slabname 4096 0"
|
||||
val match = slabPattern.matchEntire(line) ?: throw IRParseException("invalid slab $line")
|
||||
val (name, size, align) = match.destructured
|
||||
slabs.add(StMemorySlab(name, size.toUInt(), align.toUInt(), null))
|
||||
slabs.add(IRStMemorySlab(name, size.toUInt(), align.toUInt()))
|
||||
}
|
||||
slabs
|
||||
}
|
||||
|
@ -12,38 +12,6 @@ class IRSymbolTable {
|
||||
private val table = mutableMapOf<String, IRStNode>()
|
||||
private val asmSymbols = mutableMapOf<String, String>()
|
||||
|
||||
companion object {
|
||||
fun fromAstSymboltable(sourceSt: SymbolTable?): IRSymbolTable {
|
||||
val st = IRSymbolTable()
|
||||
if (sourceSt != null) {
|
||||
sourceSt.flat.forEach {
|
||||
when(it.value.type) {
|
||||
StNodeType.STATICVAR -> st.add(it.value as StStaticVariable)
|
||||
StNodeType.MEMVAR -> st.add(it.value as StMemVar)
|
||||
StNodeType.CONSTANT -> st.add(it.value as StConstant)
|
||||
StNodeType.MEMORYSLAB -> st.add(it.value as StMemorySlab)
|
||||
else -> { }
|
||||
}
|
||||
}
|
||||
|
||||
require(st.table.all { it.key == it.value.name })
|
||||
|
||||
st.allVariables().forEach { variable ->
|
||||
variable.onetimeInitializationArrayValue?.let {
|
||||
it.forEach { arrayElt ->
|
||||
if (arrayElt.addressOfSymbol != null) {
|
||||
require(arrayElt.addressOfSymbol.contains('.')) {
|
||||
"pointer var in array should be properly scoped: ${arrayElt.addressOfSymbol} in ${variable.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return st
|
||||
}
|
||||
}
|
||||
|
||||
fun allConstants(): Sequence<IRStConstant> =
|
||||
table.asSequence().map { it.value }.filterIsInstance<IRStConstant>()
|
||||
|
||||
@ -58,92 +26,8 @@ class IRSymbolTable {
|
||||
|
||||
fun lookup(name: String) = table[name]
|
||||
|
||||
fun add(variable: StStaticVariable) {
|
||||
val scopedName: String
|
||||
val varToadd: IRStStaticVariable
|
||||
if('.' in variable.name) {
|
||||
scopedName = variable.name
|
||||
varToadd = 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
|
||||
varToadd = IRStStaticVariable(scopedName,
|
||||
variable.dt,
|
||||
variable.initializationNumericValue,
|
||||
variable.initializationStringValue,
|
||||
fixupAddressOfInArray(variable.initializationArrayValue),
|
||||
variable.length,
|
||||
variable.zpwish,
|
||||
variable.align
|
||||
)
|
||||
}
|
||||
table[scopedName] = varToadd
|
||||
}
|
||||
|
||||
fun add(variable: StMemVar) {
|
||||
val scopedName: String
|
||||
val varToadd: IRStMemVar
|
||||
if('.' in variable.name) {
|
||||
scopedName = variable.name
|
||||
varToadd = IRStMemVar(
|
||||
variable.name,
|
||||
variable.dt,
|
||||
variable.address,
|
||||
variable.length
|
||||
)
|
||||
} else {
|
||||
scopedName = try {
|
||||
variable.scopedName
|
||||
} catch (_: UninitializedPropertyAccessException) {
|
||||
variable.name
|
||||
}
|
||||
varToadd = IRStMemVar(scopedName, variable.dt, variable.address, variable.length)
|
||||
}
|
||||
table[scopedName] = varToadd
|
||||
}
|
||||
|
||||
fun add(variable: StMemorySlab) {
|
||||
val varToadd = if('.' in variable.name)
|
||||
IRStMemorySlab(variable.name, variable.size, variable.align)
|
||||
else {
|
||||
IRStMemorySlab("prog8_slabs.${variable.name}", variable.size, variable.align)
|
||||
}
|
||||
table[varToadd.name] = varToadd
|
||||
}
|
||||
|
||||
fun add(constant: StConstant) {
|
||||
val scopedName: String
|
||||
val dt = DataType.forDt(constant.dt)
|
||||
if('.' in constant.name) {
|
||||
scopedName = constant.name
|
||||
} else {
|
||||
scopedName = try {
|
||||
constant.scopedName
|
||||
} catch (_: UninitializedPropertyAccessException) {
|
||||
constant.name
|
||||
}
|
||||
}
|
||||
table[scopedName] = IRStConstant(scopedName, dt, constant.value)
|
||||
fun add(node: IRStNode) {
|
||||
table[node.name] = node
|
||||
}
|
||||
|
||||
fun addAsmSymbol(name: String, value: String) {
|
||||
@ -157,17 +41,15 @@ class IRSymbolTable {
|
||||
val vars = table.filter { it.key.startsWith(prefix) }
|
||||
vars.forEach {
|
||||
// check if attempt is made to delete interned strings, if so, refuse that.
|
||||
if(!it.key.startsWith(internedStringsModuleName)) {
|
||||
if(!it.key.startsWith(INTERNED_STRINGS_MODULENAME)) {
|
||||
table.remove(it.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun convertArrayElt(elt: StArrayElement): IRStArrayElement = if(elt.boolean!=null)
|
||||
IRStArrayElement(elt.boolean, null, elt.addressOfSymbol)
|
||||
else
|
||||
IRStArrayElement(null, elt.number, elt.addressOfSymbol)
|
||||
fun validate() {
|
||||
require(table.all { it.key == it.value.name })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -178,10 +60,7 @@ enum class IRStNodeType {
|
||||
CONST
|
||||
}
|
||||
|
||||
open class IRStNode(val name: String,
|
||||
val type: IRStNodeType,
|
||||
val children: MutableMap<String, StNode> = mutableMapOf()
|
||||
)
|
||||
open class IRStNode(val name: String, val type: IRStNodeType)
|
||||
|
||||
class IRStMemVar(name: String,
|
||||
val dt: DataType,
|
||||
@ -209,7 +88,7 @@ class IRStConstant(name: String, val dt: DataType, val value: Double) : IRStNode
|
||||
|
||||
class IRStStaticVariable(name: String,
|
||||
val dt: DataType,
|
||||
val onetimeInitializationNumericValue: Double?, // regular (every-run-time) initialization is done via regular assignments
|
||||
val onetimeInitializationNumericValue: Double?, // TODO still needed? Or can go? regular (every-run-time) initialization is done via regular assignments
|
||||
val onetimeInitializationStringValue: IRStString?,
|
||||
val onetimeInitializationArrayValue: IRStArray?,
|
||||
val length: Int?, // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte
|
||||
|
@ -1,9 +1,9 @@
|
||||
package prog8.intermediate
|
||||
|
||||
import prog8.code.Either
|
||||
import prog8.code.core.*
|
||||
import prog8.code.left
|
||||
import prog8.code.right
|
||||
import prog8.Either
|
||||
import prog8.left
|
||||
import prog8.right
|
||||
|
||||
|
||||
fun DataType.irTypeString(length: Int?): String {
|
||||
|
@ -1,6 +1,7 @@
|
||||
include(
|
||||
':parser',
|
||||
':codeCore',
|
||||
':simpleAst',
|
||||
':intermediate',
|
||||
':compilerAst',
|
||||
':codeOptimizers',
|
||||
|
24
simpleAst/build.gradle.kts
Normal file
24
simpleAst/build.gradle.kts
Normal file
@ -0,0 +1,24 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":codeCore"))
|
||||
// implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||
implementation("com.michael-bull.kotlin-result:kotlin-result-jvm:2.0.1")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir("${project.projectDir}/src")
|
||||
}
|
||||
resources {
|
||||
srcDir("${project.projectDir}/res")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// note: there are no unit tests yet in this module!
|
17
simpleAst/simpleAst.iml
Normal file
17
simpleAst/simpleAst.iml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testResources" type="java-test-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||
<orderEntry type="module" module-name="codeCore" />
|
||||
<orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -1,13 +1,15 @@
|
||||
package prog8.code.core
|
||||
package prog8.code
|
||||
|
||||
import prog8.code.SymbolTable
|
||||
import prog8.code.ast.PtProgram
|
||||
import prog8.code.core.CompilationOptions
|
||||
import prog8.code.core.IErrorReporter
|
||||
|
||||
interface ICodeGeneratorBackend {
|
||||
fun generate(program: PtProgram,
|
||||
symbolTable: SymbolTable,
|
||||
options: CompilationOptions,
|
||||
errors: IErrorReporter): IAssemblyProgram?
|
||||
errors: IErrorReporter
|
||||
): IAssemblyProgram?
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,6 @@ import prog8.code.ast.PtProgram
|
||||
import prog8.code.core.*
|
||||
|
||||
|
||||
const val internedStringsModuleName = "prog8_interned_strings"
|
||||
|
||||
|
||||
/**
|
||||
* Tree structure containing all symbol definitions in the program
|
||||
* (blocks, subroutines, variables (all types), memoryslabs, and labels).
|
||||
@ -260,7 +257,7 @@ class StMemorySlab(
|
||||
|
||||
|
||||
class StSub(name: String, val parameters: List<StSubroutineParameter>, val returns: List<DataType>, astNode: PtNode) :
|
||||
StNode(name, StNodeType.SUBROUTINE, astNode)
|
||||
StNode(name, StNodeType.SUBROUTINE, astNode)
|
||||
|
||||
|
||||
class StExtSub(name: String,
|
@ -96,12 +96,7 @@ class PtInlineAssembly(val assembly: String, val isIR: Boolean, position: Positi
|
||||
}
|
||||
|
||||
|
||||
class PtLabel(name: String, position: Position) : PtNamedNode(name, position) {
|
||||
companion object {
|
||||
// all automatically generated labels everywhere need to have the same label name prefix:
|
||||
const val GENERATED_LABEL_PREFIX = "p8_label_gen_"
|
||||
}
|
||||
}
|
||||
class PtLabel(name: String, position: Position) : PtNamedNode(name, position)
|
||||
|
||||
|
||||
class PtBreakpoint(position: Position): PtNode(position)
|
@ -1,10 +1,10 @@
|
||||
package prog8.vm
|
||||
|
||||
import prog8.code.Either
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.left
|
||||
import prog8.code.right
|
||||
import prog8.Either
|
||||
import prog8.left
|
||||
import prog8.right
|
||||
import prog8.intermediate.*
|
||||
import prog8.code.core.DataType
|
||||
|
||||
class VmProgramLoader {
|
||||
private val placeholders = mutableMapOf<Pair<IRCodeChunk, Int>, String>() // program chunk+index to symbolname
|
||||
|
Loading…
x
Reference in New Issue
Block a user