mirror of
https://github.com/irmen/prog8.git
synced 2025-02-09 07:31:34 +00:00
fix defer interfering with return value, fix prefix expression error when operand is functioncall that doesn't return a value.
This commit is contained in:
parent
272a1001a8
commit
fcdd9414d9
@ -1054,6 +1054,14 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(expr: PrefixExpression) {
|
||||
|
||||
if(expr.expression is IFunctionCall) {
|
||||
val targetStatement = (expr.expression as IFunctionCall).target.targetSubroutine(program)
|
||||
if(targetStatement?.returntypes?.isEmpty()==true) {
|
||||
errors.err("subroutine doesn't return a value", expr.expression.position)
|
||||
}
|
||||
}
|
||||
|
||||
checkLongType(expr)
|
||||
val dt = expr.expression.inferType(program).getOr(DataType.UNDEFINED)
|
||||
if(dt==DataType.UNDEFINED)
|
||||
|
@ -71,21 +71,45 @@ private fun integrateDefers(program: PtProgram, st: SymbolTable) {
|
||||
node.parent.add(idx, invokedefer)
|
||||
}
|
||||
}
|
||||
fun notComplex(value: PtExpression): Boolean = when(value) {
|
||||
is PtAddressOf -> value.arrayIndexExpr == null || notComplex(value.arrayIndexExpr!!)
|
||||
is PtBuiltinFunctionCall -> {
|
||||
when (value.name) {
|
||||
in arrayOf("msb", "lsb", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> value.args.all { notComplex(it) }
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
is PtMemoryByte -> value.address is PtNumber
|
||||
is PtPrefix -> notComplex(value.value)
|
||||
is PtTypeCast -> notComplex(value.value)
|
||||
is PtArray,
|
||||
is PtIrRegister,
|
||||
is PtBool,
|
||||
is PtNumber,
|
||||
is PtRange,
|
||||
is PtString -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
// jump exits
|
||||
for(exit in jumpsToAugment) {
|
||||
invokedeferbefore(exit)
|
||||
}
|
||||
|
||||
// return exits
|
||||
for(ret in returnsToAugment) {
|
||||
val defer = ret.definingSub()!!.children.singleOrNull { it is PtDefer }
|
||||
if(defer == null)
|
||||
continue
|
||||
if(ret.children.size>1)
|
||||
TODO("support defer on multi return values")
|
||||
if(!ret.hasValue || ret.value!!.isSimple()) {
|
||||
val value = ret.value
|
||||
if(value==null || notComplex(value)) {
|
||||
invokedeferbefore(ret)
|
||||
} else {
|
||||
val value = ret.value!!
|
||||
continue
|
||||
}
|
||||
|
||||
// complex return value, need to store it before calling the defer block
|
||||
var typecast: DataType? = null
|
||||
var pushWord = false
|
||||
var pushFloat = false
|
||||
@ -124,8 +148,8 @@ private fun integrateDefers(program: PtProgram, st: SymbolTable) {
|
||||
val idx = ret.parent.children.indexOf(ret)
|
||||
ret.parent.children[idx] = group
|
||||
}
|
||||
}
|
||||
|
||||
// subroutine ends
|
||||
for(sub in subEndsToAugment) {
|
||||
val defer = sub.children.singleOrNull { it is PtDefer }
|
||||
if(defer != null) {
|
||||
@ -138,3 +162,4 @@ private fun integrateDefers(program: PtProgram, st: SymbolTable) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -31,18 +31,19 @@ main {
|
||||
}
|
||||
|
||||
sub testdefer() -> ubyte {
|
||||
ubyte var = 22
|
||||
ubyte @shared var = 22
|
||||
|
||||
defer txt.print("defer1\n")
|
||||
defer {
|
||||
txt.print("defer2, var=")
|
||||
txt.print_ub(var)
|
||||
txt.nl()
|
||||
var=33
|
||||
}
|
||||
|
||||
if var==22 {
|
||||
var = 88
|
||||
return var + other()
|
||||
return var ; + other()
|
||||
}
|
||||
else {
|
||||
var++
|
||||
|
Loading…
x
Reference in New Issue
Block a user