fix type of optimized lsb() / mkword() arguments when signed.

printast1 command line option now also works in case of compilation errors.
This commit is contained in:
Irmen de Jong 2024-01-10 23:57:44 +01:00
parent e8da62aa29
commit 45a9751217
3 changed files with 55 additions and 3 deletions

View File

@ -427,10 +427,15 @@ class ExpressionSimplifier(private val program: Program,
val arg = functionCallExpr.args[0]
if(arg is TypecastExpression) {
val valueDt = arg.expression.inferType(program)
if (valueDt istype DataType.BYTE || valueDt istype DataType.UBYTE) {
// useless lsb() of byte value that was typecasted to word
if (valueDt istype DataType.UBYTE) {
// useless lsb() of ubyte value
return listOf(IAstModification.ReplaceNode(functionCallExpr, arg.expression, parent))
}
else if (valueDt istype DataType.BYTE) {
// useless lsb() of byte value, but as lsb() returns unsigned, we have to cast now.
val cast = TypecastExpression(arg.expression, DataType.UBYTE, true, arg.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, cast, parent))
}
} else {
if(arg is IdentifierReference && arg.nameInSource.size==2
&& arg.nameInSource[0]=="cx16" && arg.nameInSource[1].uppercase() in RegisterOrPair.names) {
@ -439,10 +444,15 @@ class ExpressionSimplifier(private val program: Program,
return listOf(IAstModification.ReplaceNode(functionCallExpr, highReg, parent))
}
val argDt = arg.inferType(program)
if (argDt istype DataType.BYTE || argDt istype DataType.UBYTE) {
if (argDt istype DataType.UBYTE) {
// useless lsb() of byte value
return listOf(IAstModification.ReplaceNode(functionCallExpr, arg, parent))
}
else if (argDt istype DataType.BYTE) {
// useless lsb() of byte value, but as lsb() returns unsigned, we have to cast now.
val cast = TypecastExpression(arg, DataType.UBYTE, true, arg.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, cast, parent))
}
}
}
else if(functionCallExpr.target.nameInSource == listOf("msb")) {

View File

@ -164,20 +164,38 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
println("\nTotal compilation+assemble time: ${round(seconds*100.0)/100.0} sec.")
return CompilationResult(program, ast, compilationOptions, importedFiles)
} catch (px: ParseError) {
System.out.flush()
System.err.print("\n\u001b[91m") // bright red
System.err.println("${px.position.toClickableStr()} parse error: ${px.message}".trim())
System.err.print("\u001b[0m") // reset
} catch (ac: ErrorsReportedException) {
if(args.printAst1) {
println("\n*********** COMPILER AST *************")
printProgram(program)
println("*********** COMPILER AST END *************\n")
}
if (args.printAst2) {
if(ast==null)
println("There is no intermediate AST available because of compilation errors.")
else {
println("\n*********** INTERMEDIATE AST *************")
printAst(ast!!, true, ::println)
println("*********** INTERMEDIATE AST END *************\n")
}
}
if(!ac.message.isNullOrEmpty()) {
System.out.flush()
System.err.print("\n\u001b[91m") // bright red
System.err.println(ac.message)
System.err.print("\u001b[0m") // reset
}
} catch (nsf: NoSuchFileException) {
System.out.flush()
System.err.print("\n\u001b[91m") // bright red
System.err.println("File not found: ${nsf.message}")
System.err.print("\u001b[0m") // reset
} catch (ax: AstException) {
System.out.flush()
System.err.print("\n\u001b[91m") // bright red
System.err.println(ax.toString())
System.err.print("\u001b[0m") // reset

View File

@ -504,5 +504,29 @@ main {
val expr3 = BinaryExpression(left3, "+", right3, Position.DUMMY)
(expr1 isSameAs expr3) shouldBe true
}
test("mkword insertion with signed values gets correct type cast") {
val src = """
main {
sub start() {
byte[10] @shared bottom
byte @shared col = 20
col++
ubyte @shared ubb = lsb(col as uword)
uword @shared vaddr = bottom[col] as uword << 8 ; a mkword will get inserted here
}
}"""
val result = compileText(VMTarget(), optimize=true, src, writeAssembly=false)!!
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 8
val assignUbb = ((st[5] as Assignment).value as TypecastExpression)
assignUbb.type shouldBe DataType.UBYTE
assignUbb.expression shouldBe instanceOf<IdentifierReference>()
val assignVaddr = (st[7] as Assignment).value as FunctionCallExpression
assignVaddr.target.nameInSource shouldBe listOf("mkword")
val tc = assignVaddr.args[0] as TypecastExpression
tc.type shouldBe DataType.UBYTE
tc.expression shouldBe instanceOf<ArrayIndexedExpression>()
}
})