diff --git a/builtin/core.wren b/builtin/core.wren index 34713981..8fe04790 100644 --- a/builtin/core.wren +++ b/builtin/core.wren @@ -1,6 +1,6 @@ class Sequence { map(f) { - var result = [] + var result = new List for (element in this) { result.add(f.call(element)) } @@ -8,7 +8,7 @@ class Sequence { } where(f) { - var result = [] + var result = new List for (element in this) { if (f.call(element)) result.add(element) } diff --git a/src/wren_compiler.c b/src/wren_compiler.c index a807f98c..ec96aaac 100644 --- a/src/wren_compiler.c +++ b/src/wren_compiler.c @@ -1628,33 +1628,46 @@ static void grouping(Compiler* compiler, bool allowAssignment) // A list literal. static void list(Compiler* compiler, bool allowAssignment) { - // Compile the list elements. - int numElements = 0; + // Load the List class. + int listClassSymbol = wrenSymbolTableFind(&compiler->parser->vm->globalNames, + "List", 4); + ASSERT(listClassSymbol != -1, "Should have already defined 'List' global."); + emitShortArg(compiler, CODE_LOAD_GLOBAL, listClassSymbol); + + // Instantiate a new list. + emitShortArg(compiler, CODE_CALL_0, + methodSymbol(compiler, " instantiate", 12)); + + int addSymbol = methodSymbol(compiler, "add ", 4); + + // Compile the list elements. Each one compiles to a ".add()" call. if (peek(compiler) != TOKEN_RIGHT_BRACKET) { do { ignoreNewlines(compiler); - numElements++; + + // Push a copy of the list since the add() call will consume it. + emit(compiler, CODE_DUP); + + // The element. expression(compiler); + + emitShortArg(compiler, CODE_CALL_1, addSymbol); + + // Discard the result of the add() call. + emit(compiler, CODE_POP); } while (match(compiler, TOKEN_COMMA)); } // Allow newlines before the closing ']'. ignoreNewlines(compiler); consume(compiler, TOKEN_RIGHT_BRACKET, "Expect ']' after list elements."); - - // Create the list. - // TODO: Handle lists >255 elements. - emitByteArg(compiler, CODE_LIST, numElements); } // A map literal. static void map(Compiler* compiler, bool allowAssignment) { - // TODO: Do we want to do the same thing for list literals and remove the - // bytecodes for them? - // Load the Map class. int mapClassSymbol = wrenSymbolTableFind(&compiler->parser->vm->globalNames, "Map", 3); @@ -2403,7 +2416,6 @@ static int getNumArguments(const uint8_t* bytecode, const Value* constants, case CODE_STORE_FIELD_THIS: case CODE_LOAD_FIELD: case CODE_STORE_FIELD: - case CODE_LIST: case CODE_CLASS: return 1; diff --git a/src/wren_core.c b/src/wren_core.c index 180fef31..8f17f2ec 100644 --- a/src/wren_core.c +++ b/src/wren_core.c @@ -43,7 +43,7 @@ static const char* libSource = "class Sequence {\n" " map(f) {\n" -" var result = []\n" +" var result = new List\n" " for (element in this) {\n" " result.add(f.call(element))\n" " }\n" @@ -51,7 +51,7 @@ static const char* libSource = " }\n" "\n" " where(f) {\n" -" var result = []\n" +" var result = new List\n" " for (element in this) {\n" " if (f.call(element)) result.add(element)\n" " }\n" diff --git a/src/wren_debug.c b/src/wren_debug.c index ae03d3e4..b855bb4a 100644 --- a/src/wren_debug.c +++ b/src/wren_debug.c @@ -201,13 +201,6 @@ static int debugPrintInstruction(WrenVM* vm, ObjFn* fn, int i, int* lastLine) case CODE_CLOSE_UPVALUE: printf("CLOSE_UPVALUE\n"); break; case CODE_RETURN: printf("CODE_RETURN\n"); break; - case CODE_LIST: - { - int length = READ_BYTE(); - printf("%-16s %5d length\n", "LIST", length); - break; - } - case CODE_CLOSURE: { int constant = READ_SHORT(); diff --git a/src/wren_vm.c b/src/wren_vm.c index 316302e8..2e4e35fc 100644 --- a/src/wren_vm.c +++ b/src/wren_vm.c @@ -493,7 +493,6 @@ static bool runInterpreter(WrenVM* vm) &&code_IS, &&code_CLOSE_UPVALUE, &&code_RETURN, - &&code_LIST, &&code_CLOSURE, &&code_CLASS, &&code_METHOD_INSTANCE, @@ -927,23 +926,6 @@ static bool runInterpreter(WrenVM* vm) DISPATCH(); } - CASE_CODE(LIST): - { - uint8_t numElements = READ_BYTE(); - ObjList* list = wrenNewList(vm, numElements); - // TODO: Do a straight memcopy. - for (int i = 0; i < numElements; i++) - { - list->elements[i] = *(fiber->stackTop - numElements + i); - } - - // Discard the elements. - fiber->stackTop -= numElements; - - PUSH(OBJ_VAL(list)); - DISPATCH(); - } - CASE_CODE(CLOSURE): { ObjFn* prototype = AS_FN(fn->constants[READ_SHORT()]); diff --git a/src/wren_vm.h b/src/wren_vm.h index 80c5d3f9..77f26f7b 100644 --- a/src/wren_vm.h +++ b/src/wren_vm.h @@ -148,11 +148,6 @@ typedef enum // stack. CODE_RETURN, - // Create a new list with [arg] elements. The top [arg] values on the stack - // are the elements in forward order. Removes the elements and then pushes - // the new list. - CODE_LIST, - // Creates a closure for the function stored at [arg] in the constant table. // // Following the function argument is a number of arguments, two for each