fix some compiler errors

This commit is contained in:
Irmen de Jong 2020-03-22 13:47:13 +01:00
parent 954e911eb3
commit 7232134931
4 changed files with 65 additions and 16 deletions

View File

@ -3,6 +3,8 @@ package prog8.ast.processing
import prog8.ast.*
import prog8.ast.base.DataType
import prog8.ast.base.FatalAstException
import prog8.ast.base.NumericDatatypes
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.*
import prog8.ast.statements.*
@ -19,13 +21,16 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
// - the 'start' subroutine in the 'main' block will be moved to the top immediately following the directives.
// - all other subroutines will be moved to the end of their block.
// - sorts the choices in when statement.
// - a vardecl with a non-const initializer value is split into a regular vardecl and an assignment statement.
private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option")
private val addReturns = mutableListOf<Pair<INameScope, Int>>()
private val addVardecls = mutableMapOf<INameScope, MutableList<VarDecl>>()
override fun visit(module: Module) {
addReturns.clear()
addVardecls.clear()
super.visit(module)
val (blocks, other) = module.statements.partition { it is Block }
@ -54,11 +59,17 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
module.statements.removeAll(directives)
module.statements.addAll(0, directives)
// add new statements
for(pos in addReturns) {
val returnStmt = Return(null, pos.first.position)
returnStmt.linkParents(pos.first as Node)
pos.first.statements.add(pos.second, returnStmt)
}
for((where, decls) in addVardecls) {
where.statements.addAll(0, decls)
decls.forEach { it.linkParents(where as Node) }
}
}
override fun visit(block: Block): Statement {
@ -148,6 +159,37 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
return subroutine
}
private fun addVarDecl(scope: INameScope, variable: VarDecl): VarDecl {
if(scope !in addVardecls)
addVardecls[scope] = mutableListOf()
val declList = addVardecls.getValue(scope)
val existing = declList.singleOrNull { it.name==variable.name }
return if(existing!=null) {
existing
} else {
declList.add(variable)
variable
}
}
override fun visit(decl: VarDecl): Statement {
val declValue = decl.value
if(declValue!=null && decl.type== VarDeclType.VAR && decl.datatype in NumericDatatypes) {
val declConstValue = declValue.constValue(program)
if(declConstValue==null) {
// move the vardecl (without value) to the scope and replace this with a regular assignment
val target = AssignTarget(null, IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
val assign = Assignment(target, null, declValue, decl.position)
assign.linkParents(decl.parent)
decl.value = null
addVarDecl(decl.definingScope(), decl)
return assign
}
}
return super.visit(decl)
}
override fun visit(assignment: Assignment): Statement {
val assg = super.visit(assignment)
if(assg !is Assignment)

View File

@ -4,10 +4,7 @@ import prog8.ast.IFunctionCall
import prog8.ast.INameScope
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.ErrorReporter
import prog8.ast.base.FatalAstException
import prog8.ast.base.VarDeclType
import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.functions.BuiltinFunctions
@ -22,7 +19,7 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
// collect all variables that have an initialisation value
if(decl.value!=null && decl.type== VarDeclType.VAR && !decl.isArray)
if(decl.value!=null && decl.type== VarDeclType.VAR && decl.datatype in NumericDatatypes)
decl.definingBlock().initialValues += decl
return emptyList()

View File

@ -400,17 +400,22 @@ internal class AsmGen(private val program: Program,
}
private fun makeArrayFillDataSigned(decl: VarDecl): List<String> {
val array = (decl.value as ArrayLiteralValue).value
return when {
decl.datatype == DataType.ARRAY_UB ->
val array =
if(decl.value!=null)
(decl.value as ArrayLiteralValue).value
else {
// no array init value specified, use a list of zeros
val zero = decl.asDefaultValueDecl(decl.parent).value!!
Array(decl.arraysize!!.size()!!) { zero }
}
return when (decl.datatype) {
DataType.ARRAY_UB ->
// byte array can never contain pointer-to types, so treat values as all integers
array.map {
val number = (it as NumericLiteralValue).number.toInt()
val hexnum = number.toString(16).padStart(2, '0')
"$$hexnum"
"$"+number.toString(16).padStart(2, '0')
}
decl.datatype == DataType.ARRAY_B ->
DataType.ARRAY_B ->
// byte array can never contain pointer-to types, so treat values as all integers
array.map {
val number = (it as NumericLiteralValue).number.toInt()
@ -420,12 +425,11 @@ internal class AsmGen(private val program: Program,
else
"-$$hexnum"
}
decl.datatype== DataType.ARRAY_UW -> array.map {
DataType.ARRAY_UW -> array.map {
val number = (it as NumericLiteralValue).number.toInt()
val hexnum = number.toString(16).padStart(4, '0')
"$$hexnum"
"$" + number.toString(16).padStart(4, '0')
}
decl.datatype== DataType.ARRAY_W -> array.map {
DataType.ARRAY_W -> array.map {
val number = (it as NumericLiteralValue).number.toInt()
val hexnum = number.absoluteValue.toString(16).padStart(4, '0')
if(number>=0)

View File

@ -6,6 +6,12 @@
main {
sub start() {
ubyte xyz = 99 ; TODO fix compiler error when removing unused var
word wcosa = cos8(xyz)
word wcosa_sinb = wcosa / 128
; TODO fix too much assembly in prog8_init_vars
ubyte ub1
ubyte ub2 = 99
uword uw1