diff --git a/compiler/src/prog8/astvm/AstVm.kt b/compiler/src/prog8/astvm/AstVm.kt index 081b0cf6f..45954d41d 100644 --- a/compiler/src/prog8/astvm/AstVm.kt +++ b/compiler/src/prog8/astvm/AstVm.kt @@ -274,7 +274,7 @@ class AstVm(val program: Program) { is BuiltinFunctionStatementPlaceholder -> { if(target.name=="swap") { // swap cannot be implemented as a function, so inline it here - executeSwap(sub, stmt) + executeSwap(stmt) } else { val args = evaluate(stmt.arglist) functions.performBuiltinFunction(target.name, args, statusflags) @@ -401,46 +401,15 @@ class AstVm(val program: Program) { } } - private fun executeSwap(sub: INameScope, swap: FunctionCallStatement) { - // TODO: can swap many different parameters.... in all combinations... + private fun executeSwap(swap: FunctionCallStatement) { val v1 = swap.arglist[0] val v2 = swap.arglist[1] - if(v1 is IdentifierReference && v2 is IdentifierReference) { - val decl1 = v1.targetVarDecl(program.namespace)!! - val decl2 = v2.targetVarDecl(program.namespace)!! - runtimeVariables.swap(decl1, decl2) - return - } - else if (v1 is RegisterExpr && v2 is RegisterExpr) { - runtimeVariables.swap(program.namespace, v1.register.name, program.namespace, v2.register.name) - return - } - else if(v1 is ArrayIndexedExpression && v2 is ArrayIndexedExpression) { - val decl1 = v1.identifier.targetVarDecl(program.namespace)!! - val decl2 = v2.identifier.targetVarDecl(program.namespace)!! - val index1 = evaluate(v1.arrayspec.index, evalCtx) - val index2 = evaluate(v2.arrayspec.index, evalCtx) - val rvar1 = runtimeVariables.get(decl1.definingScope(), decl1.name) - val rvar2 = runtimeVariables.get(decl2.definingScope(), decl2.name) - val val1 = rvar1.array!![index1.integerValue()] - val val2 = rvar2.array!![index2.integerValue()] - val rval1 = RuntimeValue(ArrayElementTypes.getValue(rvar1.type), val1) - val rval2 = RuntimeValue(ArrayElementTypes.getValue(rvar2.type), val2) - performAssignment(AssignTarget(null, null, v1, null, v1.position), rval2, swap, evalCtx) - performAssignment(AssignTarget(null, null, v2, null, v2.position), rval1, swap, evalCtx) - return - } - else if(v1 is DirectMemoryRead && v2 is DirectMemoryRead) { - val address1 = evaluate(v1.addressExpression, evalCtx).wordval!! - val address2 = evaluate(v2.addressExpression, evalCtx).wordval!! - val value1 = evalCtx.mem.getUByte(address1) - val value2 = evalCtx.mem.getUByte(address2) - evalCtx.mem.setUByte(address1, value2) - evalCtx.mem.setUByte(address2, value1) - return - } - - TODO("not implemented swap $v1 $v2") + val value1 = evaluate(v1, evalCtx) + val value2 = evaluate(v2, evalCtx) + val target1 = AssignTarget.fromExpr(v1) + val target2 = AssignTarget.fromExpr(v2) + performAssignment(target1, value2, swap, evalCtx) + performAssignment(target2, value1, swap, evalCtx) } fun performAssignment(target: AssignTarget, value: RuntimeValue, contextStmt: IStatement, evalCtx: EvalContext) { diff --git a/examples/test.p8 b/examples/test.p8 index 2a9246e62..b20eac033 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -6,18 +6,85 @@ ~ main { sub start() { - ubyte[10] arr1 = [1,2,3,4,5,6,7,8,9,10] - ubyte[] arr2 = [1,2,3,4,5,6,7,8,9,10] - ubyte[] arr1h = 1 to 10 - ubyte[10] arr2h = 1 to 10 + word w1 = 1111 + word w2 = 2222 + ubyte b1 = 11 + ubyte b2 = 22 + ubyte[] arr1 = [1,2,3,4] + ubyte[] arr2 = [1,2,3,4] + A=99 + Y=88 + c64scr.print_w(w1) + c64.CHROUT(',') + c64scr.print_w(w2) + c64.CHROUT('\n') + swap(w1, w2) + c64scr.print_w(w1) + c64.CHROUT(',') + c64scr.print_w(w2) + c64.CHROUT('\n') + + c64scr.print_ub(A) + c64.CHROUT(',') + c64scr.print_ub(Y) + c64.CHROUT('\n') + swap(A, Y) + c64scr.print_ub(A) + c64.CHROUT(',') + c64scr.print_ub(Y) + c64.CHROUT('\n') + + c64scr.print_ub(arr1[2]) + c64.CHROUT(',') + c64scr.print_ub(arr2[3]) + c64.CHROUT('\n') + swap(arr1[2], arr2[3]) + c64scr.print_ub(arr1[2]) + c64.CHROUT(',') + c64scr.print_ub(arr2[3]) + c64.CHROUT('\n') + + c64scr.print_ub(A) + c64.CHROUT(',') + c64scr.print_ub(b1) + c64.CHROUT('\n') + swap(A, b1) + c64scr.print_ub(A) + c64.CHROUT(',') + c64scr.print_ub(b1) + c64.CHROUT('\n') + + c64scr.print_ub(b2) + c64.CHROUT(',') + c64scr.print_ub(Y) + c64.CHROUT('\n') + swap(b2, Y) + c64scr.print_ub(b2) + c64.CHROUT(',') + c64scr.print_ub(Y) + c64.CHROUT('\n') + + c64scr.print_ub(arr1[2]) + c64.CHROUT(',') + c64scr.print_ub(Y) + c64.CHROUT('\n') + swap(arr1[2], Y) + c64scr.print_ub(arr1[2]) + c64.CHROUT(',') + c64scr.print_ub(Y) + c64.CHROUT('\n') + + c64scr.print_ub(Y) + c64.CHROUT(',') + c64scr.print_ub(arr2[3]) + c64.CHROUT('\n') + swap(Y, arr2[3]) + c64scr.print_ub(Y) + c64.CHROUT(',') + c64scr.print_ub(arr2[3]) + c64.CHROUT('\n') -; swap(w1, w2) -; swap(A, Y) -; swap(arr1[4], arr2[9]) -; ; TODO swap(arr1[4], Y) -; ; TODO swap(Y, arr2[9]) -; swap(@($d020), @($d021)) } }