mirror of
https://github.com/irmen/prog8.git
synced 2024-07-05 22:29:04 +00:00
use an AnonymousScope to contain GoSub changes instead of adding separate statements
This commit is contained in:
parent
3d23b39f4c
commit
c52aa648c0
@ -389,30 +389,23 @@ internal class StatementReorderer(val program: Program,
|
|||||||
}
|
}
|
||||||
Assignment(AssignTarget(paramIdentifier, null, null, argumentValue.position), argumentValue, argumentValue.position)
|
Assignment(AssignTarget(paramIdentifier, null, null, argumentValue.position), argumentValue, argumentValue.position)
|
||||||
}
|
}
|
||||||
return assignParams.map { IAstModification.InsertBefore(call, it, parent as IStatementContainer) } +
|
val scope = AnonymousScope(assignParams.toMutableList(), call.position)
|
||||||
IAstModification.ReplaceNode(
|
scope.statements += GoSub(null, call.target, null, call.position)
|
||||||
call,
|
return listOf(IAstModification.ReplaceNode(call, scope, parent))
|
||||||
GoSub(null, call.target, null, call.position),
|
|
||||||
parent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun replaceCallAsmSubStatementWithGosub(function: Subroutine, call: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
|
private fun replaceCallAsmSubStatementWithGosub(function: Subroutine, call: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
|
||||||
if(function.parameters.isEmpty()) {
|
if(function.parameters.isEmpty()) {
|
||||||
// 0 params -> just GoSub
|
// 0 params -> just GoSub
|
||||||
val modifications = mutableListOf<IAstModification>()
|
val scope = AnonymousScope(mutableListOf(), call.position)
|
||||||
if(function.shouldSaveX()) {
|
if(function.shouldSaveX()) {
|
||||||
modifications += IAstModification.InsertBefore(
|
scope.statements += FunctionCallStatement(IdentifierReference(listOf("sys", "rsavex"), call.position), mutableListOf(), true, call.position)
|
||||||
call,
|
|
||||||
FunctionCallStatement(IdentifierReference(listOf("sys", "rsavex"), call.position), mutableListOf(), true, call.position),
|
|
||||||
parent as IStatementContainer
|
|
||||||
)
|
|
||||||
modifications += IAstModification.InsertAfter(
|
|
||||||
call,
|
|
||||||
FunctionCallStatement(IdentifierReference(listOf("sys", "rrestorex"), call.position), mutableListOf(), true, call.position),
|
|
||||||
parent as IStatementContainer
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return modifications + IAstModification.ReplaceNode(call, GoSub(null, call.target, null, call.position), parent)
|
scope.statements += GoSub(null, call.target, null, call.position)
|
||||||
|
if(function.shouldSaveX()) {
|
||||||
|
scope.statements += FunctionCallStatement(IdentifierReference(listOf("sys", "rrestorex"), call.position), mutableListOf(), true, call.position)
|
||||||
|
}
|
||||||
|
return listOf(IAstModification.ReplaceNode(call, scope, parent))
|
||||||
} else if(!options.compTarget.asmsubArgsHaveRegisterClobberRisk(call.args)) {
|
} else if(!options.compTarget.asmsubArgsHaveRegisterClobberRisk(call.args)) {
|
||||||
// no register clobber risk, let the asmgen assign values to the registers directly.
|
// no register clobber risk, let the asmgen assign values to the registers directly.
|
||||||
// this is more efficient than first evaluating them to the stack
|
// this is more efficient than first evaluating them to the stack
|
||||||
@ -423,34 +416,26 @@ internal class StatementReorderer(val program: Program,
|
|||||||
if (options.slowCodegenWarnings)
|
if (options.slowCodegenWarnings)
|
||||||
errors.warn("slow argument passing used to avoid register clobbering", call.position)
|
errors.warn("slow argument passing used to avoid register clobbering", call.position)
|
||||||
val argOrder = options.compTarget.asmsubArgsEvalOrder(function)
|
val argOrder = options.compTarget.asmsubArgsEvalOrder(function)
|
||||||
val modifications = mutableListOf<IAstModification>()
|
val scope = AnonymousScope(mutableListOf(), call.position)
|
||||||
if(function.shouldSaveX()) {
|
if(function.shouldSaveX()) {
|
||||||
modifications += IAstModification.InsertBefore(
|
scope.statements += FunctionCallStatement(IdentifierReference(listOf("sys", "rsavex"), call.position), mutableListOf(), true, call.position)
|
||||||
call,
|
|
||||||
FunctionCallStatement(IdentifierReference(listOf("sys", "rsavex"), call.position), mutableListOf(), true, call.position),
|
|
||||||
parent as IStatementContainer
|
|
||||||
)
|
|
||||||
modifications += IAstModification.InsertAfter(
|
|
||||||
call,
|
|
||||||
FunctionCallStatement(IdentifierReference(listOf("sys", "rrestorex"), call.position), mutableListOf(), true, call.position),
|
|
||||||
parent as IStatementContainer
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
argOrder.reversed().forEach {
|
argOrder.reversed().forEach {
|
||||||
val arg = call.args[it]
|
val arg = call.args[it]
|
||||||
val param = function.parameters[it]
|
val param = function.parameters[it]
|
||||||
val push = pushCall(arg, param.type, arg.position)
|
scope.statements += pushCall(arg, param.type, arg.position)
|
||||||
modifications += IAstModification.InsertBefore(call, push, parent as IStatementContainer)
|
|
||||||
}
|
}
|
||||||
// ... and pop them off again into the registers.
|
// ... and pop them off again into the registers.
|
||||||
argOrder.forEach {
|
argOrder.forEach {
|
||||||
val param = function.parameters[it]
|
val param = function.parameters[it]
|
||||||
val targetName = function.scopedName + param.name
|
val targetName = function.scopedName + param.name
|
||||||
val pop = popCall(targetName, param.type, call.position)
|
scope.statements += popCall(targetName, param.type, call.position)
|
||||||
modifications += IAstModification.InsertBefore(call, pop, parent as IStatementContainer)
|
|
||||||
}
|
}
|
||||||
|
scope.statements += GoSub(null, call.target, null, call.position)
|
||||||
return modifications + IAstModification.ReplaceNode(call, GoSub(null, call.target, null, call.position), parent)
|
if(function.shouldSaveX()) {
|
||||||
|
scope.statements += FunctionCallStatement(IdentifierReference(listOf("sys", "rrestorex"), call.position), mutableListOf(), true, call.position)
|
||||||
|
}
|
||||||
|
return listOf(IAstModification.ReplaceNode(call, scope, parent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ Use GoSub to call subroutines (statements):
|
|||||||
- [DONE] allow separate assigns to subroutine's parameter variables / registers
|
- [DONE] allow separate assigns to subroutine's parameter variables / registers
|
||||||
- [DONE] turn a regular subroutine call into assignments to the parameters + GoSub (take code from gosub branch)
|
- [DONE] turn a regular subroutine call into assignments to the parameters + GoSub (take code from gosub branch)
|
||||||
- [DONE] also do this for asmsubs taking >0 parameters
|
- [DONE] also do this for asmsubs taking >0 parameters
|
||||||
|
|
||||||
- make that push(x+1) doesn't use stack evaluation, via a temp var?
|
- make that push(x+1) doesn't use stack evaluation, via a temp var?
|
||||||
|
|
||||||
Optimize Function calls in expressions:
|
Optimize Function calls in expressions:
|
||||||
|
Loading…
Reference in New Issue
Block a user