Added table support to the parser

a new instruction, OP_NEWARRAY has been added. this instruction will create a table out of the uint16_t values on the stack, with incremental keys [0-(u16-1)]
This commit is contained in:
CPunch 2021-01-08 22:47:36 -06:00
parent 824c0e89b9
commit 75b571c09a
4 changed files with 45 additions and 2 deletions

View File

@ -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;
}

View File

@ -23,6 +23,7 @@ typedef enum {
OP_CLOSURE,
OP_CLOSE,
OP_NEWTABLE,
OP_NEWARRAY, // really just a table
OP_INDEX,
OP_NEWINDEX,
OP_NEWOBJECT,

View File

@ -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},

View File

@ -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