mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-22 07:20:05 +00:00
Dictionaries -> Tables
Tables are going to become a more generic form of data storage. While objects will be "stateful", tables will remain static. '{}' now refers to an object declaration, '[]' will be reserved for tables.
This commit is contained in:
parent
e57c194837
commit
824c0e89b9
@ -126,7 +126,7 @@ void cosmoB_loadLibrary(CState *state) {
|
|||||||
cosmoV_pushString(state, "sub");
|
cosmoV_pushString(state, "sub");
|
||||||
cosmoV_pushCFunction(state, cosmoB_sSub);
|
cosmoV_pushCFunction(state, cosmoB_sSub);
|
||||||
|
|
||||||
cosmoV_makeDictionary(state, 1);
|
cosmoV_makeTable(state, 1);
|
||||||
// string.
|
// string.
|
||||||
|
|
||||||
// register these all to the global table
|
// register these all to the global table
|
||||||
@ -177,7 +177,7 @@ void cosmoB_loadDebug(CState *state) {
|
|||||||
cosmoV_pushString(state, "__proto"); // key
|
cosmoV_pushString(state, "__proto"); // key
|
||||||
cosmoV_pushCFunction(state, cosmoB_dgetProto); // value
|
cosmoV_pushCFunction(state, cosmoB_dgetProto); // value
|
||||||
|
|
||||||
cosmoV_makeDictionary(state, 1);
|
cosmoV_makeTable(state, 1);
|
||||||
|
|
||||||
// make __setter object
|
// make __setter object
|
||||||
cosmoV_pushString(state, "__setter");
|
cosmoV_pushString(state, "__setter");
|
||||||
@ -185,7 +185,7 @@ void cosmoB_loadDebug(CState *state) {
|
|||||||
cosmoV_pushString(state, "__proto");
|
cosmoV_pushString(state, "__proto");
|
||||||
cosmoV_pushCFunction(state, cosmoB_dsetProto);
|
cosmoV_pushCFunction(state, cosmoB_dsetProto);
|
||||||
|
|
||||||
cosmoV_makeDictionary(state, 1);
|
cosmoV_makeTable(state, 1);
|
||||||
|
|
||||||
// we call makeObject leting it know there are 2 sets of key & value pairs on the stack
|
// we call makeObject leting it know there are 2 sets of key & value pairs on the stack
|
||||||
cosmoV_makeObject(state, 2);
|
cosmoV_makeObject(state, 2);
|
||||||
|
@ -123,8 +123,8 @@ int disasmInstr(CChunk *chunk, int offset, int indent) {
|
|||||||
}
|
}
|
||||||
case OP_CLOSE:
|
case OP_CLOSE:
|
||||||
return simpleInstruction("OP_CLOSE", offset);
|
return simpleInstruction("OP_CLOSE", offset);
|
||||||
case OP_NEWDICT:
|
case OP_NEWTABLE:
|
||||||
return u16OperandInstruction("OP_NEWDICT", chunk, offset);
|
return u16OperandInstruction("OP_NEWTABLE", chunk, offset);
|
||||||
case OP_INDEX:
|
case OP_INDEX:
|
||||||
return simpleInstruction("OP_INDEX", offset);
|
return simpleInstruction("OP_INDEX", offset);
|
||||||
case OP_NEWINDEX:
|
case OP_NEWINDEX:
|
||||||
|
@ -97,9 +97,9 @@ void blackenObject(CState *state, CObj *obj) {
|
|||||||
markTable(state, &cobj->tbl);
|
markTable(state, &cobj->tbl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_DICT: { // dictionaries are just wrappers for CTable
|
case COBJ_TABLE: { // tables are just wrappers for CTable
|
||||||
CObjDict *dict = (CObjDict*)obj;
|
CObjTable *tbl = (CObjTable*)obj;
|
||||||
markTable(state, &dict->tbl);
|
markTable(state, &tbl->tbl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_UPVALUE: {
|
case COBJ_UPVALUE: {
|
||||||
|
24
src/cobj.c
24
src/cobj.c
@ -53,10 +53,10 @@ void cosmoO_free(CState *state, CObj* obj) {
|
|||||||
cosmoM_free(state, CObjObject, objTbl);
|
cosmoM_free(state, CObjObject, objTbl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_DICT: {
|
case COBJ_TABLE: {
|
||||||
CObjDict *dict = (CObjDict*)obj;
|
CObjTable *tbl = (CObjTable*)obj;
|
||||||
cosmoT_clearTable(state, &dict->tbl);
|
cosmoT_clearTable(state, &tbl->tbl);
|
||||||
cosmoM_free(state, CObjDict, dict);
|
cosmoM_free(state, CObjTable, tbl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_UPVALUE: {
|
case COBJ_UPVALUE: {
|
||||||
@ -121,8 +121,8 @@ CObjObject *cosmoO_newObject(CState *state) {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjDict *cosmoO_newDictionary(CState *state) {
|
CObjTable *cosmoO_newTable(CState *state) {
|
||||||
CObjDict *obj = (CObjDict*)cosmoO_allocateBase(state, sizeof(CObjDict), COBJ_DICT);
|
CObjTable *obj = (CObjTable*)cosmoO_allocateBase(state, sizeof(CObjTable), COBJ_TABLE);
|
||||||
|
|
||||||
// init the table (might cause a GC event)
|
// init the table (might cause a GC event)
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(obj)); // so our GC can keep track of obj
|
cosmoV_pushValue(state, cosmoV_newObj(obj)); // so our GC can keep track of obj
|
||||||
@ -448,9 +448,9 @@ CObjString *cosmoO_toString(CState *state, CObj *obj) {
|
|||||||
CObjError *err = (CObjError*)obj;
|
CObjError *err = (CObjError*)obj;
|
||||||
return cosmoV_toString(state, err->err);
|
return cosmoV_toString(state, err->err);
|
||||||
}
|
}
|
||||||
case COBJ_DICT: {
|
case COBJ_TABLE: {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
int sz = sprintf(buf, "<dict> %p", (void*)obj) + 1; // +1 for the null character
|
int sz = sprintf(buf, "<tbl> %p", (void*)obj) + 1; // +1 for the null character
|
||||||
return cosmoO_copyString(state, buf, sz);
|
return cosmoO_copyString(state, buf, sz);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -469,9 +469,9 @@ void printObject(CObj *o) {
|
|||||||
printf("<obj> %p", (void*)o);
|
printf("<obj> %p", (void*)o);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_DICT: {
|
case COBJ_TABLE: {
|
||||||
CObjDict *dict = (CObjDict*)o;
|
CObjTable *tbl = (CObjTable*)o;
|
||||||
printf("<dict> %p", (void*)dict);
|
printf("<tbl> %p", (void*)tbl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_UPVALUE: {
|
case COBJ_UPVALUE: {
|
||||||
@ -513,7 +513,7 @@ const char *cosmoO_typeStr(CObj* obj) {
|
|||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case COBJ_STRING: return "<string>";
|
case COBJ_STRING: return "<string>";
|
||||||
case COBJ_OBJECT: return "<object>";
|
case COBJ_OBJECT: return "<object>";
|
||||||
case COBJ_DICT: return "<dictionary>";
|
case COBJ_TABLE: return "<table>";
|
||||||
case COBJ_FUNCTION: return "<function>";
|
case COBJ_FUNCTION: return "<function>";
|
||||||
case COBJ_CFUNCTION: return "<c function>";
|
case COBJ_CFUNCTION: return "<c function>";
|
||||||
case COBJ_METHOD: return "<method>";
|
case COBJ_METHOD: return "<method>";
|
||||||
|
10
src/cobj.h
10
src/cobj.h
@ -6,7 +6,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
COBJ_STRING,
|
COBJ_STRING,
|
||||||
COBJ_OBJECT,
|
COBJ_OBJECT,
|
||||||
COBJ_DICT, // dictionary
|
COBJ_TABLE,
|
||||||
COBJ_FUNCTION,
|
COBJ_FUNCTION,
|
||||||
COBJ_CFUNCTION,
|
COBJ_CFUNCTION,
|
||||||
COBJ_ERROR,
|
COBJ_ERROR,
|
||||||
@ -67,10 +67,10 @@ typedef struct CObjObject {
|
|||||||
};
|
};
|
||||||
} CObjObject;
|
} CObjObject;
|
||||||
|
|
||||||
typedef struct CObjDict { // dictionary, a wrapper for CTable
|
typedef struct CObjTable { // table, a wrapper for CTable
|
||||||
CommonHeader; // "is a" CObj
|
CommonHeader; // "is a" CObj
|
||||||
CTable tbl;
|
CTable tbl;
|
||||||
} CObjDict;
|
} CObjTable;
|
||||||
|
|
||||||
typedef struct CObjFunction {
|
typedef struct CObjFunction {
|
||||||
CommonHeader; // "is a" CObj
|
CommonHeader; // "is a" CObj
|
||||||
@ -111,7 +111,7 @@ typedef struct CObjUpval {
|
|||||||
|
|
||||||
#define IS_STRING(x) isObjType(x, COBJ_STRING)
|
#define IS_STRING(x) isObjType(x, COBJ_STRING)
|
||||||
#define IS_OBJECT(x) isObjType(x, COBJ_OBJECT)
|
#define IS_OBJECT(x) isObjType(x, COBJ_OBJECT)
|
||||||
#define IS_DICT(x) isObjType(x, COBJ_DICT)
|
#define IS_TABLE(x) isObjType(x, COBJ_TABLE)
|
||||||
#define IS_FUNCTION(x) isObjType(x, COBJ_FUNCTION)
|
#define IS_FUNCTION(x) isObjType(x, COBJ_FUNCTION)
|
||||||
#define IS_CFUNCTION(x) isObjType(x, COBJ_CFUNCTION)
|
#define IS_CFUNCTION(x) isObjType(x, COBJ_CFUNCTION)
|
||||||
#define IS_METHOD(x) isObjType(x, COBJ_METHOD)
|
#define IS_METHOD(x) isObjType(x, COBJ_METHOD)
|
||||||
@ -139,7 +139,7 @@ void cosmoO_free(CState *state, CObj* obj);
|
|||||||
bool cosmoO_equal(CObj* obj1, CObj* obj2);
|
bool cosmoO_equal(CObj* obj1, CObj* obj2);
|
||||||
|
|
||||||
CObjObject *cosmoO_newObject(CState *state);
|
CObjObject *cosmoO_newObject(CState *state);
|
||||||
CObjDict *cosmoO_newDictionary(CState *state);
|
CObjTable *cosmoO_newTable(CState *state);
|
||||||
CObjFunction *cosmoO_newFunction(CState *state);
|
CObjFunction *cosmoO_newFunction(CState *state);
|
||||||
CObjCFunction *cosmoO_newCFunction(CState *state, CosmoCFunction func);
|
CObjCFunction *cosmoO_newCFunction(CState *state, CosmoCFunction func);
|
||||||
CObjError *cosmoO_newError(CState *state, CValue err);
|
CObjError *cosmoO_newError(CState *state, CValue err);
|
||||||
|
@ -22,7 +22,7 @@ typedef enum {
|
|||||||
OP_CALL, // calls top[-uint8_t] expecting uint8_t results
|
OP_CALL, // calls top[-uint8_t] expecting uint8_t results
|
||||||
OP_CLOSURE,
|
OP_CLOSURE,
|
||||||
OP_CLOSE,
|
OP_CLOSE,
|
||||||
OP_NEWDICT,
|
OP_NEWTABLE,
|
||||||
OP_INDEX,
|
OP_INDEX,
|
||||||
OP_NEWINDEX,
|
OP_NEWINDEX,
|
||||||
OP_NEWOBJECT,
|
OP_NEWOBJECT,
|
||||||
@ -45,7 +45,7 @@ typedef enum {
|
|||||||
OP_INCLOCAL, // pushes old value to stack, adds (uint8_t-128) to local[uint8_t]
|
OP_INCLOCAL, // pushes old value to stack, adds (uint8_t-128) to local[uint8_t]
|
||||||
OP_INCGLOBAL, // pushes old value to stack, adds (uint8_t-128) to globals[const[uint16_t]]
|
OP_INCGLOBAL, // pushes old value to stack, adds (uint8_t-128) to globals[const[uint16_t]]
|
||||||
OP_INCUPVAL, // pushes old value to stack, adds (uint8_t-128) to closure->upval[uint8_t]
|
OP_INCUPVAL, // pushes old value to stack, adds (uint8_t-128) to closure->upval[uint8_t]
|
||||||
OP_INCINDEX, // pushes old value to stack, adds (uint8_t-128) to dict[pop()]
|
OP_INCINDEX,
|
||||||
OP_INCOBJECT, // pushes old value to stack, adds (uint8_t-128) to obj[const[uint16_t]]
|
OP_INCOBJECT, // pushes old value to stack, adds (uint8_t-128) to obj[const[uint16_t]]
|
||||||
|
|
||||||
// EQUALITY
|
// EQUALITY
|
||||||
|
55
src/cparse.c
55
src/cparse.c
@ -621,6 +621,34 @@ static void call_(CParseState *pstate, bool canAssign, Precedence prec) {
|
|||||||
valuePushed(pstate, returnNum);
|
valuePushed(pstate, returnNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void table(CParseState *pstate, bool canAssign, Precedence prec) {
|
||||||
|
// enter having already consumed '['
|
||||||
|
int entries = 0;
|
||||||
|
int tblType = 0; // 0 = we don't know yet / 1 = array-like table / 2 = dictionary-like table
|
||||||
|
|
||||||
|
if (!match(pstate, TOKEN_RIGHT_BRACKET)) {
|
||||||
|
do {
|
||||||
|
// grab value/key
|
||||||
|
expression(pstate, 1, true);
|
||||||
|
|
||||||
|
// they want to make a table with key:value
|
||||||
|
if (match(pstate, TOKEN_COLON) && tblType != 1) {
|
||||||
|
tblType = 2; // dictionary-like
|
||||||
|
|
||||||
|
// grab value
|
||||||
|
expression(pstate, 1, true);
|
||||||
|
} else if ((check(pstate, TOKEN_COMMA) || check(pstate, TOKEN_RIGHT_BRACKET)) && tblType != 2) {
|
||||||
|
tblType = 1; // array-like
|
||||||
|
} else {
|
||||||
|
error(pstate, "Can't change table description type mid-definition!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entries++;
|
||||||
|
} while (match(pstate, TOKEN_COMMA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void object(CParseState *pstate, bool canAssign, Precedence prec) {
|
static void object(CParseState *pstate, bool canAssign, Precedence prec) {
|
||||||
// already consumed the beginning '{'
|
// already consumed the beginning '{'
|
||||||
int entries = 0;
|
int entries = 0;
|
||||||
@ -628,22 +656,25 @@ static void object(CParseState *pstate, bool canAssign, Precedence prec) {
|
|||||||
if (!match(pstate, TOKEN_RIGHT_BRACE)) {
|
if (!match(pstate, TOKEN_RIGHT_BRACE)) {
|
||||||
do {
|
do {
|
||||||
// parse the key first
|
// parse the key first
|
||||||
expression(pstate, 1, true); // should parse until ':'
|
consume(pstate, TOKEN_IDENTIFIER, "Expected property identifier before '='!");
|
||||||
|
uint16_t ident = identifierConstant(pstate, &pstate->previous);
|
||||||
|
writeu8(pstate, OP_LOADCONST);
|
||||||
|
writeu16(pstate, ident);
|
||||||
|
|
||||||
consume(pstate, TOKEN_COLON, "Expected ':' to mark end of key and start of value!");
|
consume(pstate, TOKEN_EQUAL, "Expected '=' to mark the start of value!");
|
||||||
|
|
||||||
// now, parse the value (until comma)
|
// now, parse the value (until comma)
|
||||||
expression(pstate, 1, true);
|
expression(pstate, 1, true);
|
||||||
|
|
||||||
// "pop" the 2 values
|
// "pop" the 1 value
|
||||||
valuePopped(pstate, 2);
|
valuePopped(pstate, 1);
|
||||||
entries++;
|
entries++;
|
||||||
} while (match(pstate, TOKEN_COMMA) && !pstate->hadError);
|
} while (match(pstate, TOKEN_COMMA) && !pstate->hadError);
|
||||||
|
|
||||||
consume(pstate, TOKEN_RIGHT_BRACE, "Expected '}' to end object definition.");
|
consume(pstate, TOKEN_RIGHT_BRACE, "Expected '}' to end object definition.");
|
||||||
}
|
}
|
||||||
|
|
||||||
writeu8(pstate, OP_NEWDICT); // creates a dictionary with u16 entries
|
writeu8(pstate, OP_NEWOBJECT); // creates a object with u16 entries
|
||||||
writeu16(pstate, entries);
|
writeu16(pstate, entries);
|
||||||
valuePushed(pstate, 1);
|
valuePushed(pstate, 1);
|
||||||
}
|
}
|
||||||
@ -725,7 +756,7 @@ static void walkIndexes(CParseState *pstate, int lastIndexType, uint16_t lastIde
|
|||||||
break;
|
break;
|
||||||
case 1: // []
|
case 1: // []
|
||||||
writeu8(pstate, OP_INDEX); // so, that was a normal index, perform that
|
writeu8(pstate, OP_INDEX); // so, that was a normal index, perform that
|
||||||
valuePopped(pstate, 1); // pops the key & dict off the stack, but pushes the value
|
valuePopped(pstate, 1); // pops the key & table off the stack, but pushes the value
|
||||||
break;
|
break;
|
||||||
default: // no previous index
|
default: // no previous index
|
||||||
break;
|
break;
|
||||||
@ -750,7 +781,7 @@ static void walkIndexes(CParseState *pstate, int lastIndexType, uint16_t lastIde
|
|||||||
case 1: // []
|
case 1: // []
|
||||||
writeu8(pstate, OP_INCINDEX);
|
writeu8(pstate, OP_INCINDEX);
|
||||||
writeu8(pstate, 128 + val);
|
writeu8(pstate, 128 + val);
|
||||||
valuePopped(pstate, 2); // popped the dictionary & the key off the stack, but pushes the previous value
|
valuePopped(pstate, 2); // popped the table & the key off the stack, but pushes the previous value
|
||||||
break;
|
break;
|
||||||
default: // no previous index
|
default: // no previous index
|
||||||
break;
|
break;
|
||||||
@ -766,8 +797,8 @@ static void increment(CParseState *pstate, int val) {
|
|||||||
|
|
||||||
// walk the indexes
|
// walk the indexes
|
||||||
walkIndexes(pstate, 0, ident, val);
|
walkIndexes(pstate, 0, ident, val);
|
||||||
} else if (match(pstate, TOKEN_LEFT_BRACKET)) { // dictionary?
|
} else if (match(pstate, TOKEN_LEFT_BRACKET)) { // table?
|
||||||
namedVariable(pstate, name, false, false, 0); // just get the dictionary
|
namedVariable(pstate, name, false, false, 0); // just get the table
|
||||||
|
|
||||||
// grab key
|
// grab key
|
||||||
expression(pstate, 1, true);
|
expression(pstate, 1, true);
|
||||||
@ -1174,8 +1205,8 @@ static void function(CParseState *pstate, FunctionType type) {
|
|||||||
} while (match(pstate, TOKEN_COMMA));
|
} while (match(pstate, TOKEN_COMMA));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match(pstate, TOKEN_DOT_DOT_DOT)) { // marks a function as variadic, now we expect an identifer for the populated variadic dictionary
|
if (match(pstate, TOKEN_DOT_DOT_DOT)) { // marks a function as variadic, now we expect an identifer for the populated variadic table
|
||||||
uint16_t vari = parseVariable(pstate, "Expected identifier for variadic dictionary!", true);
|
uint16_t vari = parseVariable(pstate, "Expected identifier for variadic table!", true);
|
||||||
defineVariable(pstate, vari, true);
|
defineVariable(pstate, vari, true);
|
||||||
valuePushed(pstate, 1);
|
valuePushed(pstate, 1);
|
||||||
compiler.function->variadic = true;
|
compiler.function->variadic = true;
|
||||||
@ -1271,7 +1302,7 @@ static void forEachLoop(CParseState *pstate) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// after we consume the values, get the dictionary/object/whatever on the stack
|
// after we consume the values, get the table/object/whatever on the stack
|
||||||
consume(pstate, TOKEN_IN, "Expected 'in' before iterator!");
|
consume(pstate, TOKEN_IN, "Expected 'in' before iterator!");
|
||||||
expression(pstate, 1, true);
|
expression(pstate, 1, true);
|
||||||
|
|
||||||
|
104
src/cvm.c
104
src/cvm.c
@ -225,7 +225,7 @@ static bool callCFunction(CState *state, CosmoCFunction cfunc, int args, int nre
|
|||||||
static bool rawCall(CState *state, CObjClosure *closure, int args, int nresults, int offset) {
|
static bool rawCall(CState *state, CObjClosure *closure, int args, int nresults, int offset) {
|
||||||
CObjFunction *func = closure->function;
|
CObjFunction *func = closure->function;
|
||||||
|
|
||||||
// if the function is variadic and theres more args than parameters, push the args into a dictionary
|
// if the function is variadic and theres more args than parameters, push the args into a table
|
||||||
if (func->variadic && args >= func->args) {
|
if (func->variadic && args >= func->args) {
|
||||||
int extraArgs = args - func->args;
|
int extraArgs = args - func->args;
|
||||||
StkPtr variStart = cosmoV_getTop(state, extraArgs-1);
|
StkPtr variStart = cosmoV_getTop(state, extraArgs-1);
|
||||||
@ -236,8 +236,8 @@ static bool rawCall(CState *state, CObjClosure *closure, int args, int nresults,
|
|||||||
cosmoV_pushValue(state, *(variStart + i));
|
cosmoV_pushValue(state, *(variStart + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_makeDictionary(state, extraArgs);
|
cosmoV_makeTable(state, extraArgs);
|
||||||
*variStart = *cosmoV_getTop(state, 0); // move dict on the stack to the vari local
|
*variStart = *cosmoV_getTop(state, 0); // move table on the stack to the vari local
|
||||||
state->top -= extraArgs;
|
state->top -= extraArgs;
|
||||||
|
|
||||||
pushCallFrame(state, closure, func->args + 1);
|
pushCallFrame(state, closure, func->args + 1);
|
||||||
@ -390,10 +390,10 @@ COSMO_API void cosmoV_makeObject(CState *state, int pairs) {
|
|||||||
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
||||||
}
|
}
|
||||||
|
|
||||||
COSMO_API void cosmoV_makeDictionary(CState *state, int pairs) {
|
COSMO_API void cosmoV_makeTable(CState *state, int pairs) {
|
||||||
StkPtr key, val;
|
StkPtr key, val;
|
||||||
CObjDict *newObj = cosmoO_newDictionary(state);
|
CObjTable *newObj = cosmoO_newTable(state);
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(newObj)); // so our GC doesn't free our new dictionary
|
cosmoV_pushValue(state, cosmoV_newObj(newObj)); // so our GC doesn't free our new table
|
||||||
|
|
||||||
for (int i = 0; i < pairs; i++) {
|
for (int i = 0; i < pairs; i++) {
|
||||||
val = cosmoV_getTop(state, (i*2) + 1);
|
val = cosmoV_getTop(state, (i*2) + 1);
|
||||||
@ -404,8 +404,8 @@ COSMO_API void cosmoV_makeDictionary(CState *state, int pairs) {
|
|||||||
*newVal = *val;
|
*newVal = *val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// once done, pop everything off the stack + push new dictionary
|
// once done, pop everything off the stack + push new table
|
||||||
cosmoV_setTop(state, (pairs * 2) + 1); // + 1 for our dictionary
|
cosmoV_setTop(state, (pairs * 2) + 1); // + 1 for our table
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +449,7 @@ COSMO_API bool cosmoV_set(CState *state, CObj *_obj, CValue key, CValue val) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _dict__next(CState *state, int nargs, CValue *args) {
|
int _tbl__next(CState *state, int nargs, CValue *args) {
|
||||||
if (nargs != 1) {
|
if (nargs != 1) {
|
||||||
cosmoV_error(state, "Expected 1 parameter, %d received!", nargs);
|
cosmoV_error(state, "Expected 1 parameter, %d received!", nargs);
|
||||||
return 0;
|
return 0;
|
||||||
@ -466,17 +466,17 @@ int _dict__next(CState *state, int nargs, CValue *args) {
|
|||||||
|
|
||||||
cosmoO_getIString(state, obj, ISTRING_RESERVED, &val);
|
cosmoO_getIString(state, obj, ISTRING_RESERVED, &val);
|
||||||
|
|
||||||
if (!IS_DICT(val)) {
|
if (!IS_TABLE(val)) {
|
||||||
return 0; // someone set the __reserved member to something else. this will exit the iterator loop
|
return 0; // someone set the __reserved member to something else. this will exit the iterator loop
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(val);
|
CObjTable *table = (CObjTable*)cosmoV_readObj(val);
|
||||||
|
|
||||||
// while the entry is invalid, go to the next entry
|
// while the entry is invalid, go to the next entry
|
||||||
CTableEntry *entry;
|
CTableEntry *entry;
|
||||||
do {
|
do {
|
||||||
entry = &dict->tbl.table[index++];
|
entry = &table->tbl.table[index++];
|
||||||
} while (IS_NIL(entry->key) && index < dict->tbl.capacity);
|
} while (IS_NIL(entry->key) && index < table->tbl.capacity);
|
||||||
cosmoO_setUserI(state, obj, index); // update the userdata
|
cosmoO_setUserI(state, obj, index); // update the userdata
|
||||||
|
|
||||||
if (!IS_NIL(entry->key)) { // if the entry is valid, return it's key and value pair
|
if (!IS_NIL(entry->key)) { // if the entry is valid, return it's key and value pair
|
||||||
@ -614,24 +614,24 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_NEWDICT: {
|
case OP_NEWTABLE: {
|
||||||
uint16_t pairs = READUINT();
|
uint16_t pairs = READUINT();
|
||||||
cosmoV_makeDictionary(state, pairs);
|
cosmoV_makeTable(state, pairs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_INDEX: {
|
case OP_INDEX: {
|
||||||
StkPtr key = cosmoV_getTop(state, 0); // key should be the top of the stack
|
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 dictionary
|
StkPtr temp = cosmoV_getTop(state, 1); // after that should be the table
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
CValue val; // to hold our value
|
CValue val; // to hold our value
|
||||||
|
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
case COBJ_DICT: {
|
case COBJ_TABLE: {
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
cosmoT_get(&dict->tbl, *key, &val);
|
cosmoT_get(&tbl->tbl, *key, &val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { // check for __index metamethod
|
default: { // check for __index metamethod
|
||||||
@ -665,9 +665,9 @@ int cosmoV_execute(CState *state) {
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
case COBJ_DICT: { // index and set table
|
case COBJ_TABLE: { // index and set table
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
CValue *newVal = cosmoT_insert(state, &dict->tbl, *key);
|
CValue *newVal = cosmoT_insert(state, &tbl->tbl, *key);
|
||||||
|
|
||||||
*newVal = *value; // set the index
|
*newVal = *value; // set the index
|
||||||
break;
|
break;
|
||||||
@ -709,10 +709,10 @@ int cosmoV_execute(CState *state) {
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
case COBJ_DICT: { // syntax sugar, makes "namespaces" possible
|
case COBJ_TABLE: { // syntax sugar, makes "namespaces" possible
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
cosmoT_get(&dict->tbl, constants[ident], &val);
|
cosmoT_get(&tbl->tbl, constants[ident], &val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -736,9 +736,9 @@ int cosmoV_execute(CState *state) {
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
case COBJ_DICT: { // index and set the table
|
case COBJ_TABLE: { // index and set the table
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
CValue *newVal = cosmoT_insert(state, &dict->tbl, constants[ident]);
|
CValue *newVal = cosmoT_insert(state, &tbl->tbl, constants[ident]);
|
||||||
|
|
||||||
*newVal = *value; // set the index
|
*newVal = *value; // set the index
|
||||||
break;
|
break;
|
||||||
@ -757,19 +757,19 @@ int cosmoV_execute(CState *state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_INVOKE: { // this is an optimization made by the parser, instead of allocating a CObjMethod every time we want to invoke a method, we shrink it down into one minimal instruction!
|
case OP_INVOKE: { // this is an optimization made by the parser, instead of allocating a CObjMethod every time we want to invoke a method, we shrink it down into one minimal instruction!
|
||||||
CValue val; // to hold our value
|
|
||||||
uint8_t args = READBYTE();
|
uint8_t args = READBYTE();
|
||||||
uint8_t nres = READBYTE();
|
uint8_t nres = READBYTE();
|
||||||
uint16_t ident = READUINT();
|
uint16_t ident = READUINT();
|
||||||
StkPtr temp = cosmoV_getTop(state, args); // grabs object from stack
|
StkPtr temp = cosmoV_getTop(state, args); // grabs object from stack
|
||||||
|
CValue val; // to hold our value
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
case COBJ_DICT: { // again, syntax sugar ("""""namespaces""""")
|
case COBJ_TABLE: { // again, syntax sugar ("""""namespaces""""")
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
cosmoT_get(&dict->tbl, constants[ident], &val);
|
cosmoT_get(&tbl->tbl, constants[ident], &val);
|
||||||
|
|
||||||
// call closure/cfunction
|
// call closure/cfunction
|
||||||
if (!callCValue(state, val, args, nres, 0))
|
if (!callCValue(state, val, args, nres, 0))
|
||||||
@ -799,7 +799,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_ITER: {
|
case OP_ITER: {
|
||||||
StkPtr temp = cosmoV_getTop(state, 0); // should be the object/dictionary
|
StkPtr temp = cosmoV_getTop(state, 0); // should be the object/table
|
||||||
|
|
||||||
if (!IS_OBJ(*temp)) {
|
if (!IS_OBJ(*temp)) {
|
||||||
cosmoV_error(state, "Couldn't iterate over non-iterator type %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Couldn't iterate over non-iterator type %s!", cosmoV_typeStr(*temp));
|
||||||
@ -808,15 +808,15 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
CObj *obj = cosmoV_readObj(*temp);
|
CObj *obj = cosmoV_readObj(*temp);
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case COBJ_DICT: {
|
case COBJ_TABLE: {
|
||||||
CObjDict *dict = (CObjDict*)obj;
|
CObjTable *tbl = (CObjTable*)obj;
|
||||||
|
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(state->iStrings[ISTRING_RESERVED])); // key
|
cosmoV_pushValue(state, cosmoV_newObj(state->iStrings[ISTRING_RESERVED])); // key
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(dict)); // value
|
cosmoV_pushValue(state, cosmoV_newObj(tbl)); // value
|
||||||
|
|
||||||
cosmoV_pushString(state, "__next"); // key
|
cosmoV_pushString(state, "__next"); // key
|
||||||
CObjCFunction *dict_next = cosmoO_newCFunction(state, _dict__next);
|
CObjCFunction *tbl_next = cosmoO_newCFunction(state, _tbl__next);
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(dict_next)); // value
|
cosmoV_pushValue(state, cosmoV_newObj(tbl_next)); // value
|
||||||
|
|
||||||
cosmoV_makeObject(state, 2); // pushes the new object to the stack
|
cosmoV_makeObject(state, 2); // pushes the new object to the stack
|
||||||
|
|
||||||
@ -824,9 +824,9 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoO_setUserI(state, obj, 0); // increment for iterator
|
cosmoO_setUserI(state, obj, 0); // increment for iterator
|
||||||
|
|
||||||
// make our CObjMethod for OP_NEXT to call
|
// make our CObjMethod for OP_NEXT to call
|
||||||
CObjMethod *method = cosmoO_newMethod(state, cosmoV_newObj(dict_next), (CObj*)obj);
|
CObjMethod *method = cosmoO_newMethod(state, cosmoV_newObj(tbl_next), (CObj*)obj);
|
||||||
|
|
||||||
cosmoV_setTop(state, 2); // pops the object & the dict
|
cosmoV_setTop(state, 2); // pops the object & the tbl
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(method)); // pushes the method for OP_NEXT
|
cosmoV_pushValue(state, cosmoV_newObj(method)); // pushes the method for OP_NEXT
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -930,17 +930,17 @@ int cosmoV_execute(CState *state) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_COUNT: { // pop 1 value off the stack & if it's a dictionary return the amount of active entries it has
|
case OP_COUNT: { // pop 1 value off the stack & if it's a table return the amount of active entries it has
|
||||||
StkPtr temp = cosmoV_getTop(state, 0);
|
StkPtr temp = cosmoV_getTop(state, 0);
|
||||||
|
|
||||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_DICT) {
|
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_TABLE) {
|
||||||
cosmoV_error(state, "Expected object, got %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Expected object, got %s!", cosmoV_typeStr(*temp));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
cosmoV_pushNumber(state, cosmoT_count(&dict->tbl)); // pushes the count onto the stack
|
cosmoV_pushNumber(state, cosmoT_count(&tbl->tbl)); // pushes the count onto the stack
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_CONCAT: {
|
case OP_CONCAT: {
|
||||||
@ -1004,11 +1004,11 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
case COBJ_DICT: {
|
case COBJ_TABLE: {
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
CValue *val = cosmoT_insert(state, &dict->tbl, *key);
|
CValue *val = cosmoT_insert(state, &tbl->tbl, *key);
|
||||||
|
|
||||||
// pops dict & key from stack
|
// pops tbl & key from stack
|
||||||
cosmoV_setTop(state, 2);
|
cosmoV_setTop(state, 2);
|
||||||
|
|
||||||
if (IS_NUMBER(*val)) {
|
if (IS_NUMBER(*val)) {
|
||||||
@ -1063,11 +1063,11 @@ int cosmoV_execute(CState *state) {
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
case COBJ_DICT: {
|
case COBJ_TABLE: {
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(*temp);
|
||||||
CValue *val = cosmoT_insert(state, &dict->tbl, ident);
|
CValue *val = cosmoT_insert(state, &tbl->tbl, ident);
|
||||||
|
|
||||||
// pops dict from stack
|
// pops tbl from stack
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
|
|
||||||
if (IS_NUMBER(*val)) {
|
if (IS_NUMBER(*val)) {
|
||||||
|
@ -16,7 +16,7 @@ typedef enum {
|
|||||||
COSMO_API COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults);
|
COSMO_API COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults);
|
||||||
COSMO_API COSMOVMRESULT cosmoV_pcall(CState *state, int args, int nresults);
|
COSMO_API COSMOVMRESULT cosmoV_pcall(CState *state, int args, int nresults);
|
||||||
COSMO_API void cosmoV_makeObject(CState *state, int pairs);
|
COSMO_API void cosmoV_makeObject(CState *state, int pairs);
|
||||||
COSMO_API void cosmoV_makeDictionary(CState *state, int pairs);
|
COSMO_API void cosmoV_makeTable(CState *state, int pairs);
|
||||||
COSMO_API void cosmoV_concat(CState *state, int vals);
|
COSMO_API void cosmoV_concat(CState *state, int vals);
|
||||||
COSMO_API void cosmoV_pushFString(CState *state, const char *format, ...);
|
COSMO_API void cosmoV_pushFString(CState *state, const char *format, ...);
|
||||||
COSMO_API void cosmoV_printError(CState *state, CObjError *err);
|
COSMO_API void cosmoV_printError(CState *state, CObjError *err);
|
||||||
|
Loading…
Reference in New Issue
Block a user