From 8a7922ffcc79537903a404ca64d22b51e2ed6cfc Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 9 Jul 2026 23:20:47 +0200 Subject: [PATCH] fix split words arrays on m68k to be not split --- codeCore/src/prog8/code/core/DataTypes.kt | 43 ++++++++++--------- .../test/prog8tests/codecore/TestDataType.kt | 11 ++--- .../codegen/cpu6502/BuiltinFunctionsAsmGen.kt | 2 +- codeGenCpu6502/test/TestAsmOptimizer.kt | 5 +-- codeGenCpu6502/test/TestCodegen.kt | 8 ++-- .../prog8/codegen/intermediate/IRCodeGen.kt | 2 +- .../test/TestSymbolPrefixer.kt | 32 +++++++------- codeGenIntermediate/test/TestVmCodeGen.kt | 26 +++++------ .../optimizer/ConstantFoldingOptimizer.kt | 10 ++--- .../optimizer/ConstantIdentifierReplacer.kt | 4 +- compiler/res/prog8lib/qemu68k/syslib.p8 | 8 ++-- .../src/prog8/compiler/BuiltinFunctions.kt | 24 +++++------ compiler/src/prog8/compiler/Compiler.kt | 2 +- .../compiler/astprocessing/AstChecker.kt | 10 +++-- .../astprocessing/BeforeAsmAstChanger.kt | 2 +- .../compiler/astprocessing/CodeDesugarer.kt | 8 ++-- ...teralsToAutoVarsAndRecombineIdentifiers.kt | 2 +- .../compiler/astprocessing/M68kAstChecker.kt | 2 +- .../astprocessing/SimplifiedAstMaker.kt | 13 +++--- .../compiler/astprocessing/TypecastsAdder.kt | 2 +- .../compiler/astprocessing/VariousCleanups.kt | 35 ++++++++++++--- .../astprocessing/VerifyFunctionArgTypes.kt | 8 ++++ compiler/test/TestCallgraph.kt | 10 +++-- compiler/test/TestMemory.kt | 26 ++++++----- compiler/test/TestModuleImporter.kt | 3 +- compiler/test/TestOptimization.kt | 10 +++-- compiler/test/TestPointers.kt | 14 +++--- compiler/test/ast/TestAstToSourceText.kt | 6 +-- compiler/test/ast/TestIdentifierRef.kt | 6 +-- compiler/test/ast/TestProg8Parser.kt | 19 +++++--- compiler/test/ast/TestProgram.kt | 24 +++++++---- compiler/test/ast/TestVariousCompilerAst.kt | 9 ++-- .../test/codegeneration/TestAsmGenSymbols.kt | 11 +++-- compiler/test/codegeneration/TestLibrary.kt | 6 +-- .../test/codegeneration/TestVariousCodeGen.kt | 2 +- compilerAst/src/prog8/ast/AstToplevel.kt | 4 +- compilerAst/src/prog8/ast/Program.kt | 3 +- .../prog8/ast/antlr/Antlr2KotlinVisitor.kt | 3 +- .../prog8/ast/expressions/AstExpressions.kt | 12 +++--- .../prog8/ast/expressions/InferredTypes.kt | 17 +------- .../src/prog8/ast/statements/AstStatements.kt | 6 +-- .../src/prog8/intermediate/IRFileReader.kt | 18 ++++---- simpleAst/src/prog8/code/ast/AstBase.kt | 9 ++-- .../code/TestComparisonOptimizers.kt | 5 +-- .../code/TestSymbolTableConstruction.kt | 27 ++++++------ 45 files changed, 275 insertions(+), 234 deletions(-) diff --git a/codeCore/src/prog8/code/core/DataTypes.kt b/codeCore/src/prog8/code/core/DataTypes.kt index 8357f5fc9..35aeab6c5 100644 --- a/codeCore/src/prog8/code/core/DataTypes.kt +++ b/codeCore/src/prog8/code/core/DataTypes.kt @@ -20,7 +20,7 @@ enum class BaseDataType { ARRAY_SPLITW, // pass by reference, split word layout, subtype is the element type (restricted to word types) POINTER, // typed pointer, subtype is whatever type is pointed to STRUCT_INSTANCE, // the actual instance of a struct (not directly supported in the language yet, but we need its type) - ARRAY_POINTER, // array of pointers (uwords), subtype is whatever type each element points to + ARRAY_POINTER, // array of pointers (uwords or longs), subtype is whatever type each element points to UNDEFINED; @@ -85,12 +85,6 @@ val BaseDataType.isIterable get() = this in setOf(BaseDataType.STR, BaseDataTyp val BaseDataType.isPassByRef get() = this.isIterable && !this.isPointer val BaseDataType.isPassByValue get() = !this.isIterable || this.isPointer -fun DataType.isSplitWordArrayOnTarget(target: ICompilationTarget): Boolean = when(base) { - BaseDataType.ARRAY_SPLITW -> true - BaseDataType.ARRAY_POINTER -> target.POINTER_MEM_SIZE <= 2u - else -> false -} - /** * Interface for types that can be used as subtypes in DataType. @@ -190,17 +184,19 @@ class DataType private constructor( return simpletypes.getValue(dt) } - fun arrayFor(elementDt: BaseDataType, splitwordarray: Boolean=true): DataType { + fun arrayFor(elementDt: BaseDataType): DataType { + // wether or not a word-array should be split-words, is determined later require(!elementDt.isPointer) { "use other array constructor for arrays of pointers" } val actualElementDt = if(elementDt==BaseDataType.STR) BaseDataType.UWORD else elementDt // array of strings is actually just an array of UWORD pointers - return if(splitwordarray && actualElementDt.isWord) - DataType(BaseDataType.ARRAY_SPLITW, actualElementDt, null) - else { - if(actualElementDt.isNumericOrBool) - DataType(BaseDataType.ARRAY, actualElementDt, null) - else - throw NoSuchElementException("invalid basic element dt $elementDt") - } + if(actualElementDt.isNumericOrBool) + return DataType(BaseDataType.ARRAY, actualElementDt, null) + else + throw NoSuchElementException("invalid basic element dt $elementDt") + } + + fun splitWordArrayFor(elementDt: BaseDataType): DataType { + require(elementDt.isWord) { "split word array element type must be word" } + return DataType(BaseDataType.ARRAY_SPLITW, elementDt, null) } fun arrayOfPointersTo(sub: BaseDataType): DataType = DataType(BaseDataType.ARRAY_POINTER, sub, null) @@ -225,8 +221,10 @@ class DataType private constructor( // ============================================================================ fun elementToArray(splitwords: Boolean = true): DataType { - return if (base == BaseDataType.UWORD || base == BaseDataType.WORD || base == BaseDataType.STR) arrayFor(base, splitwords) - else arrayFor(base, false) + if (splitwords && (base == BaseDataType.UWORD || base == BaseDataType.WORD || base == BaseDataType.STR)) + return splitWordArrayFor(base) + else + return arrayFor(base) } fun elementType(): DataType = @@ -248,11 +246,14 @@ class DataType private constructor( if (isPointer) return untypedPointerType if (isArray) { - if (msb || base == BaseDataType.ARRAY_SPLITW) + val isSplit = base == BaseDataType.ARRAY_SPLITW || + (base == BaseDataType.ARRAY_POINTER && mem.memorySize(BaseDataType.POINTER) <= 2) + if (msb || isSplit) return pointer(BaseDataType.UBYTE) val elementDt = elementType() - require(elementDt.isBasic) - return pointer(elementDt) + if (elementDt.isBasic) + return pointer(elementDt) + return untypedPointerType } if (subType != null) return pointer(this) diff --git a/codeCore/test/prog8tests/codecore/TestDataType.kt b/codeCore/test/prog8tests/codecore/TestDataType.kt index ac966018a..be05581a8 100644 --- a/codeCore/test/prog8tests/codecore/TestDataType.kt +++ b/codeCore/test/prog8tests/codecore/TestDataType.kt @@ -8,6 +8,7 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import prog8.code.core.* + /** * Unit tests for DataType and BaseDataType classes in codeCore. * Focus on type predicates, relationships, and key operations. @@ -98,7 +99,7 @@ class TestDataType: FunSpec({ test("isSplitWordArray extension") { BaseDataType.ARRAY_SPLITW.isSplitWordArray.shouldBeTrue() - BaseDataType.ARRAY_POINTER.isSplitWordArray.shouldBeFalse() + BaseDataType.ARRAY_POINTER.isSplitWordArray.shouldBeTrue() BaseDataType.ARRAY.isSplitWordArray.shouldBeFalse() } @@ -124,9 +125,9 @@ class TestDataType: FunSpec({ ubyteArray.base shouldBe BaseDataType.ARRAY ubyteArray.sub shouldBe BaseDataType.UBYTE - val wordArraySplit = DataType.arrayFor(BaseDataType.WORD) - wordArraySplit.base shouldBe BaseDataType.ARRAY_SPLITW - wordArraySplit.sub shouldBe BaseDataType.WORD + val wordArray = DataType.arrayFor(BaseDataType.WORD) + wordArray.base shouldBe BaseDataType.ARRAY + wordArray.sub shouldBe BaseDataType.WORD } test("DataType.pointer creates pointer types") { @@ -306,6 +307,6 @@ class TestDataType: FunSpec({ test("DataType.toString for arrays") { DataType.arrayFor(BaseDataType.UBYTE).toString() shouldBe "ubyte[]" - DataType.arrayFor(BaseDataType.WORD).toString() shouldBe "word[] (split)" + DataType.arrayFor(BaseDataType.WORD).toString() shouldBe "word[]" } }) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index c81e54bc5..d8b3570d3 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -1137,7 +1137,7 @@ import prog8.codegen.cpu6502.assignment.* val msbAdd: Int if(indexer.splitWords) { val arrayVariable = indexer.variable ?: TODO("ptr indexing ${indexer.position}") - indexer.setChild(0, PtIdentifier(arrayVariable.name + (if(msb) "_msb" else "_lsb"), DataType.arrayFor(BaseDataType.UBYTE, false), arrayVariable.position)) + indexer.setChild(0, PtIdentifier(arrayVariable.name + (if(msb) "_msb" else "_lsb"), DataType.arrayFor(BaseDataType.UBYTE), arrayVariable.position)) elementSize = 1 msbAdd = 0 } else { diff --git a/codeGenCpu6502/test/TestAsmOptimizer.kt b/codeGenCpu6502/test/TestAsmOptimizer.kt index 2686aff09..cd35c8ed3 100644 --- a/codeGenCpu6502/test/TestAsmOptimizer.kt +++ b/codeGenCpu6502/test/TestAsmOptimizer.kt @@ -7,15 +7,14 @@ import prog8.code.SymbolTable import prog8.code.ast.PtProgram import prog8.code.core.DataType import prog8.code.target.C64Target +import prog8.code.target.VMTarget import prog8.codegen.cpu6502.* -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder class TestAsmOptimizer: FunSpec({ val machine = C64Target() - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val symbolTable = SymbolTable(program) // Add test variables with known non-IO addresses so the optimizer can resolve them diff --git a/codeGenCpu6502/test/TestCodegen.kt b/codeGenCpu6502/test/TestCodegen.kt index ebfca7773..cfd2074c3 100644 --- a/codeGenCpu6502/test/TestCodegen.kt +++ b/codeGenCpu6502/test/TestCodegen.kt @@ -12,10 +12,9 @@ import prog8.code.ast.* import prog8.code.core.* import prog8.code.source.SourceCode import prog8.code.target.C64Target +import prog8.code.target.VMTarget import prog8.codegen.cpu6502.AsmGen6502 import prog8.codegen.cpu6502.VariableAllocator -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder import prog8tests.helpers.ErrorReporterForTests import java.nio.file.Files import kotlin.io.path.Path @@ -46,8 +45,9 @@ class TestCodegen: FunSpec({ // xx += cx16.r0 // } //} + val compTarget = C64Target() val codegen = AsmGen6502(0) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main",false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -166,7 +166,7 @@ class TestCodegen: FunSpec({ } test("memory mapped zp var is correctly considered to be zp var") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val st = SymbolTable(program) st.add(StMemVar("zpmemvar", DataType.WORD, 0x20u, null, null)) st.add(StMemVar("normalmemvar", DataType.WORD, 0x9000u, null, null)) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index bc2c4d8b1..0852ac6e4 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -228,7 +228,7 @@ class IRCodeGen( val shadowInit = IRVariableInitializer.Array(initBytes.map { IRStSymbolicReference.Numeric(it.toDouble()) }) val shadowVar = IRStStaticVariable( shadowName, - DataType.arrayFor(BaseDataType.UBYTE, false), + DataType.arrayFor(BaseDataType.UBYTE), shadowInit, initBytes.size.toUInt(), ZeropageWish.NOT_IN_ZEROPAGE, diff --git a/codeGenIntermediate/test/TestSymbolPrefixer.kt b/codeGenIntermediate/test/TestSymbolPrefixer.kt index 258d49e71..d9ee471c9 100644 --- a/codeGenIntermediate/test/TestSymbolPrefixer.kt +++ b/codeGenIntermediate/test/TestSymbolPrefixer.kt @@ -2,15 +2,15 @@ import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe -import prog8.code.* +import prog8.code.StNodeType +import prog8.code.SymbolTableMaker import prog8.code.ast.* import prog8.code.core.* import prog8.code.source.SourceCode +import prog8.code.target.VMTarget import prog8.codegen.intermediate.prefixScopedName import prog8.codegen.intermediate.prefixSymbols import prog8.codegen.intermediate.typePrefixChar -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder class TestSymbolPrefixer : FunSpec({ @@ -59,7 +59,7 @@ class TestSymbolPrefixer : FunSpec({ // --- full program prefixing tests --- test("prefixSymbols prefixes a simple program") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) val varX = PtVariable("x", DataType.UBYTE, ZeropageWish.DONTCARE, 0u, false, null, null, Position.DUMMY) @@ -84,7 +84,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols handles subroutine parameters") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) val param = PtSubroutineParameter("arg", DataType.UBYTE, null, Position.DUMMY) @@ -100,7 +100,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols handles constants") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val constant = PtConstant("SIZE", DataType.UWORD, 100.0, null, Position.DUMMY) block.add(constant) @@ -114,7 +114,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols handles labels") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) val label = PtLabel("mylabel", Position.DUMMY) @@ -130,7 +130,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols handles generated labels without prefixing them") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) val genLabel = PtLabel("p8_label_gen_42", Position.DUMMY) @@ -146,7 +146,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols handles struct declarations") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val struct = PtStructDecl("Point", listOf( PtStructField(DataType.UBYTE, "x", null), @@ -163,7 +163,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols handles asmsub") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val asmsub = PtAsmSub("routine", PtAsmSub.Address(null, null, 0x5000u), setOf(CpuRegister.Y), emptyList(), emptyList(), false, Position.DUMMY) block.add(asmsub) @@ -177,7 +177,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols handles memmapped variables") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val memvar = PtMemMapped("reg", DataType.UBYTE, 0xd020u, null, Position.DUMMY) block.add(memvar) @@ -193,7 +193,7 @@ class TestSymbolPrefixer : FunSpec({ // --- noSymbolPrefixing tests --- test("noSymbolPrefixing blocks keep their names intact") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val libOptions = PtBlock.Options(noSymbolPrefixing = true) val libBlock = PtBlock("lib", false, SourceCode.Generated("test"), libOptions, Position.DUMMY) val libSub = PtSub("func", emptyList(), emptyList(), Position.DUMMY) @@ -209,7 +209,7 @@ class TestSymbolPrefixer : FunSpec({ } test("references from user block to noSymbolPrefixing block are not prefixed") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) // Library block with no symbol prefixing val libOptions = PtBlock.Options(noSymbolPrefixing = true) @@ -240,7 +240,7 @@ class TestSymbolPrefixer : FunSpec({ } test("references from noSymbolPrefixing block to regular block get prefixed") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) // Regular user block val userBlock = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) @@ -267,7 +267,7 @@ class TestSymbolPrefixer : FunSpec({ } test("identifier references are prefixed according to their target type") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) val varX = PtVariable("x", DataType.UBYTE, ZeropageWish.DONTCARE, 0u, false, null, null, Position.DUMMY) @@ -290,7 +290,7 @@ class TestSymbolPrefixer : FunSpec({ } test("prefixSymbols exception for unknown identifier") { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) val idRef = PtIdentifier("nonexistent", DataType.UBYTE, Position.DUMMY) diff --git a/codeGenIntermediate/test/TestVmCodeGen.kt b/codeGenIntermediate/test/TestVmCodeGen.kt index 21839d93a..95de601bd 100644 --- a/codeGenIntermediate/test/TestVmCodeGen.kt +++ b/codeGenIntermediate/test/TestVmCodeGen.kt @@ -12,8 +12,7 @@ import prog8.codegen.vm.VmCodeGen import prog8.intermediate.IRSubroutine import prog8.intermediate.Opcode import prog8.intermediate.toAddress -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder + import prog8tests.helpers.ErrorReporterForTests class TestVmCodeGen: FunSpec({ @@ -41,8 +40,9 @@ class TestVmCodeGen: FunSpec({ // xx += cx16.r0 // } //} + val compTarget = VMTarget() val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -153,7 +153,7 @@ class TestVmCodeGen: FunSpec({ // Pattern: @(ptr+offset) = @(ptr+offset) + val i.e. ptr[offset] += val // Non-zero offsets are used to avoid potential optimization of the address expression. val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable("ptr", DataType.pointer(BaseDataType.UBYTE), ZeropageWish.DONTCARE, 0u, false, null, null, Position.DUMMY)) @@ -230,7 +230,7 @@ class TestVmCodeGen: FunSpec({ // } //} val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -302,7 +302,7 @@ class TestVmCodeGen: FunSpec({ // } //} val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -370,7 +370,7 @@ class TestVmCodeGen: FunSpec({ // } //} val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -426,7 +426,7 @@ class TestVmCodeGen: FunSpec({ // } //} val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -498,7 +498,7 @@ class TestVmCodeGen: FunSpec({ // } //} val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -566,7 +566,7 @@ class TestVmCodeGen: FunSpec({ // } //} val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable( @@ -615,7 +615,7 @@ class TestVmCodeGen: FunSpec({ // } //} val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val extsub = PtAsmSub("routine", PtAsmSub.Address(null, null, 0x5000u), setOf(CpuRegister.Y), emptyList(), emptyList(), false, Position.DUMMY) block.add(extsub) @@ -640,7 +640,7 @@ class TestVmCodeGen: FunSpec({ test("ir codegen for target 'virtual' produces no prefixed names") { val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable("x", DataType.UBYTE, ZeropageWish.DONTCARE, 0u, false, null, null, Position.DUMMY)) @@ -668,7 +668,7 @@ class TestVmCodeGen: FunSpec({ test("ir codegen for target 'cx16' via newcodegen produces prefixed names") { val codegen = VmCodeGen(false) - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY) val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY) sub.add(PtVariable("x", DataType.UBYTE, ZeropageWish.DONTCARE, 0u, false, null, null, Position.DUMMY)) diff --git a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt index 37c20f49a..c76dc2162 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -110,7 +110,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors: if (leftPtrConst != null && rightOffsetConst != null) { val ptrDt = leftDt.getOrUndef() val subDt = ptrDt.sub - val scale = if(subDt is BaseDataType) program.memsizer.memorySize(subDt) else ptrDt.size(program.memsizer) + val scale = if(subDt is BaseDataType) program.target.memorySize(subDt) else ptrDt.size(program.target) val offset = rightOffsetConst.number.toInt() * scale val result = if (expr.operator == "+") leftPtrConst.number + offset else leftPtrConst.number - offset return listOf(AstReplaceNode(expr, NumericLiteral(BaseDataType.UWORD, result, expr.position), parent)) @@ -123,7 +123,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors: if (rightPtrConst != null && leftOffsetConst != null) { val ptrDt = rightDt.getOrUndef() val subDt = ptrDt.sub - val scale = if(subDt is BaseDataType) program.memsizer.memorySize(subDt) else ptrDt.size(program.memsizer) + val scale = if(subDt is BaseDataType) program.target.memorySize(subDt) else ptrDt.size(program.target) val offset = leftOffsetConst.number.toInt() * scale val result = rightPtrConst.number + offset return listOf(AstReplaceNode(expr, NumericLiteral(BaseDataType.UWORD, result, expr.position), parent)) @@ -142,8 +142,8 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors: val concatenated = if(leftString.encoding==rightString.encoding) { leftString.value + rightString.value } else { - program.encoding.decodeString( - program.encoding.encodeString(leftString.value, leftString.encoding) + program.encoding.encodeString(rightString.value, rightString.encoding), + program.target.decodeString( + program.target.encodeString(leftString.value, leftString.encoding) + program.target.encodeString(rightString.value, rightString.encoding), leftString.encoding) } val concatStr = StringLiteral.create(concatenated, leftString.encoding, expr.position) @@ -535,7 +535,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors: override fun after(decl: VarDecl, parent: Node): Iterable { if (decl.type == VarDeclType.CONST && decl.datatype.isPointer) { - val sizer = program.memsizer + val sizer = program.target if (decl.datatype.size(sizer) > 1) { errors.err("due to internal compiler complexity, currently pointer variables with data type size > 1 cannot be const", decl.position) } diff --git a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt index 0577b661f..9d03da6ea 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt @@ -149,7 +149,7 @@ class VarConstantValueTypeAdjuster( private fun canBeMadeConst(decl: VarDecl, usages: List): Boolean { if (decl.datatype.isPointer) { - if (decl.datatype.size(program.memsizer) > 1) return false + if (decl.datatype.size(program.target) > 1) return false val derefCount = usages.count { val p = it.parent val gp = p.parent @@ -599,7 +599,7 @@ internal class ConstantIdentifierReplacer( if(declArraySize!=null && declArraySize!=rangeExpr.size()) errors.err("range expression size (${rangeExpr.size()}) doesn't match declared array size ($declArraySize)", decl.value?.position!!) if(constRange!=null) { - return ArrayLiteral(InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.FLOAT, false)), + return ArrayLiteral(InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.FLOAT)), constRange.map { NumericLiteral(BaseDataType.FLOAT, it.toDouble(), decl.value!!.position) }.toTypedArray(), position = decl.value!!.position) } diff --git a/compiler/res/prog8lib/qemu68k/syslib.p8 b/compiler/res/prog8lib/qemu68k/syslib.p8 index 7a407a7fe..8746dd22b 100644 --- a/compiler/res/prog8lib/qemu68k/syslib.p8 +++ b/compiler/res/prog8lib/qemu68k/syslib.p8 @@ -123,7 +123,7 @@ sys { ; ------- memory routines -------- - asmsub memcopy(^^ubyte source @D0, ^^ubyte tgt @D1, uword count @D2) { + asmsub memcopy(long source @D0, long tgt @D1, uword count @D2) { ; Copy bytes from source to target. ; Bulk of the work uses long-aligned longword copies; ; pre-alignment and remainder bytes use individual byte copies. @@ -186,7 +186,7 @@ sys { }} } - asmsub memset(^^ubyte mem @D0, uword numbytes @D1, ubyte value @D2) { + asmsub memset(long mem @D0, uword numbytes @D1, ubyte value @D2) { %asm {{ movea.l d0,a0 tst.w d1 @@ -237,7 +237,7 @@ sys { }} } - asmsub memclear(^^ubyte mem @D0, uword numbytes @D1) { + asmsub memclear(long mem @D0, uword numbytes @D1) { ; Clear memory (fill with zero). Uses movem.l d0-d7,-(a0) ; for the bulk clear (32 bytes per instruction, decrementing from ; the end address). Handles misaligned start and remaining bytes. @@ -314,7 +314,7 @@ sys { }} } - asmsub memsetw(^^ubyte mem @D0, uword numwords @D1, uword value @D2) { + asmsub memsetw(long mem @D0, uword numwords @D1, uword value @D2) { ; Fill memory with the given 16-bit word value, for the given number of words. ; Word-aligned start: fast path with longword stores (2 words at a time). ; Odd start: first byte written individually to realign, then same fast path diff --git a/compiler/src/prog8/compiler/BuiltinFunctions.kt b/compiler/src/prog8/compiler/BuiltinFunctions.kt index ed9eb6ed7..a239e6cb8 100644 --- a/compiler/src/prog8/compiler/BuiltinFunctions.kt +++ b/compiler/src/prog8/compiler/BuiltinFunctions.kt @@ -123,7 +123,7 @@ private fun builtinOffsetof(args: List, position: Position, program: val structname = identifier.dropLast(1) val fieldname = identifier.last() val struct = args[0].definingScope.lookup(structname) as? StructDecl ?: throw SyntaxError("cannot find struct '$structname'", args[0].position) - val offset = struct.offsetof(fieldname, program.memsizer) ?: throw SyntaxError("no such field '${identifier.joinToString(".")}'", args[0].position) + val offset = struct.offsetof(fieldname, program.target) ?: throw SyntaxError("no such field '${identifier.joinToString(".")}'", args[0].position) return NumericLiteral.optimalInteger(offset.toInt(), position) } @@ -137,7 +137,7 @@ private fun builtinSizeof(args: List, position: Position, program: P val dt = args[0].inferType(program) if(dt.isKnown) { if(args[0] is NumericLiteral || args[0] is AddressOf || args[0] is MemorySlabRef) - return NumericLiteral.optimalInteger(program.memsizer.memorySize(dt.getOrUndef(), null), position) + return NumericLiteral.optimalInteger(program.target.memorySize(dt.getOrUndef(), null), position) val target = (args[0] as? IdentifierReference)?.targetStatement() ?: throw SyntaxError("wrong argument type", position) @@ -146,7 +146,7 @@ private fun builtinSizeof(args: List, position: Position, program: P dt.isArray -> { val length = (target as VarDecl).arraysize?.constIndex() ?: throw CannotEvaluateException("sizeof", "unknown array size") val elementDt = dt.getOrUndef().elementType() - NumericLiteral.optimalInteger(program.memsizer.memorySize(elementDt, length), position) + NumericLiteral.optimalInteger(program.target.memorySize(elementDt, length), position) } dt.isString -> { if(target is VarDecl) { @@ -156,26 +156,26 @@ private fun builtinSizeof(args: List, position: Position, program: P else throw SyntaxError("sizeof(str) is undefined here. Perhaps use len, or strings.length?", position) } - else -> NumericLiteral.optimalInteger( program.memsizer.memorySize(dt.getOrUndef(), null), position) + else -> NumericLiteral.optimalInteger( program.target.memorySize(dt.getOrUndef(), null), position) } } else { val identifier = args[0] as? IdentifierReference if(identifier?.nameInSource?.size==1) { when(identifier.nameInSource[0]) { - "ubyte" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.UBYTE), position) - "byte" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.BYTE), position) - "uword" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.UWORD), position) - "word" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.WORD), position) - "long" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.LONG), position) - "float" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.FLOAT), position) - "bool" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.BOOL), position) + "ubyte" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.UBYTE), position) + "byte" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.BYTE), position) + "uword" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.UWORD), position) + "word" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.WORD), position) + "long" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.LONG), position) + "float" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.FLOAT), position) + "bool" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.BOOL), position) } } // the argument could refer to a struct declaration val struct = (args[0] as? IdentifierReference)?.targetStructDecl() if(struct!=null) { - val size = struct.memsize(program.memsizer) + val size = struct.memsize(program.target) return NumericLiteral(BaseDataType.UBYTE, size.toDouble(), position) } diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index c7bd21fd2..44201cb04 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -412,7 +412,7 @@ fun parseMainModule(filepath: Path, quiet: Boolean, traceImports: Boolean): Triple> { val bf = BuiltinFunctionsFacade(BuiltinFunctions) - val program = Program(filepath.nameWithoutExtension, bf, compTarget, compTarget) + val program = Program(filepath.nameWithoutExtension, bf, compTarget) bf.program = program val importer = ModuleImporter(program, compTarget.name, errors, sourceDirs, libraryDirs, cwd, quiet, traceImports) diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index d3ae7368c..5b9085900 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -1698,6 +1698,8 @@ internal class AstChecker(private val program: Program, // exception allowed on 16 bits pointers: comparing uword (pointer) with string } else if(compilerOptions.compTarget.POINTER_MEM_SIZE>2u && leftDt.isPointer && rightDt.isString) { // exception allowed on 32 bits pointers: comparing pointer with string + } else if(compilerOptions.compTarget.POINTER_MEM_SIZE>2u && ((leftDt.isLong && rightDt.isPointer) || (leftDt.isPointer && rightDt.isLong))) { + // exception allowed on 32 bits pointers: comparing long (untyped pointer) with pointer } else { errors.err("left and right operands aren't the same type: $leftDt vs $rightDt", expr.position) } @@ -2310,7 +2312,7 @@ internal class AstChecker(private val program: Program, val uniqueFields = struct.fields.mapTo(mutableSetOf()) { it.name } if(uniqueFields.size!=struct.fields.size) errors.err("duplicate field names in struct", struct.position) - val memsize = struct.memsize(program.memsizer) + val memsize = struct.memsize(program.target) if(memsize>256) errors.err("struct contains too many fields, max struct size is 256 bytes (actual: $memsize)", struct.position) @@ -2642,7 +2644,7 @@ internal class AstChecker(private val program: Program, targetDatatype.isUnsignedByte -> sourceDatatype.isUnsignedByte targetDatatype.isSignedWord -> sourceDatatype.isSignedWord || sourceDatatype.isByte targetDatatype.isUnsignedWord -> sourceDatatype.isUnsignedWord || sourceDatatype.isUnsignedByte - targetDatatype.isLong -> sourceDatatype.isLong || sourceDatatype.isWord || sourceDatatype.isByte + targetDatatype.isLong -> sourceDatatype.isLong || sourceDatatype.isPointer || sourceDatatype.isWord || sourceDatatype.isByte targetDatatype.isFloat -> sourceDatatype.isNumeric targetDatatype.isString -> sourceDatatype.isString else -> false @@ -2668,9 +2670,9 @@ internal class AstChecker(private val program: Program, errors.err("cannot assign different pointer type, expected $targetDatatype or uword but got $sourceDatatype", position) } else if(sourceDatatype.isString && targetDatatype.sub?.isByte==true) { // assigning a string to a byte pointer is allowed. - } else if(!sourceDatatype.isUnsignedWord && !sourceDatatype.isStructInstance) + } else if(!sourceDatatype.isUnsignedWord && !sourceDatatype.isLong && !sourceDatatype.isStructInstance) if(!(sourceDatatype isAssignableTo targetDatatype)) - errors.err("incompatible value type, can only assign uword or correct pointer type", position) + errors.err("incompatible value type, can only assign uword, long, or correct pointer type", position) } else if(targetDatatype.isString && sourceDatatype.isUnsignedWord) errors.err("can't assign uword to str. If the source is a string pointer and you actually want to overwrite the target string, use an explicit strings.copy(src,tgt) instead.", position) diff --git a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt index 4f6f0f9cc..56a633390 100644 --- a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt +++ b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt @@ -161,7 +161,7 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co if(options.compTarget.name != VMTarget.NAME && expr.left.inferType(program).isPointer) { val cast = expr.right as? TypecastExpression if(cast!=null && cast.type.isWord && cast.expression.inferType(program).isBytes) { - val structsize = expr.left.inferType(program).getOrUndef().size(program.memsizer) + val structsize = expr.left.inferType(program).getOrUndef().size(program.target) // pointer + byte -> (pointer as uword) + (byte as uword * structsize) (yields better code on 6502 than the plain pointer arithmetic) // but only if the struct/value size is >1 if(structsize>1) { diff --git a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt index 3b84e3cba..eb2ac194a 100644 --- a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt +++ b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt @@ -789,7 +789,7 @@ _after: true // for calls (indirect JSR), split array is always the optimal choice else target.cpu==CpuType.CPU6502 // for goto (indirect JMP), split array is optimal for 6502, but NOT for the 65C02 (it has a different JMP addressing mode available) - val arrayDt = DataType.arrayFor(BaseDataType.UWORD, split) + val arrayDt = DataType.arrayFor(BaseDataType.UWORD) val labelArray = ArrayLiteral(InferredTypes.knownFor(arrayDt), ongoto.labels.toTypedArray(), ongoto.position) val jumplistArray = VarDecl.createAutoOptionalSplit(labelArray) @@ -978,13 +978,13 @@ _after: val ptrVar = deref.definingScope.lookup(ptrName) as? VarDecl if(ptrVar!=null && (ptrVar.datatype.isPointer || ptrVar.datatype.isPointerArray)) { val struct = ptrVar.datatype.subType!! as StructDecl - val offsetNumber = NumericLiteral.optimalInteger(struct.offsetof(field.first, program.memsizer)!!.toInt(), deref.position) + val offsetNumber = NumericLiteral.optimalInteger(struct.offsetof(field.first, program.target)!!.toInt(), deref.position) val pointerIdentifier = IdentifierReference(ptrName, deref.position) val addrType = if(target.POINTER_MEM_SIZE > 2u) DataType.LONG else DataType.UWORD val address: Expression if(ptrVar.datatype.isPointer) { // pointer[idx].field = value --> pokeXXX(pointer as uword/long + idx*sizeof(Struct) + offsetof(Struct.field), value) - val structSize = ptrVar.datatype.dereference().size(program.memsizer) + val structSize = ptrVar.datatype.dereference().size(program.target) val pointerAsAddr = TypecastExpression(pointerIdentifier, addrType, true, deref.position) val idx = ptr.last().second!!.indexExpr val scaledIndex = BinaryExpression(idx, "*", NumericLiteral(BaseDataType.UWORD, structSize.toDouble(), deref.position), deref.position) @@ -1162,7 +1162,7 @@ _after: if(targetDt.isStructInstance && sourceDt.isStructInstance) { if(targetDt == sourceDt) { // special case simple struct instance assignment via memory copy - val size = program.memsizer.memorySize(sourceDt.getOrUndef(), null) + val size = program.target.memorySize(sourceDt.getOrUndef(), null) val structSizeNum = NumericLiteral.optimalInteger(size, assignment.position) val deref = assignment.value as? PtrDereference if(deref!=null) { diff --git a/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVarsAndRecombineIdentifiers.kt b/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVarsAndRecombineIdentifiers.kt index 4a853636a..fbd39d7ce 100644 --- a/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVarsAndRecombineIdentifiers.kt +++ b/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVarsAndRecombineIdentifiers.kt @@ -67,7 +67,7 @@ internal class LiteralsToAutoVarsAndRecombineIdentifiers(private val program: Pr // turn the array literal it into an identifier reference val litval2 = array.cast(targetDt.getOrUndef()) if (litval2 != null) { - val vardecl2 = VarDecl.createAuto(litval2) + val vardecl2 = VarDecl.createAuto(litval2, program.target) val identifier = IdentifierReference(listOf(vardecl2.name), vardecl2.position) return listOf( AstReplaceNode(array, identifier, parent), diff --git a/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt b/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt index 1e81c37f3..3dbbc3916 100644 --- a/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt @@ -85,7 +85,7 @@ internal class M68kAstChecker(private val errors: IErrorReporter) : IAstVisitor if (decl.splitwordarray == SplitWish.NOSPLIT) { errors.err("@nosplit is not available on the m68k target (there are no split word arrays)", decl.position) } - if (decl.datatype.isSplitWordArray) { + if (decl.datatype.isSplitWordArray && decl.splitwordarray != SplitWish.DONTCARE) { errors.err("split word arrays are not supported on the m68k target", decl.position) } decl.value?.accept(this) diff --git a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt index 302c69df6..cd34b8ecd 100644 --- a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt @@ -42,8 +42,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro val ptProgram = PtProgram( program.name, - program.memsizer, - program.encoding + program.target ) // note: modules are not represented any longer in this Ast. All blocks have been moved into the top scope. @@ -272,7 +271,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro // pointer arithmetic: add or subract the size of the struct times the argument val leftDt = expr.left.inferType(program).getOrUndef() require(leftDt.isPointer && !expr.right.inferType(program).isPointer) - val structSize = leftDt.size(program.memsizer) + val structSize = leftDt.size(program.target) val constValue = augmentedValue.constValue(program) if(constValue!=null) { val total = constValue.number*structSize @@ -991,7 +990,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro val offsType = addrType.base // use the target-appropriate offset type (UWORD on 6502, LONG on m68k) if(leftDt.isPointer && !rightDt.isPointer) { - val structSize = leftDt.size(program.memsizer) + val structSize = leftDt.size(program.target) val constValue = expr.right.constValue(program) if(constValue!=null) { // ptr + constvalue * structsize @@ -1032,7 +1031,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro } } } else if(!leftDt.isPointer && rightDt.isPointer) { - val structSize = rightDt.size(program.memsizer) + val structSize = rightDt.size(program.target) val constValue = expr.left.constValue(program) if(constValue!=null) { // ptr + constvalue * structsize @@ -1176,8 +1175,8 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro if(type.isSplitWordArray) { // ranges are never a split word array! when(type.sub) { - BaseDataType.WORD -> type = DataType.arrayFor(BaseDataType.WORD, false) - BaseDataType.UWORD -> type = DataType.arrayFor(BaseDataType.UWORD, false) + BaseDataType.WORD -> type = DataType.arrayFor(BaseDataType.WORD) + BaseDataType.UWORD -> type = DataType.arrayFor(BaseDataType.UWORD) else -> { } } } diff --git a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt index 42137e025..95ddec685 100644 --- a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt +++ b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt @@ -318,7 +318,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val paramsPossibleDatatypes = BuiltinFunctions.getValue(sub.name).parameters.map { it.possibleDatatypes.map { dt -> if(dt.isArray) - DataType.arrayFor(BaseDataType.BOOL, false) // the builtin function signature doesn't tell us the element type.... + DataType.arrayFor(BaseDataType.BOOL) // the builtin function signature doesn't tell us the element type.... else if(dt.isPointer) DataType.pointer(BaseDataType.UBYTE) else diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index 55fdf27e0..26360a407 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -31,7 +31,9 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, VarDeclType.VAR -> { if(decl.isArray) { // using a array of words as initializer to a pointer array is fine - if (!valueDt.isSplitWordArray || !decl.datatype.isPointerArray) + val ok = valueDt.isSplitWordArray && decl.datatype.isPointerArray || + valueDt.isWordArray && decl.datatype.isPointerArray && decl.splitwordarray == SplitWish.DONTCARE && options.compTarget.POINTER_MEM_SIZE == 2u + if (!ok) errors.err("value has incompatible type ($valueType) for the variable (${decl.datatype})", decl.value!!.position) } else if(!decl.datatype.isString) { if (valueDt.largerSizeThan(decl.datatype)) { @@ -87,17 +89,24 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, var changeDataType: DataType? when(decl.splitwordarray) { SplitWish.DONTCARE -> { - changeDataType = if(decl.datatype.isSplitWordArray) null else { + changeDataType = if(decl.datatype.isSplitWordArray) { + if(options.compTarget.POINTER_MEM_SIZE > 2u) + DataType.arrayFor(decl.datatype.elementType().base) + else + null + } else { val eltDt = decl.datatype.elementType() if(eltDt.isPointer) TODO("convert array of pointers to split words array type ${decl.position}") + else if(options.compTarget.POINTER_MEM_SIZE == 2u) + DataType.splitWordArrayFor(eltDt.base) else - DataType.arrayFor(eltDt.base) + null } } SplitWish.NOSPLIT -> { changeDataType = if(decl.datatype.isSplitWordArray && !decl.datatype.elementType().isPointer) - DataType.arrayFor(decl.datatype.elementType().base, false) + DataType.arrayFor(decl.datatype.elementType().base) else null } } @@ -116,7 +125,21 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, // handle @nosplit on pointer arrays: convert to regular non-split word array if(decl.datatype.isPointerArray && decl.splitwordarray == SplitWish.NOSPLIT) { - val newDt = DataType.arrayFor(BaseDataType.UWORD, false) // false = not split (sequential) + val newDt = DataType.arrayFor(BaseDataType.UWORD) // non-split + var value = decl.value + if(value is ArrayLiteral && !(value.type istype newDt)) { + value = ArrayLiteral(InferredTypes.knownFor(newDt), value.value, value.position) + } + val newDecl = VarDecl.builder(newDt, decl.position) + .copyFrom(decl) + .value(value) + .build() + return listOf(AstReplaceNode(decl, newDecl, parent)) + } + + // handle DONTCARE pointer arrays on non-6502 targets: convert back to regular array with long elements + if(decl.datatype.isPointerArray && decl.splitwordarray == SplitWish.DONTCARE && options.compTarget.POINTER_MEM_SIZE > 2u) { + val newDt = DataType.arrayFor(BaseDataType.LONG) var value = decl.value if(value is ArrayLiteral && !(value.type istype newDt)) { value = ArrayLiteral(InferredTypes.knownFor(newDt), value.value, value.position) @@ -438,7 +461,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, if(stringVal.value.isEmpty()) return replaceWithFalse() if(stringVal.value.length==1) { - val string = program.encoding.encodeString(stringVal.value, stringVal.encoding) + val string = program.target.encodeString(stringVal.value, stringVal.encoding) return replaceWithEquals(NumericLiteral(BaseDataType.UBYTE, string[0].toDouble(), stringVal.position)) } return noModifications diff --git a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt index 96542e78b..b8acf89a5 100644 --- a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt +++ b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt @@ -122,6 +122,14 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila if(paramDt.isPointer && argDt.base==BaseDataType.LONG) return true + // if expected is LONG and actual is an array, we allow it (address of array is a long on 32-bit targets) + if(paramDt.isLong && argDt.isArray) + return true + + // if expected is LONG and actual is any pointer, we allow it (pointer is a long on m68k) + if(paramDt.isLong && argDt.isPointer) + return true + if(paramDt.isString && (argDt.isPointer && argDt.sub==BaseDataType.UBYTE)) return true diff --git a/compiler/test/TestCallgraph.kt b/compiler/test/TestCallgraph.kt index 7d15a0840..b65364803 100644 --- a/compiler/test/TestCallgraph.kt +++ b/compiler/test/TestCallgraph.kt @@ -19,7 +19,9 @@ import prog8.code.target.VMTarget import prog8.compiler.CallGraph import prog8.parser.Prog8Parser.parseModule import prog8.vm.VmRunner -import prog8tests.helpers.* +import prog8tests.helpers.DummyFunctions +import prog8tests.helpers.ErrorReporterForTests +import prog8tests.helpers.compileText import kotlin.io.path.readText class TestCallgraph: FunSpec({ @@ -166,7 +168,7 @@ class TestCallgraph: FunSpec({ } }""" val module = parseModule(SourceCode.Text(source)) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val program = Program("test", DummyFunctions, VMTarget()) program.addModule(module) val callgraph = CallGraph(program) val blockMain = program.allBlocks.single { it.name=="main" } @@ -201,7 +203,7 @@ class TestCallgraph: FunSpec({ } }""" val module = parseModule(SourceCode.Text(source)) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val program = Program("test", DummyFunctions, VMTarget()) program.addModule(module) val callgraph = CallGraph(program) val errors = ErrorReporterForTests() @@ -225,7 +227,7 @@ class TestCallgraph: FunSpec({ } }""" val module = parseModule(SourceCode.Text(source)) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val program = Program("test", DummyFunctions, VMTarget()) program.addModule(module) val callgraph = CallGraph(program) val errors = ErrorReporterForTests() diff --git a/compiler/test/TestMemory.kt b/compiler/test/TestMemory.kt index d8e24b96e..c40b22440 100644 --- a/compiler/test/TestMemory.kt +++ b/compiler/test/TestMemory.kt @@ -14,10 +14,14 @@ import prog8.ast.expressions.IdentifierReference import prog8.ast.expressions.NumericLiteral import prog8.ast.expressions.PrefixExpression import prog8.ast.statements.* -import prog8.code.core.* +import prog8.code.core.BaseDataType +import prog8.code.core.DataType +import prog8.code.core.Position import prog8.code.source.SourceCode import prog8.code.target.* -import prog8tests.helpers.* +import prog8tests.helpers.DummyFunctions +import prog8tests.helpers.ErrorReporterForTests +import prog8tests.helpers.compileText class TestMemory: FunSpec({ @@ -26,7 +30,7 @@ class TestMemory: FunSpec({ val outputDir = tempdir().toPath() fun wrapWithProgram(statements: List): Program { - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val program = Program("test", DummyFunctions, c64target) val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, false, statements.toMutableList(), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) program.addModule(module) @@ -271,7 +275,7 @@ class TestMemory: FunSpec({ val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) - Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + Program("test", DummyFunctions, c64target) .addModule(module) target.isIOAddress(c64target) shouldBe false } @@ -294,7 +298,7 @@ class TestMemory: FunSpec({ val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) - Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + Program("test", DummyFunctions, c64target) .addModule(module) target.isIOAddress(c64target) shouldBe false } @@ -317,7 +321,7 @@ class TestMemory: FunSpec({ val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) - Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + Program("test", DummyFunctions, c64target) .addModule(module) target.isIOAddress(c64target) shouldBe true } @@ -331,7 +335,7 @@ class TestMemory: FunSpec({ val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) - Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + Program("test", DummyFunctions, c64target) .addModule(module) target.isIOAddress(c64target) shouldBe false } @@ -348,7 +352,7 @@ class TestMemory: FunSpec({ val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) - Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + Program("test", DummyFunctions, c64target) .addModule(module) target.isIOAddress(c64target) shouldBe false } @@ -365,7 +369,7 @@ class TestMemory: FunSpec({ val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) - Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + Program("test", DummyFunctions, c64target) .addModule(module) target.isIOAddress(c64target) shouldBe true } @@ -421,8 +425,8 @@ class TestMemory: FunSpec({ target.memorySize(DataType.arrayFor(BaseDataType.UWORD), 10) shouldBe 20 target.memorySize(DataType.arrayFor(BaseDataType.LONG), 10) shouldBe 40 target.memorySize(DataType.arrayFor(BaseDataType.FLOAT), 10) shouldBe 10*target.FLOAT_MEM_SIZE.toInt() - target.memorySize(DataType.arrayFor(BaseDataType.WORD, true), 10) shouldBe 20 - target.memorySize(DataType.arrayFor(BaseDataType.UWORD, true), 10) shouldBe 20 + target.memorySize(DataType.splitWordArrayFor(BaseDataType.WORD), 10) shouldBe 20 + target.memorySize(DataType.splitWordArrayFor(BaseDataType.UWORD), 10) shouldBe 20 target.memorySize(DataType.BOOL, 10) shouldBe 10 target.memorySize(DataType.UWORD, 10) shouldBe 20 diff --git a/compiler/test/TestModuleImporter.kt b/compiler/test/TestModuleImporter.kt index 76070053e..73b37c5be 100644 --- a/compiler/test/TestModuleImporter.kt +++ b/compiler/test/TestModuleImporter.kt @@ -13,6 +13,7 @@ import prog8.code.INTERNED_STRINGS_MODULENAME import prog8.code.PROG8_CONTAINER_MODULES import prog8.code.core.IErrorReporter import prog8.code.source.SourceCode +import prog8.code.target.VMTarget import prog8.compiler.ModuleImporter import prog8.parser.MultipleParseErrors import prog8tests.helpers.* @@ -25,7 +26,7 @@ class TestModuleImporter: FunSpec({ lateinit var program: Program beforeTest { - program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + program = Program("foo", DummyFunctions, VMTarget()) } fun makeImporter(errors: IErrorReporter? = null, searchIn: Iterable) = diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 43b7c2ef3..951933899 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -23,7 +23,9 @@ import prog8.code.target.C64Target import prog8.code.target.Cx16Target import prog8.code.target.VMTarget import prog8.vm.VmRunner -import prog8tests.helpers.* +import prog8tests.helpers.DummyFunctions +import prog8tests.helpers.ErrorReporterForTests +import prog8tests.helpers.compileText import kotlin.io.path.readText @@ -141,9 +143,10 @@ other { } test("generated constvalue from typecast inherits proper parent linkage") { + val target = VMTarget() val number = NumericLiteral(BaseDataType.UBYTE, 11.0, Position.DUMMY) val tc = TypecastExpression(number, DataType.BYTE, false, Position.DUMMY) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val program = Program("test", DummyFunctions, target) tc.linkParents(ParentSentinel) tc.parent shouldNotBe null number.parent shouldNotBe null @@ -156,9 +159,10 @@ other { } test("generated constvalue from prefixexpr inherits proper parent linkage") { + val target = VMTarget() val number = NumericLiteral(BaseDataType.UBYTE, 11.0, Position.DUMMY) val pfx = PrefixExpression("-", number, Position.DUMMY) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val program = Program("test", DummyFunctions, target) pfx.linkParents(ParentSentinel) pfx.parent shouldNotBe null number.parent shouldNotBe null diff --git a/compiler/test/TestPointers.kt b/compiler/test/TestPointers.kt index d7e51543d..088685d53 100644 --- a/compiler/test/TestPointers.kt +++ b/compiler/test/TestPointers.kt @@ -662,7 +662,7 @@ main { compileText(VMTarget(), false, src, outputDir, errors=errors) val err = errors.errors err.size shouldBe 1 - err[0] shouldContain("15:16: incompatible value type, can only assign uword or correct pointer") + err[0] shouldContain("15:16: incompatible value type, can only assign uword") } test("pointer uword assignments with cast") { @@ -757,12 +757,12 @@ main { DataType.UNDEFINED.typeForUntypedAddressOf(false, memsizer) shouldBe DataType.UWORD DataType.UNDEFINED.typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) DataType.STR.typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.FLOAT, false).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.FLOAT) - DataType.arrayFor(BaseDataType.FLOAT, false).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.UWORD, false).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UWORD) - DataType.arrayFor(BaseDataType.UWORD, true).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.UWORD, false).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) - DataType.arrayFor(BaseDataType.UWORD, true).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.arrayFor(BaseDataType.FLOAT).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.FLOAT) + DataType.arrayFor(BaseDataType.FLOAT).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.arrayFor(BaseDataType.UWORD).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UWORD) + DataType.splitWordArrayFor(BaseDataType.UWORD).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.arrayFor(BaseDataType.UWORD).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) + DataType.splitWordArrayFor(BaseDataType.UWORD).typeForUntypedAddressOf(true, memsizer) shouldBe DataType.pointer(BaseDataType.UBYTE) DataType.pointer(Struct("struct")).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.UWORD DataType.pointerFromAntlr(listOf("struct")).typeForUntypedAddressOf(false, memsizer) shouldBe DataType.UWORD diff --git a/compiler/test/ast/TestAstToSourceText.kt b/compiler/test/ast/TestAstToSourceText.kt index 9b64ffb97..84a8eb936 100644 --- a/compiler/test/ast/TestAstToSourceText.kt +++ b/compiler/test/ast/TestAstToSourceText.kt @@ -7,18 +7,18 @@ import prog8.ast.Module import prog8.ast.Program import prog8.code.PROG8_CONTAINER_MODULES import prog8.code.source.SourceCode +import prog8.code.target.VMTarget import prog8.parser.ParseError import prog8.parser.Prog8Parser.parseModule import prog8tests.helpers.DummyFunctions -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder class TestAstToSourceText: FunSpec({ // Helper function to generate Prog8 source from AST fun generateP8(module: Module): String { - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("test", DummyFunctions, target) .addModule(module) var generatedText = "" diff --git a/compiler/test/ast/TestIdentifierRef.kt b/compiler/test/ast/TestIdentifierRef.kt index ab110d915..e0fa020b5 100644 --- a/compiler/test/ast/TestIdentifierRef.kt +++ b/compiler/test/ast/TestIdentifierRef.kt @@ -14,10 +14,9 @@ import prog8.ast.statements.Subroutine import prog8.ast.statements.VarDecl import prog8.code.core.Position import prog8.code.source.SourceCode +import prog8.code.target.VMTarget import prog8.parser.Prog8Parser import prog8tests.helpers.DummyFunctions -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder class TestIdentifierRef: FunSpec({ @@ -55,7 +54,8 @@ class TestIdentifierRef: FunSpec({ } } """) val module = Prog8Parser.parseModule(src) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("test", DummyFunctions, target) program.addModule(module) val mstmts = (module.statements.single() as Block).statements val stmts = mstmts.filterIsInstance().single().statements diff --git a/compiler/test/ast/TestProg8Parser.kt b/compiler/test/ast/TestProg8Parser.kt index bab690ded..22a70ef78 100644 --- a/compiler/test/ast/TestProg8Parser.kt +++ b/compiler/test/ast/TestProg8Parser.kt @@ -677,9 +677,10 @@ class TestProg8Parser: FunSpec( { val char3 = CharLiteral.create('_', Encoding.ISO, Position.DUMMY) val char4 = CharLiteral.create('_', Encoding.DEFAULT, Position.DUMMY) - val program = Program("test", DummyFunctions, DummyMemsizer, AsciiStringEncoder) - char1.constValue(program)?.number?.toInt() shouldBe 65 - char2.constValue(program)?.number?.toInt() shouldBe 122 + val target = VMTarget() + val program = Program("test", DummyFunctions, target) + char1.constValue(program)?.number?.toInt() shouldBe 193 + char2.constValue(program)?.number?.toInt() shouldBe 26 char3.constValue(program)?.number?.toInt() shouldBe 95 char4.constValue(program) shouldBe null } @@ -810,7 +811,8 @@ class TestProg8Parser: FunSpec( { } """) val module = parseModule(src) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("test", DummyFunctions, target) program.addModule(module) val bb2 = (module.statements.single() as Block).statements[2] as VarDecl val expr = bb2.value as BinaryExpression @@ -833,7 +835,8 @@ class TestProg8Parser: FunSpec( { } """) val module = parseModule(src) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("test", DummyFunctions, target) program.addModule(module) val stmts = (module.statements.single() as Block).statements stmts.size shouldBe 6 @@ -860,7 +863,8 @@ class TestProg8Parser: FunSpec( { ubyte ub = (cos8(r)/2 + 100) as ubyte }""") val module = parseModule(src) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("test", DummyFunctions, target) program.addModule(module) val stmts = (module.statements.single() as Block).statements stmts.size shouldBe 2 @@ -891,7 +895,8 @@ class TestProg8Parser: FunSpec( { }""") val module = parseModule(src) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("test", DummyFunctions, target) program.addModule(module) val stmts = program.entrypoint.statements val expectedResults = listOf( diff --git a/compiler/test/ast/TestProgram.kt b/compiler/test/ast/TestProgram.kt index 5af1c10b6..cadffbd16 100644 --- a/compiler/test/ast/TestProgram.kt +++ b/compiler/test/ast/TestProgram.kt @@ -19,9 +19,8 @@ import prog8.code.ast.PtBlock import prog8.code.core.Position import prog8.code.source.SourceCode import prog8.code.target.C64Target +import prog8.code.target.VMTarget import prog8tests.helpers.DummyFunctions -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder import prog8tests.helpers.compileText class TestProgram: FunSpec({ @@ -30,7 +29,8 @@ class TestProgram: FunSpec({ context("Constructor") { test("withNameBuiltinsAndMemsizer") { - val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("foo", DummyFunctions, target) program.modules.size shouldBe PROG8_CONTAINER_MODULES.size program.modules[0].name shouldBe INTERNED_STRINGS_MODULENAME program.modules[0].program shouldBeSameInstanceAs program @@ -40,7 +40,8 @@ class TestProgram: FunSpec({ context("AddModule") { test("withEmptyModule") { - val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("foo", DummyFunctions, target) val m1 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar")) val retVal = program.addModule(m1) @@ -66,7 +67,8 @@ class TestProgram: FunSpec({ context("MoveModuleToFront") { test("withInternedStringsModule") { - val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("foo", DummyFunctions, target) val m = program.modules[0] m.name shouldBe INTERNED_STRINGS_MODULENAME @@ -76,14 +78,16 @@ class TestProgram: FunSpec({ } test("withForeignModule") { - val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("foo", DummyFunctions, target) val m = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar")) shouldThrow { program.moveModuleToFront(m) } } test("withFirstOfPreviouslyAddedModules") { - val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("foo", DummyFunctions, target) val m1 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar")) val m2 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("qmbl")) program.addModule(m1) @@ -95,7 +99,8 @@ class TestProgram: FunSpec({ } test("withSecondOfPreviouslyAddedModules") { - val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("foo", DummyFunctions, target) val m1 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar")) val m2 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("qmbl")) program.addModule(m1) @@ -109,7 +114,8 @@ class TestProgram: FunSpec({ context("Properties") { test("modules") { - val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder) + val target = VMTarget() + val program = Program("foo", DummyFunctions, target) val ms1 = program.modules val ms2 = program.modules diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index b5968fe7f..d25c612f7 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -1070,13 +1070,12 @@ main { DataType.forDt(BaseDataType.STR).isString shouldBe true DataType.forDt(BaseDataType.FLOAT).isFloat shouldBe true - DataType.arrayFor(BaseDataType.UBYTE, true).isUnsignedByteArray shouldBe true DataType.arrayFor(BaseDataType.LONG).isLongArray shouldBe true DataType.arrayFor(BaseDataType.FLOAT).isFloatArray shouldBe true DataType.arrayFor(BaseDataType.UWORD).isUnsignedWordArray shouldBe true DataType.arrayFor(BaseDataType.UWORD).isArray shouldBe true - DataType.arrayFor(BaseDataType.UWORD).isSplitWordArray shouldBe true - DataType.arrayFor(BaseDataType.UWORD, false).isSplitWordArray shouldBe false + DataType.splitWordArrayFor(BaseDataType.UWORD).isSplitWordArray shouldBe true + DataType.arrayFor(BaseDataType.UWORD).isSplitWordArray shouldBe false shouldThrow { DataType.forDt(BaseDataType.ARRAY) @@ -1112,7 +1111,7 @@ main { (st1[1] as VarDecl).name shouldBe "names" val array1 = (st1[1] as VarDecl).value as ArrayLiteral array1.type.isArray shouldBe true - array1.type.getOrUndef() shouldBe DataType.arrayFor(BaseDataType.UWORD, true) + array1.type.getOrUndef() shouldBe DataType.splitWordArrayFor(BaseDataType.UWORD) val ast2 = result.codegenAst!! val st2 = ast2.entrypoint()!!.children @@ -1120,7 +1119,7 @@ main { (st2[1] as PtVariable).name shouldBe "p8v_variable" (st2[2] as PtVariable).name shouldBe "p8v_names" val array2 = (st2[2] as PtVariable).value as PtArray - array2.type shouldBe DataType.arrayFor(BaseDataType.UWORD, true) + array2.type shouldBe DataType.splitWordArrayFor(BaseDataType.UWORD) } diff --git a/compiler/test/codegeneration/TestAsmGenSymbols.kt b/compiler/test/codegeneration/TestAsmGenSymbols.kt index 4c9523ca2..1240287d3 100644 --- a/compiler/test/codegeneration/TestAsmGenSymbols.kt +++ b/compiler/test/codegeneration/TestAsmGenSymbols.kt @@ -21,10 +21,13 @@ import prog8.code.target.VMTarget import prog8.codegen.cpu6502.AsmGen6502Internal import prog8.compiler.astprocessing.AstChecker import prog8.compiler.astprocessing.SimplifiedAstMaker -import prog8tests.helpers.* +import prog8tests.helpers.DummyFunctions +import prog8tests.helpers.ErrorReporterForTests +import prog8tests.helpers.compileText class TestAsmGenSymbols: StringSpec({ val outputDir = tempdir().toPath() + val target = VMTarget() fun createTestProgram(): Program { /* @@ -78,7 +81,7 @@ class TestAsmGenSymbols: StringSpec({ val block = Block("main", null, mutableListOf(labelInBlock, varInBlock, subroutine), false, Position.DUMMY) val module = Module(mutableListOf(block), Position.DUMMY, SourceCode.Generated("test")) - val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder).addModule(module) + val program = Program("test", DummyFunctions, target).addModule(module) return program } @@ -171,8 +174,8 @@ main { asmgen.asmSymbolName(listOf("prog8_lib","P8ZP_SCRATCH_W2")) shouldBe "P8ZP_SCRATCH_W2" val id1 = PtIdentifier("prog8_lib.P8ZP_SCRATCH_REG", DataType.UBYTE, Position.DUMMY) val id2 = PtIdentifier("prog8_lib.P8ZP_SCRATCH_W2", DataType.UWORD, Position.DUMMY) - id1.parent = PtProgram("test", DummyMemsizer, DummyStringEncoder) - id2.parent = PtProgram("test", DummyMemsizer, DummyStringEncoder) + id1.parent = PtProgram("test", VMTarget()) + id2.parent = PtProgram("test", VMTarget()) asmgen.asmSymbolName(id1) shouldBe "P8ZP_SCRATCH_REG" asmgen.asmSymbolName(id2) shouldBe "P8ZP_SCRATCH_W2" } diff --git a/compiler/test/codegeneration/TestLibrary.kt b/compiler/test/codegeneration/TestLibrary.kt index d2c8c90c9..3d710417c 100644 --- a/compiler/test/codegeneration/TestLibrary.kt +++ b/compiler/test/codegeneration/TestLibrary.kt @@ -61,7 +61,7 @@ library { main.name shouldBe "p8b_main" val jumptable = main.children[0] as PtVariable jumptable.name shouldBe "p8v_jumptable" - jumptable.type shouldBe DataType.arrayFor(BaseDataType.UWORD, false) + jumptable.type shouldBe DataType.arrayFor(BaseDataType.UWORD) jumptable.arraySize shouldBe 4u val bin = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".bin").readBytes().map { it.toUByte() } @@ -144,7 +144,7 @@ library { main.name shouldBe "p8b_main" val jumptable = main.children[0] as PtVariable jumptable.name shouldBe "p8v_jumptable" - jumptable.type shouldBe DataType.arrayFor(BaseDataType.UWORD, false) + jumptable.type shouldBe DataType.arrayFor(BaseDataType.UWORD) jumptable.arraySize shouldBe 4u val asm = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".asm").readText() println(asm) @@ -187,4 +187,4 @@ library { // check func2 bin[offset(func2Addr)] shouldBe 0xCeu // DEC abs } -}) \ No newline at end of file +}) diff --git a/compiler/test/codegeneration/TestVariousCodeGen.kt b/compiler/test/codegeneration/TestVariousCodeGen.kt index 2fb040c26..780406e8a 100644 --- a/compiler/test/codegeneration/TestVariousCodeGen.kt +++ b/compiler/test/codegeneration/TestVariousCodeGen.kt @@ -67,7 +67,7 @@ main { val text=""" main { sub start() { - uword[3] seed + uword[3] @nosplit seed cx16.r0 = seed[0] + seed[1] + seed[2] } }""" diff --git a/compilerAst/src/prog8/ast/AstToplevel.kt b/compilerAst/src/prog8/ast/AstToplevel.kt index d29d64687..0255cf39d 100644 --- a/compilerAst/src/prog8/ast/AstToplevel.kt +++ b/compilerAst/src/prog8/ast/AstToplevel.kt @@ -434,9 +434,9 @@ open class Module(final override val statements: MutableList, val textEncoding: Encoding by lazy { val encoding = statements.singleOrNull { it is Directive && it.directive == "%encoding" } as? Directive if(encoding!=null) - Encoding.entries.firstOrNull { it.prefix==encoding.args[0].string } ?: program.encoding.defaultEncoding // invalid encoding will be noticed by ast checker error message + Encoding.entries.firstOrNull { it.prefix==encoding.args[0].string } ?: program.target.defaultEncoding // invalid encoding will be noticed by ast checker error message else - program.encoding.defaultEncoding + program.target.defaultEncoding } val isLibrary get() = source.isFromLibrary diff --git a/compilerAst/src/prog8/ast/Program.kt b/compilerAst/src/prog8/ast/Program.kt index 07741e577..f4c1e96e5 100644 --- a/compilerAst/src/prog8/ast/Program.kt +++ b/compilerAst/src/prog8/ast/Program.kt @@ -14,8 +14,7 @@ import prog8.code.source.SourceCode class Program(val name: String, val builtinFunctions: IBuiltinFunctions, - val memsizer: IMemSizer, - val encoding: IStringEncoding + val target: ICompilationTarget ) { private val _modules = mutableListOf() diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt b/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt index d4d072975..ca17991ed 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt @@ -12,6 +12,7 @@ import prog8.ast.expressions.* import prog8.ast.statements.* import prog8.code.core.* import prog8.code.source.SourceCode + import prog8.parser.Prog8ANTLRParser.* import prog8.parser.Prog8ANTLRVisitor import kotlin.io.path.Path @@ -218,7 +219,7 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor index - target.datatype.isPointer || target.datatype.isArray -> index * targetVar.datatype.size(program.memsizer) + target.datatype.isPointer || target.datatype.isArray -> index * targetVar.datatype.size(program.target) else -> throw FatalAstException("need array or ptr") } } else @@ -691,16 +691,16 @@ data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: Array override fun referencesIdentifier(nameInSource: List) = identifier?.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true || dereference?.referencesIdentifier(nameInSource)==true override fun inferType(program: Program): InferredTypes.InferredType { if(!typed) { - val untypedPointerType = if(program.memsizer.memorySize(BaseDataType.POINTER)>2) BaseDataType.LONG else BaseDataType.UWORD + val untypedPointerType = if(program.target.memorySize(BaseDataType.POINTER)>2) BaseDataType.LONG else BaseDataType.UWORD return InferredTypes.knownFor(untypedPointerType) } if(identifier!=null) { val type = identifier!!.inferType(program).getOrUndef() - val addrofDt = type.typeForUntypedAddressOf(msb, program.memsizer) + val addrofDt = type.typeForUntypedAddressOf(msb, program.target) return if(addrofDt.isUndefined) InferredTypes.unknown() else InferredTypes.knownFor(addrofDt) } else if(dereference!=null) { val type = dereference!!.inferType(program).getOrUndef() - val addrofDt = type.typeForUntypedAddressOf(msb, program.memsizer) + val addrofDt = type.typeForUntypedAddressOf(msb, program.target) return if(addrofDt.isUndefined) InferredTypes.unknown() else InferredTypes.knownFor(addrofDt) } else throw FatalAstException("invalid addressof") @@ -1149,7 +1149,7 @@ class CharLiteral private constructor(val value: Char, override fun constValue(program: Program): NumericLiteral? { if(encoding== Encoding.DEFAULT) // will be determined at a later stage, hopefully return null - val bytevalue = program.encoding.encodeString(value.toString(), encoding).single() + val bytevalue = program.target.encodeString(value.toString(), encoding).single() return NumericLiteral(BaseDataType.UBYTE, bytevalue.toDouble(), position) } override fun accept(visitor: IAstVisitor) = visitor.visit(this) @@ -1794,7 +1794,7 @@ class ContainmentCheck(var element: Expression, val stringval = iterable as StringLiteral if(stringval.encoding== Encoding.DEFAULT) // will be set at a later stage, hopefully return null - val exists = program.encoding.encodeString(stringval.value, stringval.encoding).contains(elementConst.number.toInt().toUByte() ) + val exists = program.target.encodeString(stringval.value, stringval.encoding).contains(elementConst.number.toInt().toUByte() ) return NumericLiteral.fromBoolean(exists, position) } } diff --git a/compilerAst/src/prog8/ast/expressions/InferredTypes.kt b/compilerAst/src/prog8/ast/expressions/InferredTypes.kt index 2a9a82e9c..bd67963e5 100644 --- a/compilerAst/src/prog8/ast/expressions/InferredTypes.kt +++ b/compilerAst/src/prog8/ast/expressions/InferredTypes.kt @@ -107,21 +107,6 @@ object InferredTypes { if(instance!=null) return instance else - return when { - type.isPointerArray -> InferredType.known(type) - type.isSplitWordArray -> { - when (type.sub) { - BaseDataType.UWORD -> InferredType.known(DataType.arrayFor(BaseDataType.UWORD)) - BaseDataType.WORD -> InferredType.known(DataType.arrayFor(BaseDataType.WORD)) - BaseDataType.STR -> InferredType.known(DataType.arrayFor(BaseDataType.STR)) - else -> throw IllegalArgumentException("invalid sub type") - } - } - - type.isArray -> InferredType.known(type) - type.isPointer -> InferredType.known(type) - type.isStructInstance -> InferredType.known(type) - else -> throw IllegalArgumentException("invalid type $type") - } + return InferredType.known(type) } } diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index ee45bc09b..709fd77cd 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -389,14 +389,14 @@ class VarDecl( .build() } - fun createAuto(array: ArrayLiteral): VarDecl { + fun createAuto(array: ArrayLiteral, target: ICompilationTarget): VarDecl { val autoVarName = "auto_heap_value_${++autoHeapValueSequenceNumber}" var arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") } if(arrayDt.isSplitWordArray) { // autovars for array literals are NEVER stored as a split word array! when(arrayDt.sub) { - BaseDataType.WORD -> arrayDt = DataType.arrayFor(BaseDataType.WORD, false) - BaseDataType.UWORD -> arrayDt = DataType.arrayFor(BaseDataType.UWORD, false) + BaseDataType.WORD -> arrayDt = DataType.arrayFor(BaseDataType.WORD) + BaseDataType.UWORD -> arrayDt = DataType.arrayFor(BaseDataType.UWORD) else -> { } } } diff --git a/intermediate/src/prog8/intermediate/IRFileReader.kt b/intermediate/src/prog8/intermediate/IRFileReader.kt index b692b14f4..a6f61baf6 100644 --- a/intermediate/src/prog8/intermediate/IRFileReader.kt +++ b/intermediate/src/prog8/intermediate/IRFileReader.kt @@ -57,6 +57,8 @@ class IRFileReader { } } } + + private lateinit var options: CompilationOptions private fun parseProgram(reader: XMLEventReader): IRProgram { require(reader.nextEvent().isStartDocument) @@ -64,7 +66,7 @@ class IRFileReader { require(start.name.localPart=="PROGRAM") { "missing PROGRAM" } val programName = start.attributes.asSequence().single { it.name.localPart == "NAME" }.value val compilerVersion = start.attributes.asSequence().single { it.name.localPart == "COMPILERVERSION" }.value - val options = parseOptions(reader, compilerVersion) + options = parseOptions(reader, compilerVersion) val asmsymbols = parseAsmSymbols(reader) skipText(reader) @@ -612,13 +614,13 @@ class IRFileReader { } } return when(type) { - "bool" -> DataType.arrayFor(BaseDataType.BOOL, false) - "byte" -> DataType.arrayFor(BaseDataType.BYTE, false) - "ubyte", "str" -> DataType.arrayFor(BaseDataType.UBYTE, false) - "word" -> DataType.arrayFor(BaseDataType.WORD, false) - "uword" -> DataType.arrayFor(BaseDataType.UWORD, false) - "float" -> DataType.arrayFor(BaseDataType.FLOAT, false) - "long" -> DataType.arrayFor(BaseDataType.LONG, false) + "bool" -> DataType.arrayFor(BaseDataType.BOOL) + "byte" -> DataType.arrayFor(BaseDataType.BYTE) + "ubyte", "str" -> DataType.arrayFor(BaseDataType.UBYTE) + "word" -> DataType.arrayFor(BaseDataType.WORD) + "uword" -> DataType.arrayFor(BaseDataType.UWORD) + "float" -> DataType.arrayFor(BaseDataType.FLOAT) + "long" -> DataType.arrayFor(BaseDataType.LONG) else -> { throw IRParseException("invalid dt $type") } diff --git a/simpleAst/src/prog8/code/ast/AstBase.kt b/simpleAst/src/prog8/code/ast/AstBase.kt index a467174ba..78901fff7 100644 --- a/simpleAst/src/prog8/code/ast/AstBase.kt +++ b/simpleAst/src/prog8/code/ast/AstBase.kt @@ -132,15 +132,14 @@ sealed class PtNamedNode(initialName: String, position: Position): PtNode(positi class PtProgram( val name: String, - val memsizer: IMemSizer, - val encoding: IStringEncoding + val target: ICompilationTarget ) : PtNode(Position.DUMMY) { + val memsizer: IMemSizer get() = target + val encoding: IStringEncoding get() = target + // Root node is never transformed - return self override fun copy(): PtNode = this -// fun allModuleDirectives(): Sequence = -// children.asSequence().flatMap { it.children }.filterIsInstance().distinct() - fun allBlocks(): Sequence = children.asSequence().filterIsInstance() diff --git a/simpleAst/test/prog8tests/code/TestComparisonOptimizers.kt b/simpleAst/test/prog8tests/code/TestComparisonOptimizers.kt index d666bc914..843b55232 100644 --- a/simpleAst/test/prog8tests/code/TestComparisonOptimizers.kt +++ b/simpleAst/test/prog8tests/code/TestComparisonOptimizers.kt @@ -8,8 +8,7 @@ import prog8.code.core.DataType import prog8.code.core.Position import prog8.code.optimize.ComparisonOptimizers import prog8.code.target.VMTarget -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder + /** * Tests for ComparisonOptimizers, particularly the optimizeComparisonIdentities function. @@ -21,7 +20,7 @@ class TestComparisonOptimizers: FunSpec({ // Helper to create a simple program with a binary expression in a sub fun createProgramWithComparison(operator: String, leftType: DataType): PtProgram { - val program = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val program = PtProgram("test", VMTarget()) val block = PtBlock("main", false, prog8.code.source.SourceCode.Generated("main"), PtBlock.Options(), Position.DUMMY) program.add(block) diff --git a/simpleAst/test/prog8tests/code/TestSymbolTableConstruction.kt b/simpleAst/test/prog8tests/code/TestSymbolTableConstruction.kt index 558928589..65cb93379 100644 --- a/simpleAst/test/prog8tests/code/TestSymbolTableConstruction.kt +++ b/simpleAst/test/prog8tests/code/TestSymbolTableConstruction.kt @@ -12,8 +12,7 @@ import prog8.code.core.DataType import prog8.code.core.Position import prog8.code.core.ZeropageWish import prog8.code.source.SourceCode -import prog8tests.helpers.DummyMemsizer -import prog8tests.helpers.DummyStringEncoder +import prog8.code.target.VMTarget /** * Tests for SymbolTable construction and structural integrity. @@ -32,14 +31,14 @@ class TestSymbolTableConstruction: FunSpec({ // ============================================================================ fun makeSimpleSymbolTable(): SymbolTable { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) return SymbolTable(astProgram) } fun makeSymbolTableWithDuplicates(): Pair { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -59,7 +58,7 @@ class TestSymbolTableConstruction: FunSpec({ // ============================================================================ test("empty symboltable creation") { - val astNode = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astNode = PtProgram("test", VMTarget()) val st = SymbolTable(astNode) st.name shouldBe "test" st.type shouldBe StNodeType.GLOBAL @@ -75,7 +74,7 @@ class TestSymbolTableConstruction: FunSpec({ } test("symboltable with multiple modules") { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock1 = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) val astBlock2 = PtBlock("block2", false, SourceCode.Generated("block2"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock1) @@ -100,7 +99,7 @@ class TestSymbolTableConstruction: FunSpec({ } test("duplicate struct instance insertion is handled") { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -119,7 +118,7 @@ class TestSymbolTableConstruction: FunSpec({ } test("duplicate memory slab insertion is handled") { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -138,7 +137,7 @@ class TestSymbolTableConstruction: FunSpec({ } test("duplicate label insertion is handled") { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -218,7 +217,7 @@ class TestSymbolTableConstruction: FunSpec({ // ================================================================================ private fun makeStWithVariables(): SymbolTable { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -235,7 +234,7 @@ private fun makeStWithVariables(): SymbolTable { } private fun makeStWithMemVars(): SymbolTable { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -250,7 +249,7 @@ private fun makeStWithMemVars(): SymbolTable { } private fun makeStWithSlabs(): SymbolTable { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -265,7 +264,7 @@ private fun makeStWithSlabs(): SymbolTable { } private fun makeStWithStructInstances(): SymbolTable { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram) @@ -280,7 +279,7 @@ private fun makeStWithStructInstances(): SymbolTable { } private fun makeStWithStructs(): SymbolTable { - val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder) + val astProgram = PtProgram("test", VMTarget()) val astBlock = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY) astProgram.add(astBlock) val st = SymbolTable(astProgram)