mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
fixed missing type checking in vardecl initializer values. Fixes #29
Also fix wrong assert of 0 const check in assembly gen for if-statement comparisons.
This commit is contained in:
parent
3d956ef554
commit
c70bbdab26
@ -194,7 +194,9 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I
|
||||
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
|
||||
}
|
||||
|
||||
if((binExpr.left as? NumericLiteralValue)?.number==0)
|
||||
if((binExpr.operator=="==" || binExpr.operator=="!=") &&
|
||||
(binExpr.left as? NumericLiteralValue)?.number==0 &&
|
||||
(binExpr.right as? NumericLiteralValue)?.number!=0)
|
||||
throw CompilerException("if 0==X should have been swapped to if X==0")
|
||||
|
||||
// split the conditional expression into separate variables if the operand(s) is not simple.
|
||||
|
@ -409,7 +409,7 @@ internal class AstChecker(private val program: Program,
|
||||
if(targetDt.typeOrElse(DataType.STRUCT) in IterableDatatypes)
|
||||
errors.err("cannot assign value to string or array", assignment.value.position)
|
||||
else if(!(valueDt.istype(DataType.STR) && targetDt.istype(DataType.UWORD)))
|
||||
errors.err("value's type doesn't match target", assignment.value.position)
|
||||
errors.err("type of value doesn't match target", assignment.value.position)
|
||||
}
|
||||
|
||||
if(assignment.value is TypecastExpression) {
|
||||
@ -562,7 +562,7 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
val memberDt = memberdecl.datatype
|
||||
if(!checkValueTypeAndRange(memberDt, constValue)) {
|
||||
errors.err("struct member value's type is not compatible with member field '${memberdecl.name}'", value.first.position)
|
||||
errors.err("type of struct member value is not compatible with member field '${memberdecl.name}'", value.first.position)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,13 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
|
||||
}
|
||||
|
||||
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
||||
|
||||
// ConstValue <associativeoperator> X --> X <associativeoperator> ConstValue
|
||||
// (this should be done by the ExpressionSimplifier when optimizing is enabled,
|
||||
// but the current assembly code generator for IF statements now also depends on it so we do it here regardless of optimization.)
|
||||
if (expr.left.constValue(program) != null && expr.operator in associativeOperators && expr.right.constValue(program) == null)
|
||||
return listOf(IAstModification.SwapOperands(expr))
|
||||
|
||||
// when using a simple bit shift and assigning it to a variable of a different type,
|
||||
// try to make the bit shifting 'wide enough' to fall into the variable's type.
|
||||
// with this, for instance, uword x = 1 << 10 will result in 1024 rather than 0 (the ubyte result).
|
||||
|
@ -28,6 +28,10 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk
|
||||
if(valueDt.typeOrElse(DataType.STRUCT) in IntegerDatatypes && decl.datatype in ArrayDatatypes)
|
||||
return noModifications
|
||||
|
||||
// don't add a typecast if the initializer value is inherently not assignable
|
||||
if(valueDt isNotAssignableTo decl.datatype)
|
||||
return noModifications
|
||||
|
||||
return listOf(IAstModification.ReplaceNode(
|
||||
declValue,
|
||||
TypecastExpression(declValue, decl.datatype, true, declValue.position),
|
||||
|
@ -4,20 +4,11 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
str anim = "1234"
|
||||
ubyte anim_counter = 0
|
||||
|
||||
test_stack.test()
|
||||
|
||||
txt.print("loading ")
|
||||
repeat 100 {
|
||||
ubyte qq = anim[anim_counter/2]
|
||||
txt.chrout(qq)
|
||||
anim_counter = (anim_counter+1) & 7
|
||||
ubyte xx=99
|
||||
if 0==xx {
|
||||
txt.print("fout")
|
||||
}
|
||||
txt.print("done!\n")
|
||||
|
||||
test_stack.test()
|
||||
txt.print("loading ")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user