* reintroduce the conversion of CharLiteral to UBYTE literals, but now *during AST preprocessing*, not in the parser

This commit is contained in:
meisl 2021-06-28 12:04:34 +02:00
parent 0567168ea9
commit 82f5a141ed
3 changed files with 29 additions and 8 deletions

View File

@ -1,9 +1,6 @@
package prog8.compiler package prog8.compiler
import prog8.ast.AstToSourceCode import prog8.ast.*
import prog8.ast.IBuiltinFunctions
import prog8.ast.IMemSizer
import prog8.ast.Program
import prog8.ast.base.AstException import prog8.ast.base.AstException
import prog8.ast.base.Position import prog8.ast.base.Position
import prog8.ast.expressions.Expression import prog8.ast.expressions.Expression
@ -268,6 +265,9 @@ private fun processAst(programAst: Program, errors: IErrorReporter, compilerOpti
println("Processing for target ${compilerOptions.compTarget.name}...") println("Processing for target ${compilerOptions.compTarget.name}...")
programAst.checkIdentifiers(errors, compilerOptions) programAst.checkIdentifiers(errors, compilerOptions)
errors.report() errors.report()
// TODO: turning char literals into UBYTEs via an encoding should really happen in code gen - but for that we'd need DataType.CHAR
programAst.charLiteralsToUByteLiterals(errors, compilerOptions.compTarget as IStringEncoding)
errors.report()
programAst.constantFold(errors, compilerOptions.compTarget) programAst.constantFold(errors, compilerOptions.compTarget)
errors.report() errors.report()
programAst.reorderStatements(errors) programAst.reorderStatements(errors)

View File

@ -1,8 +1,15 @@
package prog8.compiler.astprocessing package prog8.compiler.astprocessing
import prog8.ast.IStringEncoding
import prog8.ast.Node
import prog8.ast.Program import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.FatalAstException import prog8.ast.base.FatalAstException
import prog8.ast.expressions.CharLiteral
import prog8.ast.expressions.NumericLiteralValue
import prog8.ast.statements.Directive import prog8.ast.statements.Directive
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.compiler.BeforeAsmGenerationAstChanger import prog8.compiler.BeforeAsmGenerationAstChanger
import prog8.compiler.CompilationOptions import prog8.compiler.CompilationOptions
import prog8.compiler.IErrorReporter import prog8.compiler.IErrorReporter
@ -33,6 +40,20 @@ internal fun Program.reorderStatements(errors: IErrorReporter) {
} }
} }
internal fun Program.charLiteralsToUByteLiterals(errors: IErrorReporter, enc: IStringEncoding) {
val walker = object : AstWalker() {
override fun after(char: CharLiteral, parent: Node): Iterable<IAstModification> {
return listOf(IAstModification.ReplaceNode(
char,
NumericLiteralValue(DataType.UBYTE, enc.encodeString(char.value.toString(), char.altEncoding)[0].toInt(), char.position),
parent
))
}
}
walker.visit(this)
walker.applyModifications()
}
internal fun Program.addTypecasts(errors: IErrorReporter) { internal fun Program.addTypecasts(errors: IErrorReporter) {
val caster = TypecastsAdder(this, errors) val caster = TypecastsAdder(this, errors)
caster.visit(this) caster.visit(this)

View File

@ -40,7 +40,7 @@ class TestCompilerOnCharLit {
"char literal should have been replaced by ubyte literal") "char literal should have been replaced by ubyte literal")
val arg = funCall.args[0] as NumericLiteralValue val arg = funCall.args[0] as NumericLiteralValue
assertEquals(DataType.UBYTE, arg.type) assertEquals(DataType.UBYTE, arg.type)
assertEquals(platform.encodeString("\n", false)[0], arg.number) assertEquals(platform.encodeString("\n", false)[0], arg.number.toShort()) // TODO: short/int/UBYTE - which should it be?
} }
@Test @Test
@ -67,7 +67,7 @@ class TestCompilerOnCharLit {
"char literal should have been replaced by ubyte literal") "char literal should have been replaced by ubyte literal")
val initializerValue = decl.value as NumericLiteralValue val initializerValue = decl.value as NumericLiteralValue
assertEquals(DataType.UBYTE, initializerValue.type) assertEquals(DataType.UBYTE, initializerValue.type)
assertEquals(platform.encodeString("\n", false)[0], initializerValue.number) assertEquals(platform.encodeString("\n", false)[0], initializerValue.number.toShort()) // TODO: short/int/UBYTE - which should it be?
} }
@Test @Test
@ -87,12 +87,12 @@ class TestCompilerOnCharLit {
assertEquals(DataType.UBYTE, decl.datatype) assertEquals(DataType.UBYTE, decl.datatype)
assertEquals( assertEquals(
platform.encodeString("\n", false)[0], platform.encodeString("\n", false)[0],
(decl.value as NumericLiteralValue).number) (decl.value as NumericLiteralValue).number.toShort()) // TODO: short/int/UBYTE - which should it be?
} }
is NumericLiteralValue -> { is NumericLiteralValue -> {
assertEquals( assertEquals(
platform.encodeString("\n", false)[0], platform.encodeString("\n", false)[0],
arg.number) arg.number.toShort()) // TODO: short/int/UBYTE - which should it be?
} }
else -> assertIs<IdentifierReference>(funCall.args[0]) // make test fail else -> assertIs<IdentifierReference>(funCall.args[0]) // make test fail
} }