mirror of
https://github.com/irmen/prog8.git
synced 2025-02-20 03:29:01 +00:00
VarDecl: make its origin explicit
This commit is contained in:
parent
596f9566d8
commit
3831679772
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user