mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +00:00
tweaking multiple assignment targets
This commit is contained in:
parent
23c1167d7f
commit
a2a8a772ec
@ -9,10 +9,18 @@ sub start() {
|
|||||||
|
|
||||||
ubyte v1
|
ubyte v1
|
||||||
ubyte v2
|
ubyte v2
|
||||||
|
float f2
|
||||||
|
uword address
|
||||||
|
|
||||||
|
|
||||||
v1=foo()
|
v1=foo()
|
||||||
v1 , v2 =c64.GETADR()
|
X, Y =c64.GETADR()
|
||||||
|
v1, v2 =c64.GETADR()
|
||||||
|
address =c64.MEMBOT(1, 0.w)
|
||||||
|
address =c64.IOBASE()
|
||||||
|
A = c64.CHRIN()
|
||||||
|
X = c64.CHRIN()
|
||||||
|
v1 = c64.CHRIN()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -709,6 +709,16 @@ data class AssignTarget(val register: Register?,
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun shortString(): String {
|
||||||
|
if(register!=null)
|
||||||
|
return register.toString()
|
||||||
|
if(identifier!=null)
|
||||||
|
return identifier.nameInSource.last()
|
||||||
|
if(arrayindexed!=null)
|
||||||
|
return arrayindexed.identifier!!.nameInSource.last()
|
||||||
|
return "???"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,7 +371,17 @@ class AstChecker(private val namespace: INameScope,
|
|||||||
// a functioncall COULD return multiple values (from an asm subroutine), treat that differently
|
// a functioncall COULD return multiple values (from an asm subroutine), treat that differently
|
||||||
val stmt = (assignment.value as FunctionCall).target.targetStatement(namespace)
|
val stmt = (assignment.value as FunctionCall).target.targetStatement(namespace)
|
||||||
if(stmt is Subroutine && stmt.returntypes.size>1) {
|
if(stmt is Subroutine && stmt.returntypes.size>1) {
|
||||||
checkResult.add(ExpressionError("subroutine returning multiple values", assignment.value.position)) // TODO check this
|
if(stmt.isAsmSubroutine) {
|
||||||
|
if(stmt.returntypes.size != assignment.targets.size)
|
||||||
|
checkResult.add(ExpressionError("number of return values doesn't match number of assignment targets", assignment.value.position))
|
||||||
|
else {
|
||||||
|
for(thing in stmt.returntypes.zip(assignment.targets)) {
|
||||||
|
if(thing.second.determineDatatype(namespace, heap, assignment)!=thing.first)
|
||||||
|
checkResult.add(ExpressionError("return type mismatch for target ${thing.second.shortString()}", assignment.value.position))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
checkResult.add(ExpressionError("only asmsub subroutines can return multiple values", assignment.value.position))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
checkResult.add(ExpressionError("function call doesn't return a suitable value to use in assignment", assignment.value.position))
|
checkResult.add(ExpressionError("function call doesn't return a suitable value to use in assignment", assignment.value.position))
|
||||||
|
@ -1089,7 +1089,46 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(stmt: Assignment) {
|
private fun translate(stmt: Assignment) {
|
||||||
val assignTarget= stmt.singleTarget ?: throw CompilerException("cannot use assignment to multiple assignment targets ${stmt.position}")
|
val assignTarget= stmt.singleTarget
|
||||||
|
|
||||||
|
if(assignTarget==null) {
|
||||||
|
// we're dealing with multiple return values
|
||||||
|
val targetStmt = (stmt.value as? FunctionCall)?.target?.targetStatement(namespace)
|
||||||
|
if(targetStmt is Subroutine && targetStmt.isAsmSubroutine) {
|
||||||
|
// we're dealing with the one case where multiple assignment targets are allowed: a call to an asmsub with multiple return values
|
||||||
|
// for now, we only support multiple return values as long as they're returned in registers as well.
|
||||||
|
if(targetStmt.asmReturnvaluesRegisters.isEmpty())
|
||||||
|
throw CompilerException("we only support multiple return values / assignment when the asmsub returns values in registers")
|
||||||
|
// if the result registers are not assigned in the exact same registers, or in variables, we need some code
|
||||||
|
if(stmt.targets.all{it.register!=null}) {
|
||||||
|
val resultRegisters = mutableListOf<Register>()
|
||||||
|
for(x in targetStmt.asmReturnvaluesRegisters) {
|
||||||
|
when(x.registerOrPair) {
|
||||||
|
RegisterOrPair.A -> resultRegisters.add(Register.A)
|
||||||
|
RegisterOrPair.X -> resultRegisters.add(Register.X)
|
||||||
|
RegisterOrPair.Y -> resultRegisters.add(Register.Y)
|
||||||
|
RegisterOrPair.AX -> {
|
||||||
|
resultRegisters.add(Register.A)
|
||||||
|
resultRegisters.add(Register.X)
|
||||||
|
}
|
||||||
|
RegisterOrPair.AY -> {
|
||||||
|
resultRegisters.add(Register.A)
|
||||||
|
resultRegisters.add(Register.Y)
|
||||||
|
}
|
||||||
|
RegisterOrPair.XY -> {
|
||||||
|
resultRegisters.add(Register.X)
|
||||||
|
resultRegisters.add(Register.Y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TODO("$resultRegisters")
|
||||||
|
} else {
|
||||||
|
TODO("store results from registers ${targetStmt.asmReturnvaluesRegisters}")
|
||||||
|
}
|
||||||
|
} else throw CompilerException("can only use multiple assignment targets on an asmsub call")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
prog.line(stmt.position)
|
prog.line(stmt.position)
|
||||||
translate(stmt.value)
|
translate(stmt.value)
|
||||||
val valueDt = stmt.value.resultingDatatype(namespace, heap)
|
val valueDt = stmt.value.resultingDatatype(namespace, heap)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user