mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
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:
parent
e8da62aa29
commit
45a9751217
@ -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")) {
|
||||
|
@ -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
|
||||
|
@ -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>()
|
||||
}
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user