* 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
import prog8.ast.AstToSourceCode
import prog8.ast.IBuiltinFunctions
import prog8.ast.IMemSizer
import prog8.ast.Program
import prog8.ast.*
import prog8.ast.base.AstException
import prog8.ast.base.Position
import prog8.ast.expressions.Expression
@ -268,6 +265,9 @@ private fun processAst(programAst: Program, errors: IErrorReporter, compilerOpti
println("Processing for target ${compilerOptions.compTarget.name}...")
programAst.checkIdentifiers(errors, compilerOptions)
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)
errors.report()
programAst.reorderStatements(errors)

View File

@ -1,8 +1,15 @@
package prog8.compiler.astprocessing
import prog8.ast.IStringEncoding
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.CharLiteral
import prog8.ast.expressions.NumericLiteralValue
import prog8.ast.statements.Directive
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.compiler.BeforeAsmGenerationAstChanger
import prog8.compiler.CompilationOptions
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) {
val caster = TypecastsAdder(this, errors)
caster.visit(this)

View File

@ -40,7 +40,7 @@ class TestCompilerOnCharLit {
"char literal should have been replaced by ubyte literal")
val arg = funCall.args[0] as NumericLiteralValue
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
@ -67,7 +67,7 @@ class TestCompilerOnCharLit {
"char literal should have been replaced by ubyte literal")
val initializerValue = decl.value as NumericLiteralValue
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
@ -87,12 +87,12 @@ class TestCompilerOnCharLit {
assertEquals(DataType.UBYTE, decl.datatype)
assertEquals(
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 -> {
assertEquals(
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
}