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:
Irmen de Jong 2024-10-18 21:22:32 +02:00
parent 272a1001a8
commit fcdd9414d9
3 changed files with 76 additions and 42 deletions

View File

@ -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)

View File

@ -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) {
}
}

View File

@ -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++