VarDecl: make its origin explicit

This commit is contained in:
Irmen de Jong 2022-01-10 01:48:25 +01:00
parent 596f9566d8
commit 3831679772
13 changed files with 65 additions and 55 deletions

View File

@ -356,7 +356,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
if(variable!=null) { if(variable!=null) {
if(elementDt istype DataType.FLOAT) if(elementDt istype DataType.FLOAT)
throw AssemblyError("containment check of floats not supported") throw AssemblyError("containment check of floats not supported")
if(variable.autogeneratedDontRemove) { if(variable.origin!=VarDeclOrigin.USERCODE) {
when(variable.datatype) { when(variable.datatype) {
DataType.STR -> { DataType.STR -> {
require(elementDt.isBytes) require(elementDt.isBytes)

View File

@ -102,7 +102,7 @@ class UnusedCodeRemover(private val program: Program,
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> { override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
if(decl.type==VarDeclType.VAR) { if(decl.type==VarDeclType.VAR) {
val forceOutput = "force_output" in decl.definingBlock.options() val forceOutput = "force_output" in decl.definingBlock.options()
if (!forceOutput && !decl.autogeneratedDontRemove && !decl.sharedWithAsm && !decl.definingBlock.isInLibrary) { if (!forceOutput && decl.origin==VarDeclOrigin.USERCODE && !decl.sharedWithAsm && !decl.definingBlock.isInLibrary) {
val usages = callgraph.usages(decl) val usages = callgraph.usages(decl)
if (usages.isEmpty()) { if (usages.isEmpty()) {
errors.warn("removing unused variable '${decl.name}'", decl.position) errors.warn("removing unused variable '${decl.name}'", decl.position)

View File

@ -7,6 +7,7 @@ import prog8.ast.expressions.CharLiteral
import prog8.ast.expressions.IdentifierReference import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.NumericLiteralValue import prog8.ast.expressions.NumericLiteralValue
import prog8.ast.statements.Directive import prog8.ast.statements.Directive
import prog8.ast.statements.VarDeclOrigin
import prog8.ast.walk.AstWalker import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification import prog8.ast.walk.IAstModification
import prog8.compilerinterface.CompilationOptions import prog8.compilerinterface.CompilationOptions
@ -139,7 +140,7 @@ internal fun Program.moveMainAndStartToFirst() {
internal fun IdentifierReference.isSubroutineParameter(program: Program): Boolean { internal fun IdentifierReference.isSubroutineParameter(program: Program): Boolean {
val vardecl = this.targetVarDecl(program) val vardecl = this.targetVarDecl(program)
if(vardecl!=null && vardecl.autogeneratedDontRemove) { if(vardecl!=null && vardecl.origin==VarDeclOrigin.SUBROUTINEPARAM) {
return vardecl.definingSubroutine?.parameters?.any { it.name==vardecl.name } == true return vardecl.definingSubroutine?.parameters?.any { it.name==vardecl.name } == true
} }
return false return false

View File

@ -48,7 +48,7 @@ internal class StatementReorderer(val program: Program,
if(decl !in declsProcessedWithInitAssignment) { if(decl !in declsProcessedWithInitAssignment) {
declsProcessedWithInitAssignment.add(decl) declsProcessedWithInitAssignment.add(decl)
if (decl.value == null) { if (decl.value == null) {
if (!decl.autogeneratedDontRemove && decl.allowInitializeWithZero) { if (decl.origin==VarDeclOrigin.USERCODE && decl.allowInitializeWithZero) {
// A numeric vardecl without an initial value is initialized with zero, // A numeric vardecl without an initial value is initialized with zero,
// unless there's already an assignment below it, that initializes the value (or a for loop that uses it as loopvar). // unless there's already an assignment below it, that initializes the value (or a for loop that uses it as loopvar).
// This allows you to restart the program and have the same starting values of the variables // This allows you to restart the program and have the same starting values of the variables
@ -153,7 +153,16 @@ internal class StatementReorderer(val program: Program,
.filterIsInstance<VarDecl>() .filterIsInstance<VarDecl>()
.filter { it.subroutineParameter!=null && it.name in stringParamsByNames } .filter { it.subroutineParameter!=null && it.name in stringParamsByNames }
.map { .map {
val newvar = VarDecl(it.type, DataType.UWORD, it.zeropage, null, it.name, null, false, true, it.sharedWithAsm, stringParamsByNames.getValue(it.name), it.position) val newvar = VarDecl(it.type, it.origin, DataType.UWORD,
it.zeropage,
null,
it.name,
null,
false,
it.sharedWithAsm,
stringParamsByNames.getValue(it.name),
it.position
)
IAstModification.ReplaceNode(it, newvar, subroutine) IAstModification.ReplaceNode(it, newvar, subroutine)
} }
} }

View File

@ -94,7 +94,7 @@ class TestCompilerOnImportsAndIncludes: FunSpec({
) )
tests.forEach { tests.forEach {
val (where, p8Str, binStr) = it val (where, p8Str, _) = it
test("%asmbinary from ${where}folder") { test("%asmbinary from ${where}folder") {
val p8Path = assumeReadableFile(fixturesDir, p8Str) val p8Path = assumeReadableFile(fixturesDir, p8Str)
// val binPath = assumeReadableFile(fixturesDir, binStr) // val binPath = assumeReadableFile(fixturesDir, binStr)

View File

@ -112,7 +112,7 @@ class TestMemory: FunSpec({
} }
fun createTestProgramForMemoryRefViaVar(address: UInt, vartype: VarDeclType): AssignTarget { fun createTestProgramForMemoryRefViaVar(address: UInt, vartype: VarDeclType): AssignTarget {
val decl = VarDecl(vartype, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, false, null, Position.DUMMY) val decl = VarDecl(vartype, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, null, Position.DUMMY)
val memexpr = IdentifierReference(listOf("address"), Position.DUMMY) val memexpr = IdentifierReference(listOf("address"), Position.DUMMY)
val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY)
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
@ -151,7 +151,7 @@ class TestMemory: FunSpec({
} }
test("regular variable not in mapped IO ram on C64") { test("regular variable not in mapped IO ram on C64") {
val decl = VarDecl(VarDeclType.VAR, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", null, false, false, false, null, Position.DUMMY) val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", null, false, false, null, Position.DUMMY)
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
@ -163,7 +163,7 @@ class TestMemory: FunSpec({
test("memory mapped variable not in mapped IO ram on C64") { test("memory mapped variable not in mapped IO ram on C64") {
val address = 0x1000u val address = 0x1000u
val decl = VarDecl(VarDeclType.MEMORY, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, false, null, Position.DUMMY) val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, null, Position.DUMMY)
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
@ -175,7 +175,7 @@ class TestMemory: FunSpec({
test("memory mapped variable in mapped IO ram on C64") { test("memory mapped variable in mapped IO ram on C64") {
val address = 0xd020u val address = 0xd020u
val decl = VarDecl(VarDeclType.MEMORY, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, false, null, Position.DUMMY) val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, null, Position.DUMMY)
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
@ -186,7 +186,7 @@ class TestMemory: FunSpec({
} }
test("array not in mapped IO ram") { test("array not in mapped IO ram") {
val decl = VarDecl(VarDeclType.VAR, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", null, false, false, false, null, Position.DUMMY) val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", null, false, false, null, Position.DUMMY)
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY) val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
@ -199,7 +199,7 @@ class TestMemory: FunSpec({
test("memory mapped array not in mapped IO ram") { test("memory mapped array not in mapped IO ram") {
val address = 0x1000u val address = 0x1000u
val decl = VarDecl(VarDeclType.MEMORY, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, false, null, Position.DUMMY) val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, null, Position.DUMMY)
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY) val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
@ -212,7 +212,7 @@ class TestMemory: FunSpec({
test("memory mapped array in mapped IO ram") { test("memory mapped array in mapped IO ram") {
val address = 0xd800u val address = 0xd800u
val decl = VarDecl(VarDeclType.MEMORY, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, false, null, Position.DUMMY) val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, null, Position.DUMMY)
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY) val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
@ -225,7 +225,7 @@ class TestMemory: FunSpec({
test("memory() with spaces in name works") { test("memory() with spaces in name works") {
val result = compileText(C64Target, false, """ compileText(C64Target, false, """
main { main {
sub start() { sub start() {
uword @shared mem = memory("a b c", 100) uword @shared mem = memory("a b c", 100)

View File

@ -46,8 +46,8 @@ class TestAsmGenSymbols: StringSpec({
} }
*/ */
val varInSub = VarDecl(VarDeclType.VAR, DataType.UWORD, ZeropageWish.DONTCARE, null, "localvar", NumericLiteralValue.optimalInteger(1234, Position.DUMMY), false, false, false, null, Position.DUMMY) val varInSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "localvar", NumericLiteralValue.optimalInteger(1234, Position.DUMMY), false, false, null, Position.DUMMY)
val var2InSub = VarDecl(VarDeclType.VAR, DataType.UWORD, ZeropageWish.DONTCARE, null, "tgt", null, false, false, false, null, Position.DUMMY) val var2InSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "tgt", null, false, false, null, Position.DUMMY)
val labelInSub = Label("locallabel", Position.DUMMY) val labelInSub = Label("locallabel", Position.DUMMY)
val tgt = AssignTarget(IdentifierReference(listOf("tgt"), Position.DUMMY), null, null, Position.DUMMY) val tgt = AssignTarget(IdentifierReference(listOf("tgt"), Position.DUMMY), null, null, Position.DUMMY)
@ -63,13 +63,11 @@ class TestAsmGenSymbols: StringSpec({
val statements = mutableListOf(varInSub, var2InSub, labelInSub, assign1, assign2, assign3, assign4, assign5, assign6, assign7, assign8) val statements = mutableListOf(varInSub, var2InSub, labelInSub, assign1, assign2, assign3, assign4, assign5, assign6, assign7, assign8)
val subroutine = Subroutine("start", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, statements, Position.DUMMY) val subroutine = Subroutine("start", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, statements, Position.DUMMY)
val labelInBlock = Label("label_outside", Position.DUMMY) val labelInBlock = Label("label_outside", Position.DUMMY)
val varInBlock = VarDecl(VarDeclType.VAR, DataType.UWORD, ZeropageWish.DONTCARE, null, "var_outside", null, false, false, false, null, Position.DUMMY) val varInBlock = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "var_outside", null, false, false, null, Position.DUMMY)
val block = Block("main", null, mutableListOf(labelInBlock, varInBlock, subroutine), false, Position.DUMMY) val block = Block("main", null, mutableListOf(labelInBlock, varInBlock, subroutine), false, Position.DUMMY)
val module = Module(mutableListOf(block), Position.DUMMY, SourceCode.Generated("test")) val module = Module(mutableListOf(block), Position.DUMMY, SourceCode.Generated("test"))
val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) return Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder).addModule(module)
.addModule(module)
return program
} }
fun createTestAsmGen(program: Program): AsmGen { fun createTestAsmGen(program: Program): AsmGen {

View File

@ -6,10 +6,7 @@ import prog8.ast.base.Position
import prog8.ast.base.VarDeclType import prog8.ast.base.VarDeclType
import prog8.ast.expressions.ContainmentCheck import prog8.ast.expressions.ContainmentCheck
import prog8.ast.expressions.StringLiteralValue import prog8.ast.expressions.StringLiteralValue
import prog8.ast.statements.Block import prog8.ast.statements.*
import prog8.ast.statements.Subroutine
import prog8.ast.statements.VarDecl
import prog8.ast.statements.ZeropageWish
import prog8.compilerinterface.IMemSizer import prog8.compilerinterface.IMemSizer
import prog8.compilerinterface.IStringEncoding import prog8.compilerinterface.IStringEncoding
import prog8.parser.SourceCode import prog8.parser.SourceCode
@ -94,8 +91,8 @@ class Program(val name: String,
.first { it is Block && it.name == internedStringsModuleName } as Block .first { it is Block && it.name == internedStringsModuleName } as Block
val varName = "string_${internedStringsBlock.statements.size}" val varName = "string_${internedStringsBlock.statements.size}"
val decl = VarDecl( val decl = VarDecl(
VarDeclType.VAR, DataType.STR, ZeropageWish.NOT_IN_ZEROPAGE, null, varName, string, VarDeclType.VAR, VarDeclOrigin.STRINGLITERAL, DataType.STR, ZeropageWish.NOT_IN_ZEROPAGE, null, varName, string,
isArray = false, autogeneratedDontRemove = true, sharedWithAsm = false, subroutineParameter = null, position = string.position isArray = false, sharedWithAsm = false, subroutineParameter = null, position = string.position
) )
internedStringsBlock.statements.add(decl) internedStringsBlock.statements.add(decl)
decl.linkParents(internedStringsBlock) decl.linkParents(internedStringsBlock)

View File

@ -9,7 +9,6 @@ import prog8.parser.Prog8ANTLRParser
import prog8.parser.SourceCode import prog8.parser.SourceCode
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.isRegularFile import kotlin.io.path.isRegularFile
import kotlin.math.exp
/***************** Antlr Extension methods to create AST ****************/ /***************** Antlr Extension methods to create AST ****************/
@ -56,14 +55,13 @@ private fun Prog8ANTLRParser.VariabledeclarationContext.toAst() : Statement {
varinitializer()?.let { varinitializer()?.let {
val vd = it.vardecl() val vd = it.vardecl()
return VarDecl( return VarDecl(
VarDeclType.VAR, VarDeclType.VAR, VarDeclOrigin.USERCODE,
vd.datatype()?.toAst() ?: DataType.UNDEFINED, vd.datatype()?.toAst() ?: DataType.UNDEFINED,
if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE,
vd.arrayindex()?.toAst(), vd.arrayindex()?.toAst(),
vd.varname.text, vd.varname.text,
it.expression().toAst(), it.expression().toAst(),
vd.ARRAYSIG() != null || vd.arrayindex() != null, vd.ARRAYSIG() != null || vd.arrayindex() != null,
false,
vd.SHARED()!=null, vd.SHARED()!=null,
null, null,
it.toPosition() it.toPosition()
@ -74,14 +72,13 @@ private fun Prog8ANTLRParser.VariabledeclarationContext.toAst() : Statement {
val cvarinit = it.varinitializer() val cvarinit = it.varinitializer()
val vd = cvarinit.vardecl() val vd = cvarinit.vardecl()
return VarDecl( return VarDecl(
VarDeclType.CONST, VarDeclType.CONST, VarDeclOrigin.USERCODE,
vd.datatype()?.toAst() ?: DataType.UNDEFINED, vd.datatype()?.toAst() ?: DataType.UNDEFINED,
if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE,
vd.arrayindex()?.toAst(), vd.arrayindex()?.toAst(),
vd.varname.text, vd.varname.text,
cvarinit.expression().toAst(), cvarinit.expression().toAst(),
vd.ARRAYSIG() != null || vd.arrayindex() != null, vd.ARRAYSIG() != null || vd.arrayindex() != null,
false,
vd.SHARED() != null, vd.SHARED() != null,
null, null,
cvarinit.toPosition() cvarinit.toPosition()
@ -92,14 +89,13 @@ private fun Prog8ANTLRParser.VariabledeclarationContext.toAst() : Statement {
val mvarinit = it.varinitializer() val mvarinit = it.varinitializer()
val vd = mvarinit.vardecl() val vd = mvarinit.vardecl()
return VarDecl( return VarDecl(
VarDeclType.MEMORY, VarDeclType.MEMORY, VarDeclOrigin.USERCODE,
vd.datatype()?.toAst() ?: DataType.UNDEFINED, vd.datatype()?.toAst() ?: DataType.UNDEFINED,
if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, if (vd.ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE,
vd.arrayindex()?.toAst(), vd.arrayindex()?.toAst(),
vd.varname.text, vd.varname.text,
mvarinit.expression().toAst(), mvarinit.expression().toAst(),
vd.ARRAYSIG() != null || vd.arrayindex() != null, vd.ARRAYSIG() != null || vd.arrayindex() != null,
false,
vd.SHARED()!=null, vd.SHARED()!=null,
null, null,
mvarinit.toPosition() mvarinit.toPosition()
@ -606,14 +602,13 @@ private fun Prog8ANTLRParser.When_choiceContext.toAst(): WhenChoice {
private fun Prog8ANTLRParser.VardeclContext.toAst(): VarDecl { private fun Prog8ANTLRParser.VardeclContext.toAst(): VarDecl {
return VarDecl( return VarDecl(
VarDeclType.VAR, VarDeclType.VAR, VarDeclOrigin.USERCODE,
datatype()?.toAst() ?: DataType.UNDEFINED, datatype()?.toAst() ?: DataType.UNDEFINED,
if(ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE, if(ZEROPAGE() != null) ZeropageWish.PREFER_ZEROPAGE else ZeropageWish.DONTCARE,
arrayindex()?.toAst(), arrayindex()?.toAst(),
varname.text, varname.text,
null, null,
ARRAYSIG() != null || arrayindex() != null, ARRAYSIG() != null || arrayindex() != null,
false,
SHARED()!=null, SHARED()!=null,
null, null,
toPosition() toPosition()

View File

@ -902,7 +902,7 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
fun wasStringLiteral(program: Program): Boolean { fun wasStringLiteral(program: Program): Boolean {
val decl = targetVarDecl(program) val decl = targetVarDecl(program)
if(decl == null || !decl.autogeneratedDontRemove) if(decl == null || decl.origin!=VarDeclOrigin.STRINGLITERAL)
return false return false
val scope=decl.definingModule val scope=decl.definingModule

View File

@ -171,14 +171,21 @@ enum class ZeropageWish {
NOT_IN_ZEROPAGE NOT_IN_ZEROPAGE
} }
enum class VarDeclOrigin {
USERCODE,
SUBROUTINEPARAM,
STRINGLITERAL,
ARRAYLITERAL
}
class VarDecl(val type: VarDeclType, class VarDecl(val type: VarDeclType,
val origin: VarDeclOrigin,
private val declaredDatatype: DataType, private val declaredDatatype: DataType,
var zeropage: ZeropageWish, var zeropage: ZeropageWish,
var arraysize: ArrayIndex?, var arraysize: ArrayIndex?,
override val name: String, override val name: String,
var value: Expression?, var value: Expression?,
val isArray: Boolean, val isArray: Boolean,
val autogeneratedDontRemove: Boolean,
val sharedWithAsm: Boolean, val sharedWithAsm: Boolean,
val subroutineParameter: SubroutineParameter?, val subroutineParameter: SubroutineParameter?,
override val position: Position) : Statement(), INamedStatement { override val position: Position) : Statement(), INamedStatement {
@ -191,9 +198,8 @@ class VarDecl(val type: VarDeclType,
private var autoHeapValueSequenceNumber = 0 private var autoHeapValueSequenceNumber = 0
fun fromParameter(param: SubroutineParameter): VarDecl { fun fromParameter(param: SubroutineParameter): VarDecl {
return VarDecl(VarDeclType.VAR, param.type, ZeropageWish.DONTCARE, null, param.name, null, return VarDecl(VarDeclType.VAR, VarDeclOrigin.SUBROUTINEPARAM, param.type, ZeropageWish.DONTCARE, null, param.name, null,
isArray = false, isArray = false,
autogeneratedDontRemove = true,
sharedWithAsm = false, sharedWithAsm = false,
subroutineParameter = param, subroutineParameter = param,
position = param.position position = param.position
@ -205,8 +211,8 @@ class VarDecl(val type: VarDeclType,
val arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") } val arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") }
val declaredType = ArrayToElementTypes.getValue(arrayDt) val declaredType = ArrayToElementTypes.getValue(arrayDt)
val arraysize = ArrayIndex.forArray(array) val arraysize = ArrayIndex.forArray(array)
return VarDecl(VarDeclType.VAR, declaredType, ZeropageWish.NOT_IN_ZEROPAGE, arraysize, autoVarName, array, return VarDecl(VarDeclType.VAR, VarDeclOrigin.ARRAYLITERAL, declaredType, ZeropageWish.NOT_IN_ZEROPAGE, arraysize, autoVarName, array,
isArray = true, autogeneratedDontRemove = true, sharedWithAsm = false, subroutineParameter = null, position = array.position) isArray = true, sharedWithAsm = false, subroutineParameter = null, position = array.position)
} }
fun defaultZero(dt: DataType, position: Position) = when(dt) { fun defaultZero(dt: DataType, position: Position) = when(dt) {
@ -260,10 +266,10 @@ class VarDecl(val type: VarDeclType,
} }
override fun copy(): VarDecl { override fun copy(): VarDecl {
val c = VarDecl(type, declaredDatatype, zeropage, arraysize?.copy(), name, value?.copy(), val copy = VarDecl(type, origin, declaredDatatype, zeropage, arraysize?.copy(), name, value?.copy(),
isArray, autogeneratedDontRemove, sharedWithAsm, subroutineParameter, position) isArray, sharedWithAsm, subroutineParameter, position)
c.allowInitializeWithZero = this.allowInitializeWithZero copy.allowInitializeWithZero = this.allowInitializeWithZero
return c return copy
} }
} }

View File

@ -21,7 +21,6 @@ Blocked by an official Commander-x16 r39 release
Future Things and Ideas Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
- clean up VarDecl.autogeneratedDontRemove -> make it explicit why it's autogenerated (i.e. special type of VarDecl)
- mark the initialization assignment to a vardecl as such - mark the initialization assignment to a vardecl as such
- can we promise a left-to-right function call argument evaluation? without sacrificing performance - can we promise a left-to-right function call argument evaluation? without sacrificing performance
- unify FunctioncallExpression + FunctioncallStatement and PipeExpression + Pipe statement, may require moving Expression/Statement into interfaces instead of abstract base classes - unify FunctioncallExpression + FunctioncallStatement and PipeExpression + Pipe statement, may require moving Expression/Statement into interfaces instead of abstract base classes

View File

@ -8,12 +8,17 @@ main {
uword ww uword ww
ubyte bb ubyte bb
derp("aaaa")
bb = ww==0 bb = ww==0
bb++ bb++
if ww==0 { if ww==0 {
bb++ bb++
} }
sub derp(str name) {
txt.print(name)
}
; fl = 1.234 |> addfloat1 |> addfloat2 |> addfloat3 ; fl = 1.234 |> addfloat1 |> addfloat2 |> addfloat3
; floats.print_f(fl) ; floats.print_f(fl)
; txt.nl() ; txt.nl()