diff --git a/codeGeneration/codeGeneration.iml b/codeGeneration/codeGeneration.iml
index 9a8fa347e..928636817 100644
--- a/codeGeneration/codeGeneration.iml
+++ b/codeGeneration/codeGeneration.iml
@@ -5,6 +5,7 @@
+
diff --git a/codeGeneration/test/AsmGenTests.kt b/codeGeneration/test/AsmGenTests.kt
index dc2711456..323f6f848 100644
--- a/codeGeneration/test/AsmGenTests.kt
+++ b/codeGeneration/test/AsmGenTests.kt
@@ -21,6 +21,7 @@ import prog8.compilerinterface.*
import prog8.parser.SourceCode
import prog8tests.asmgen.helpers.DummyFunctions
import prog8tests.asmgen.helpers.DummyMemsizer
+import prog8tests.asmgen.helpers.DummyStringEncoder
import prog8tests.asmgen.helpers.ErrorReporterForTests
import java.nio.file.Path
@@ -73,7 +74,7 @@ locallabel:
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)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
module.linkIntoProgram(program)
return program
diff --git a/codeGeneration/test/helpers/Dummies.kt b/codeGeneration/test/helpers/Dummies.kt
index abcf1f8fe..ccb9d10f3 100644
--- a/codeGeneration/test/helpers/Dummies.kt
+++ b/codeGeneration/test/helpers/Dummies.kt
@@ -7,6 +7,7 @@ import prog8.ast.expressions.InferredTypes
import prog8.ast.expressions.NumericLiteralValue
import prog8.compilerinterface.IMemSizer
import prog8.ast.base.DataType
+import prog8.compilerinterface.IStringEncoding
internal val DummyFunctions = object : IBuiltinFunctions {
@@ -24,3 +25,13 @@ internal val DummyFunctions = object : IBuiltinFunctions {
internal val DummyMemsizer = object : IMemSizer {
override fun memorySize(dt: DataType): Int = 0
}
+
+internal val DummyStringEncoder = object : IStringEncoding {
+ override fun encodeString(str: String, altEncoding: Boolean): List {
+ return emptyList()
+ }
+
+ override fun decodeString(bytes: List, altEncoding: Boolean): String {
+ return ""
+ }
+}
diff --git a/codeOptimizers/codeOptimizers.iml b/codeOptimizers/codeOptimizers.iml
index 6778075ca..45621612e 100644
--- a/codeOptimizers/codeOptimizers.iml
+++ b/codeOptimizers/codeOptimizers.iml
@@ -5,6 +5,7 @@
+
diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt
index c09a9ef4f..84ec61cbb 100644
--- a/compiler/src/prog8/compiler/Compiler.kt
+++ b/compiler/src/prog8/compiler/Compiler.kt
@@ -115,7 +115,7 @@ fun compileProgram(filepath: Path,
throw x
}
- val failedProgram = Program("failed", BuiltinFunctionsFacade(BuiltinFunctions), compTarget)
+ val failedProgram = Program("failed", BuiltinFunctionsFacade(BuiltinFunctions), compTarget, compTarget)
return CompilationResult(false, failedProgram, programName, compTarget, emptyList())
}
@@ -155,7 +155,7 @@ fun parseImports(filepath: Path,
sourceDirs: List): Triple> {
println("Compiler target: ${compTarget.name}. Parsing...")
val bf = BuiltinFunctionsFacade(BuiltinFunctions)
- val programAst = Program(filepath.nameWithoutExtension, bf, compTarget)
+ val programAst = Program(filepath.nameWithoutExtension, bf, compTarget, compTarget)
bf.program = programAst
val importer = ModuleImporter(programAst, compTarget.name, errors, sourceDirs)
diff --git a/compiler/test/ModuleImporterTests.kt b/compiler/test/ModuleImporterTests.kt
index fb7714c19..e9e6098b3 100644
--- a/compiler/test/ModuleImporterTests.kt
+++ b/compiler/test/ModuleImporterTests.kt
@@ -17,6 +17,7 @@ import prog8tests.ast.helpers.*
import prog8tests.helpers.ErrorReporterForTests
import prog8tests.helpers.DummyFunctions
import prog8tests.helpers.DummyMemsizer
+import prog8tests.helpers.DummyStringEncoder
import kotlin.io.path.*
import kotlin.test.assertContains
import kotlin.test.assertFailsWith
@@ -31,7 +32,7 @@ class TestModuleImporter {
private lateinit var program: Program
@BeforeEach
fun beforeEach() {
- program = Program("foo", DummyFunctions, DummyMemsizer)
+ program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
}
private fun makeImporter(errors: IErrorReporter?, vararg searchIn: String): ModuleImporter {
diff --git a/compiler/test/TestMemory.kt b/compiler/test/TestMemory.kt
index c75d8c4b9..ac21d098f 100644
--- a/compiler/test/TestMemory.kt
+++ b/compiler/test/TestMemory.kt
@@ -17,6 +17,7 @@ import prog8.compilerinterface.isInRegularRAMof
import prog8.parser.SourceCode
import prog8tests.helpers.DummyFunctions
import prog8tests.helpers.DummyMemsizer
+import prog8tests.helpers.DummyStringEncoder
import kotlin.test.assertFalse
import kotlin.test.assertTrue
@@ -70,7 +71,7 @@ class TestMemory {
@Test
fun testInValidRamC64_memory_identifiers() {
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
var target = createTestProgramForMemoryRefViaVar(program, 0x1000, VarDeclType.VAR)
assertTrue(target.isInRegularRAMof(C64Target.machine))
@@ -109,7 +110,7 @@ class TestMemory {
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test"))
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
module.linkIntoProgram(program)
assertTrue(target.isInRegularRAMof(C64Target.machine))
@@ -123,7 +124,7 @@ class TestMemory {
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test"))
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
module.linkIntoProgram(program)
assertTrue(target.isInRegularRAMof(C64Target.machine))
@@ -137,7 +138,7 @@ class TestMemory {
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test"))
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
module.linkIntoProgram(program)
assertFalse(target.isInRegularRAMof(C64Target.machine))
@@ -151,7 +152,7 @@ class TestMemory {
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test"))
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
module.linkIntoProgram(program)
assertTrue(target.isInRegularRAMof(C64Target.machine))
@@ -166,7 +167,7 @@ class TestMemory {
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test"))
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
module.linkIntoProgram(program)
assertTrue(target.isInRegularRAMof(C64Target.machine))
@@ -181,7 +182,7 @@ class TestMemory {
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test"))
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
module.linkIntoProgram(program)
assertFalse(target.isInRegularRAMof(C64Target.machine))
diff --git a/compiler/test/helpers/Dummies.kt b/compiler/test/helpers/Dummies.kt
index c0209f950..9a8128584 100644
--- a/compiler/test/helpers/Dummies.kt
+++ b/compiler/test/helpers/Dummies.kt
@@ -7,6 +7,7 @@ import prog8.ast.expressions.Expression
import prog8.ast.expressions.InferredTypes
import prog8.ast.expressions.NumericLiteralValue
import prog8.compilerinterface.IMemSizer
+import prog8.compilerinterface.IStringEncoding
internal val DummyFunctions = object : IBuiltinFunctions {
override val names: Set = emptySet()
@@ -23,3 +24,13 @@ internal val DummyFunctions = object : IBuiltinFunctions {
internal val DummyMemsizer = object : IMemSizer {
override fun memorySize(dt: DataType): Int = 0
}
+
+internal val DummyStringEncoder = object : IStringEncoding {
+ override fun encodeString(str: String, altEncoding: Boolean): List {
+ return emptyList()
+ }
+
+ override fun decodeString(bytes: List, altEncoding: Boolean): String {
+ return ""
+ }
+}
diff --git a/compilerAst/src/prog8/ast/AstToplevel.kt b/compilerAst/src/prog8/ast/AstToplevel.kt
index 91d97cab7..9f34ad87b 100644
--- a/compilerAst/src/prog8/ast/AstToplevel.kt
+++ b/compilerAst/src/prog8/ast/AstToplevel.kt
@@ -8,6 +8,7 @@ import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstVisitor
import prog8.compilerinterface.IMemSizer
+import prog8.compilerinterface.IStringEncoding
import prog8.parser.SourceCode
const val internedStringsModuleName = "prog8_interned_strings"
@@ -287,7 +288,8 @@ interface Node {
class Program(val name: String,
val builtinFunctions: IBuiltinFunctions,
- val memsizer: IMemSizer
+ val memsizer: IMemSizer,
+ val encoding: IStringEncoding
): Node {
private val _modules = mutableListOf()
diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt
index 5a47e0665..827599fcf 100644
--- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt
+++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt
@@ -514,7 +514,10 @@ class CharLiteral(val value: Char,
}
override fun referencesIdentifier(vararg scopedName: String) = false
- override fun constValue(program: Program): NumericLiteralValue? = null // TODO: CharLiteral.constValue can't be NumericLiteralValue... unless we re-add string encoder to program?
+ override fun constValue(program: Program): NumericLiteralValue {
+ val bytevalue = program.encoding.encodeString(value.toString(), altEncoding).single()
+ return NumericLiteralValue(DataType.UBYTE, bytevalue, position)
+ }
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
diff --git a/compilerInterfaces/src/prog8/compilerinterface/IStringEncoding.kt b/compilerAst/src/prog8/compilerinterface/IStringEncoding.kt
similarity index 100%
rename from compilerInterfaces/src/prog8/compilerinterface/IStringEncoding.kt
rename to compilerAst/src/prog8/compilerinterface/IStringEncoding.kt
diff --git a/compilerAst/test/TestAstToSourceText.kt b/compilerAst/test/TestAstToSourceText.kt
index 20ccc0f40..b322e0b1a 100644
--- a/compilerAst/test/TestAstToSourceText.kt
+++ b/compilerAst/test/TestAstToSourceText.kt
@@ -11,6 +11,7 @@ import prog8.parser.Prog8Parser.parseModule
import prog8.parser.SourceCode
import prog8tests.ast.helpers.DummyFunctions
import prog8tests.ast.helpers.DummyMemsizer
+import prog8tests.ast.helpers.DummyStringEncoder
import kotlin.test.assertContains
@@ -18,7 +19,7 @@ import kotlin.test.assertContains
class TestAstToSourceText {
private fun generateP8(module: Module) : String {
- val program = Program("test", DummyFunctions, DummyMemsizer)
+ val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder)
.addModule(module)
var generatedText = ""
diff --git a/compilerAst/test/TestProg8Parser.kt b/compilerAst/test/TestProg8Parser.kt
index 4c442f263..73f87a1d9 100644
--- a/compilerAst/test/TestProg8Parser.kt
+++ b/compilerAst/test/TestProg8Parser.kt
@@ -6,6 +6,7 @@ import org.junit.jupiter.api.TestInstance
import prog8.ast.IFunctionCall
import prog8.ast.Module
import prog8.ast.Node
+import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.Position
import prog8.ast.expressions.CharLiteral
@@ -16,9 +17,9 @@ import prog8.ast.statements.*
import prog8.parser.ParseError
import prog8.parser.Prog8Parser.parseModule
import prog8.parser.SourceCode
-import prog8tests.ast.helpers.assumeNotExists
-import prog8tests.ast.helpers.assumeReadableFile
-import prog8tests.ast.helpers.fixturesDir
+import prog8tests.ast.helpers.*
+import prog8tests.ast.helpers.DummyFunctions
+import prog8tests.ast.helpers.DummyMemsizer
import kotlin.io.path.Path
import kotlin.io.path.isRegularFile
import kotlin.io.path.name
@@ -582,6 +583,16 @@ class TestProg8Parser {
}
}
+ @Test
+ fun testCharLiteralConstValue() {
+ val char1 = CharLiteral('A', false, Position.DUMMY)
+ val char2 = CharLiteral('z', true, Position.DUMMY)
+
+ val program = Program("test", DummyFunctions, DummyMemsizer, AsciiStringEncoder)
+ assertEquals(65, char1.constValue(program).number.toInt())
+ assertEquals(122, char2.constValue(program).number.toInt())
+ }
+
@Test
fun testLiteralValueComparisons() {
val ten = NumericLiteralValue(DataType.UWORD, 10, Position.DUMMY)
diff --git a/compilerAst/test/ast/ProgramTests.kt b/compilerAst/test/ast/ProgramTests.kt
index 6694ab6fa..27896f26e 100644
--- a/compilerAst/test/ast/ProgramTests.kt
+++ b/compilerAst/test/ast/ProgramTests.kt
@@ -1,6 +1,5 @@
package prog8tests.ast.ast
-
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.containsString
import org.hamcrest.Matchers.equalTo
@@ -14,6 +13,7 @@ import prog8.ast.internedStringsModuleName
import prog8.parser.SourceCode
import prog8tests.ast.helpers.DummyFunctions
import prog8tests.ast.helpers.DummyMemsizer
+import prog8tests.ast.helpers.DummyStringEncoder
import kotlin.test.assertContains
import kotlin.test.assertFailsWith
import kotlin.test.assertSame
@@ -26,7 +26,7 @@ class ProgramTests {
inner class Constructor {
@Test
fun withNameBuiltinsAndMemsizer() {
- val program = Program("foo", DummyFunctions, DummyMemsizer)
+ val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
assertThat(program.modules.size, equalTo(1))
assertThat(program.modules[0].name, equalTo(internedStringsModuleName))
assertSame(program, program.modules[0].program)
@@ -39,7 +39,7 @@ class ProgramTests {
inner class AddModule {
@Test
fun withEmptyModule() {
- val program = Program("foo", DummyFunctions, DummyMemsizer)
+ val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
val m1 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar"))
val retVal = program.addModule(m1)
@@ -63,7 +63,7 @@ class ProgramTests {
inner class MoveModuleToFront {
@Test
fun withInternedStringsModule() {
- val program = Program("foo", DummyFunctions, DummyMemsizer)
+ val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
val m = program.modules[0]
assertThat(m.name, equalTo(internedStringsModuleName))
@@ -73,14 +73,14 @@ class ProgramTests {
}
@Test
fun withForeignModule() {
- val program = Program("foo", DummyFunctions, DummyMemsizer)
+ val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
val m = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar"))
assertFailsWith { program.moveModuleToFront(m) }
}
@Test
fun withFirstOfPreviouslyAddedModules() {
- val program = Program("foo", DummyFunctions, DummyMemsizer)
+ val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
val m1 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar"))
val m2 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("qmbl"))
program.addModule(m1)
@@ -92,7 +92,7 @@ class ProgramTests {
}
@Test
fun withSecondOfPreviouslyAddedModules() {
- val program = Program("foo", DummyFunctions, DummyMemsizer)
+ val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
val m1 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("bar"))
val m2 = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated("qmbl"))
program.addModule(m1)
@@ -108,7 +108,7 @@ class ProgramTests {
inner class Properties {
@Test
fun modules() {
- val program = Program("foo", DummyFunctions, DummyMemsizer)
+ val program = Program("foo", DummyFunctions, DummyMemsizer, DummyStringEncoder)
val ms1 = program.modules
val ms2 = program.modules
diff --git a/compilerAst/test/helpers/Dummies.kt b/compilerAst/test/helpers/Dummies.kt
index b0e2148f5..fa59a2d51 100644
--- a/compilerAst/test/helpers/Dummies.kt
+++ b/compilerAst/test/helpers/Dummies.kt
@@ -7,6 +7,7 @@ import prog8.ast.expressions.Expression
import prog8.ast.expressions.InferredTypes
import prog8.ast.expressions.NumericLiteralValue
import prog8.compilerinterface.IMemSizer
+import prog8.compilerinterface.IStringEncoding
internal val DummyFunctions = object : IBuiltinFunctions {
override val names: Set = emptySet()
@@ -23,3 +24,21 @@ internal val DummyFunctions = object : IBuiltinFunctions {
internal val DummyMemsizer = object : IMemSizer {
override fun memorySize(dt: DataType): Int = 0
}
+
+internal val DummyStringEncoder = object : IStringEncoding {
+ override fun encodeString(str: String, altEncoding: Boolean): List {
+ return emptyList()
+ }
+
+ override fun decodeString(bytes: List, altEncoding: Boolean): String {
+ return ""
+ }
+}
+
+internal val AsciiStringEncoder = object : IStringEncoding {
+ override fun encodeString(str: String, altEncoding: Boolean): List = str.map { it.code.toShort() }
+
+ override fun decodeString(bytes: List, altEncoding: Boolean): String {
+ return bytes.joinToString()
+ }
+}
diff --git a/compilerInterfaces/compilerInterfaces.iml b/compilerInterfaces/compilerInterfaces.iml
index 2c25b13e2..31645176c 100644
--- a/compilerInterfaces/compilerInterfaces.iml
+++ b/compilerInterfaces/compilerInterfaces.iml
@@ -5,6 +5,7 @@
+