diff --git a/src/cdebug.c b/src/cdebug.c index 00718f0..5ae7698 100644 --- a/src/cdebug.c +++ b/src/cdebug.c @@ -125,6 +125,8 @@ int disasmInstr(CChunk *chunk, int offset, int indent) { return simpleInstruction("OP_CLOSE", offset); case OP_NEWTABLE: return u16OperandInstruction("OP_NEWTABLE", chunk, offset); + case OP_NEWARRAY: + return u16OperandInstruction("OP_NEWARRAY", chunk, offset); case OP_INDEX: return simpleInstruction("OP_INDEX", offset); case OP_NEWINDEX: @@ -189,7 +191,7 @@ int disasmInstr(CChunk *chunk, int offset, int indent) { return u8OperandInstruction("OP_RETURN", chunk, offset); default: printf("Unknown opcode! [%d]\n", i); - exit(0); + return 1; } diff --git a/src/coperators.h b/src/coperators.h index b859759..0724bdf 100644 --- a/src/coperators.h +++ b/src/coperators.h @@ -23,6 +23,7 @@ typedef enum { OP_CLOSURE, OP_CLOSE, OP_NEWTABLE, + OP_NEWARRAY, // really just a table OP_INDEX, OP_NEWINDEX, OP_NEWOBJECT, diff --git a/src/cparse.c b/src/cparse.c index 446c942..fc05295 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -646,7 +646,28 @@ static void table(CParseState *pstate, bool canAssign, Precedence prec) { entries++; } while (match(pstate, TOKEN_COMMA)); + + consume(pstate, TOKEN_RIGHT_BRACKET, "Expected ']' to end table definition!"); } + + switch (tblType) { + case 1: // array-like + writeu8(pstate, OP_NEWARRAY); + writeu16(pstate, entries); + valuePopped(pstate, entries); + break; + case 2: // dictionary-like + writeu8(pstate, OP_NEWTABLE); + writeu16(pstate, entries); + valuePopped(pstate, entries * 2); + break; + default: // just make an empty table + writeu8(pstate, OP_NEWTABLE); + writeu16(pstate, 0); + break; + } + + valuePushed(pstate, 1); // table is now on the stack } static void object(CParseState *pstate, bool canAssign, Precedence prec) { @@ -855,7 +876,7 @@ ParseRule ruleTable[] = { [TOKEN_RIGHT_PAREN] = {NULL, NULL, PREC_NONE}, [TOKEN_LEFT_BRACE] = {object, NULL, PREC_NONE}, [TOKEN_RIGHT_BRACE] = {NULL, NULL, PREC_NONE}, - [TOKEN_LEFT_BRACKET] = {NULL, _index, PREC_CALL}, + [TOKEN_LEFT_BRACKET] = {table, _index, PREC_CALL}, [TOKEN_RIGHT_BRACKET] = {NULL, NULL, PREC_NONE}, [TOKEN_COMMA] = {NULL, NULL, PREC_NONE}, [TOKEN_COLON] = {NULL, NULL, PREC_NONE}, diff --git a/src/cvm.c b/src/cvm.c index 7305313..f2c51b1 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -619,6 +619,25 @@ int cosmoV_execute(CState *state) { cosmoV_makeTable(state, pairs); break; } + case OP_NEWARRAY: { + uint16_t pairs = READUINT(); + StkPtr val; + CObjTable *newObj = cosmoO_newTable(state); + cosmoV_pushValue(state, cosmoV_newObj(newObj)); // so our GC doesn't free our new table + + for (int i = 0; i < pairs; i++) { + val = cosmoV_getTop(state, i + 1); + + // set key/value pair + CValue *newVal = cosmoT_insert(state, &newObj->tbl, cosmoV_newNumber(i)); + *newVal = *val; + } + + // once done, pop everything off the stack + push new table + cosmoV_setTop(state, pairs + 1); // + 1 for our table + cosmoV_pushValue(state, cosmoV_newObj(newObj)); + break; + } case OP_INDEX: { StkPtr key = cosmoV_getTop(state, 0); // key should be the top of the stack StkPtr temp = cosmoV_getTop(state, 1); // after that should be the table