diff --git a/benchmark/binary_trees.swan b/benchmark/binary_trees.swan index 4f8e32c..0fab42b 100644 --- a/benchmark/binary_trees.swan +++ b/benchmark/binary_trees.swan @@ -22,7 +22,7 @@ var minDepth = 4 var maxDepth = 12 var stretchDepth = maxDepth + 1 -var start = System.clock +var start = clock() print("stretch tree of depth " + stretchDepth + " check: " + "" + Tree(0, stretchDepth).check) @@ -44,4 +44,4 @@ while (depth < stretchDepth) { } print( "long lived tree of depth " + maxDepth + " check: " + longLivedTree.check) -print(format("elapsed: %1", (System.clock - start))) +print(format("elapsed: %1", (clock() - start))) diff --git a/benchmark/fib.swan b/benchmark/fib.swan index 9945a8a..44ea82a 100644 --- a/benchmark/fib.swan +++ b/benchmark/fib.swan @@ -4,8 +4,8 @@ function fib (n) { } -var start = System.clock +var start = clock() for i in 1...5 { print(fib(28)) } -print(format("elapsed: %1", (System.clock - start))) +print(format("elapsed: %1", (clock() - start))) diff --git a/benchmark/for.swan b/benchmark/for.swan index 7bc27f0..7572822 100644 --- a/benchmark/for.swan +++ b/benchmark/for.swan @@ -1,10 +1,10 @@ var list = [] -var start = System.clock +var start = clock() for i in 0..2500000: list.add(i) var sum = 0 for i in list: sum += i print(sum) -print("elapsed: "+(System.clock - start)) +print("elapsed: "+(clock() - start)) diff --git a/benchmark/method_call.swan b/benchmark/method_call.swan index 2956b9a..f3192f7 100644 --- a/benchmark/method_call.swan +++ b/benchmark/method_call.swan @@ -29,7 +29,7 @@ class NthToggle is Toggle { } } -var start = System.clock +var start = clock() var n = 250000 var val = true var toggle = Toggle(val) @@ -67,4 +67,4 @@ for i in 0..n { print(ntoggle.value) -print("elapsed: " + (System.clock - start)) +print("elapsed: " + (clock() - start)) diff --git a/src/swan/parser/ParserCompiler.cpp b/src/swan/parser/ParserCompiler.cpp index c7687d3..908fc2f 100644 --- a/src/swan/parser/ParserCompiler.cpp +++ b/src/swan/parser/ParserCompiler.cpp @@ -368,7 +368,7 @@ struct SuperExpression: Expression { QToken superToken; SuperExpression (const QToken& t): superToken(t) {} const QToken& nearestToken () override { return superToken; } -void compile (QCompiler& compiler) override { compiler.writeOp(OP_LOAD_THIS); } +void compile (QCompiler& compiler) override; }; struct GenericMethodSymbolExpression: Expression { @@ -2652,6 +2652,15 @@ if (!isStatic) compiler.writeOpArg(OP_CALL_METHOD_1, compi compiler.writeOpArg(OP_STORE_STATIC_FIELD, fieldSlot); }} +void SuperExpression::compile (QCompiler& compiler) { +auto cls = compiler.getCurClass(); +if (!cls) compiler.compileError(superToken, "Can't use 'super' outside of a class"); +else if (cls->parents.empty()) compiler.compileError(superToken, "Can't use 'super' when having no superclass"); +else { +make_shared(cls->parents[0])->optimize()->compile(compiler); +compiler.writeOp(OP_LOAD_THIS); +}} + bool LiteralSequenceExpression::isAssignable () { if (items.size()<1) return false; for (auto& item: items) { @@ -2964,7 +2973,7 @@ string sName = string(setter->token.start, setter->token.length) + ("="); int symbol = compiler.vm.findMethodSymbol(sName); left->compile(compiler); assignedValue->compile(compiler); -compiler.writeOpArg(OP_CALL_METHOD_2, symbol); +compiler.writeOpArg(super? OP_CALL_SUPER_2 : OP_CALL_METHOD_2, symbol); return; } compiler.compileError(right->nearestToken(), ("Bad operand for '.' operator in assignment")); diff --git a/src/swan/vm/Fiber_calls.cpp b/src/swan/vm/Fiber_calls.cpp index cd8721a..30ab8d4 100644 --- a/src/swan/vm/Fiber_calls.cpp +++ b/src/swan/vm/Fiber_calls.cpp @@ -28,12 +28,12 @@ if (!re) error("%s has no method %s", cls.name, vm.methodSymbols[sym void QFiber::callSuperSymbol (int symbol, int nArgs) { uint32_t newStackBase = stack.size() -nArgs; QV receiver = stack.at(newStackBase); -QClass* cls = receiver.getClass(vm) .parent; +QClass* cls = stack.at(newStackBase -1).asObject(); +stack.erase(stack.begin() + newStackBase -1); QV method = cls->findMethod(symbol); bool re = callFunc(method, nArgs); -if (!re) { -error("%s has no method %s", cls->name, vm.methodSymbols[symbol]); -}} +if (!re) error("%s has no method %s", cls->name, vm.methodSymbols[symbol]); +} inline bool QFiber::callFunc (QV& method, int nArgs) { uint32_t newStackBase = stack.size() -nArgs;