mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
tweaking multiple assignment targets
This commit is contained in:
parent
23c1167d7f
commit
a2a8a772ec
@ -9,10 +9,18 @@ sub start() {
|
||||
|
||||
ubyte v1
|
||||
ubyte v2
|
||||
float f2
|
||||
uword address
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -709,6 +709,16 @@ data class AssignTarget(val register: Register?,
|
||||
}
|
||||
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
|
||||
val stmt = (assignment.value as FunctionCall).target.targetStatement(namespace)
|
||||
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
|
||||
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) {
|
||||
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)
|
||||
translate(stmt.value)
|
||||
val valueDt = stmt.value.resultingDatatype(namespace, heap)
|
||||
|
Loading…
x
Reference in New Issue
Block a user