mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 08:10:05 +00:00
Added CObj->proto support, state->protoObjects defines default protos for each COBJ type
a lot of refactoring in the VM
This commit is contained in:
parent
c5bd0c2478
commit
1351ff63b1
@ -131,13 +131,24 @@ void cosmoB_loadLibrary(CState *state) {
|
|||||||
|
|
||||||
// register these all to the global table
|
// register these all to the global table
|
||||||
cosmoV_register(state, 5);
|
cosmoV_register(state, 5);
|
||||||
|
|
||||||
|
// make string object for CObjStrings
|
||||||
|
|
||||||
|
// sub
|
||||||
|
cosmoV_pushString(state, "sub");
|
||||||
|
cosmoV_pushCFunction(state, cosmoB_sSub);
|
||||||
|
|
||||||
|
cosmoV_makeObject(state, 1);
|
||||||
|
|
||||||
|
StkPtr obj = cosmoV_pop(state);
|
||||||
|
state->protoObjects[COBJ_STRING] = cosmoV_readObject(*obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================ [DEBUG] ================================================================
|
// ================================================================ [DEBUG] ================================================================
|
||||||
|
|
||||||
int cosmoB_dsetProto(CState *state, int nargs, CValue *args) {
|
int cosmoB_dsetProto(CState *state, int nargs, CValue *args) {
|
||||||
if (nargs == 2) {
|
if (nargs == 2) {
|
||||||
CObjObject *obj = cosmoV_readObject(args[0]); // object to set proto too
|
CObj *obj = cosmoV_readObj(args[0]); // object to set proto too
|
||||||
CObjObject *proto = cosmoV_readObject(args[1]);
|
CObjObject *proto = cosmoV_readObject(args[1]);
|
||||||
|
|
||||||
obj->proto = proto; // boom done
|
obj->proto = proto; // boom done
|
||||||
@ -153,7 +164,7 @@ int cosmoB_dgetProto(CState *state, int nargs, CValue *args) {
|
|||||||
cosmoV_error(state, "Expected 1 argument, got %d!", nargs);
|
cosmoV_error(state, "Expected 1 argument, got %d!", nargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(cosmoV_readObject(args[0])->proto)); // just return the proto
|
cosmoV_pushValue(state, cosmoV_newObj(cosmoV_readObject(args[0])->_obj.proto)); // just return the proto
|
||||||
|
|
||||||
return 1; // 1 result
|
return 1; // 1 result
|
||||||
}
|
}
|
||||||
@ -179,6 +190,6 @@ void cosmoB_loadDebug(CState *state) {
|
|||||||
// 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);
|
||||||
|
|
||||||
// set debug proto to the debug object
|
// set debug protos to the debug object
|
||||||
state->protoObj = cosmoV_readObject(*cosmoV_pop(state));
|
state->protoObjects[COBJ_OBJECT] = cosmoV_readObject(*cosmoV_pop(state));
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ void markArray(CState *state, CValueArray *array) {
|
|||||||
|
|
||||||
// mark all references associated with the object
|
// mark all references associated with the object
|
||||||
void blackenObject(CState *state, CObj *obj) {
|
void blackenObject(CState *state, CObj *obj) {
|
||||||
|
markObject(state, (CObj*)obj->proto);
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case COBJ_STRING:
|
case COBJ_STRING:
|
||||||
case COBJ_CFUNCTION:
|
case COBJ_CFUNCTION:
|
||||||
@ -94,7 +95,6 @@ void blackenObject(CState *state, CObj *obj) {
|
|||||||
// mark everything this object is keeping track of
|
// mark everything this object is keeping track of
|
||||||
CObjObject *cobj = (CObjObject*)obj;
|
CObjObject *cobj = (CObjObject*)obj;
|
||||||
markTable(state, &cobj->tbl);
|
markTable(state, &cobj->tbl);
|
||||||
markObject(state, (CObj*)cobj->proto);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_DICT: { // dictionaries are just wrappers for CTable
|
case COBJ_DICT: { // dictionaries are just wrappers for CTable
|
||||||
@ -243,9 +243,11 @@ void markRoots(CState *state) {
|
|||||||
markUserRoots(state);
|
markUserRoots(state);
|
||||||
|
|
||||||
// mark other misc. internally reserved objects
|
// mark other misc. internally reserved objects
|
||||||
markObject(state, (CObj*)state->protoObj);
|
|
||||||
markObject(state, (CObj*)state->error);
|
markObject(state, (CObj*)state->error);
|
||||||
|
|
||||||
|
for (int i = 0; i < COBJ_MAX; i++)
|
||||||
|
markObject(state, (CObj*)state->protoObjects[i]);
|
||||||
|
|
||||||
traceGrays(state);
|
traceGrays(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
59
src/cobj.c
59
src/cobj.c
@ -22,6 +22,7 @@ CObj *cosmoO_allocateBase(CState *state, size_t sz, CObjType type) {
|
|||||||
CObj* obj = (CObj*)cosmoM_xmalloc(state, sz);
|
CObj* obj = (CObj*)cosmoM_xmalloc(state, sz);
|
||||||
obj->type = type;
|
obj->type = type;
|
||||||
obj->isMarked = false;
|
obj->isMarked = false;
|
||||||
|
obj->proto = state->protoObjects[type];
|
||||||
|
|
||||||
obj->next = state->objects;
|
obj->next = state->objects;
|
||||||
state->objects = obj;
|
state->objects = obj;
|
||||||
@ -88,6 +89,7 @@ void cosmoO_free(CState *state, CObj* obj) {
|
|||||||
cosmoM_free(state, CObjClosure, closure);
|
cosmoM_free(state, CObjClosure, closure);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case COBJ_MAX: { /* stubbed, should never happen */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +112,6 @@ bool cosmoO_equal(CObj* obj1, CObj* obj2) {
|
|||||||
|
|
||||||
CObjObject *cosmoO_newObject(CState *state) {
|
CObjObject *cosmoO_newObject(CState *state) {
|
||||||
CObjObject *obj = (CObjObject*)cosmoO_allocateBase(state, sizeof(CObjObject), COBJ_OBJECT);
|
CObjObject *obj = (CObjObject*)cosmoO_allocateBase(state, sizeof(CObjObject), COBJ_OBJECT);
|
||||||
obj->proto = state->protoObj;
|
|
||||||
obj->istringFlags = 0;
|
obj->istringFlags = 0;
|
||||||
obj->userP = NULL; // reserved for C API
|
obj->userP = NULL; // reserved for C API
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(obj)); // so our GC can keep track of it
|
cosmoV_pushValue(state, cosmoV_newObj(obj)); // so our GC can keep track of it
|
||||||
@ -164,16 +165,9 @@ CObjError *cosmoO_newError(CState *state, CValue err) {
|
|||||||
return cerror;
|
return cerror;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjMethod *cosmoO_newCMethod(CState *state, CObjCFunction *func, CObjObject *obj) {
|
CObjMethod *cosmoO_newMethod(CState *state, CValue func, CObj *obj) {
|
||||||
CObjMethod *method = (CObjMethod*)cosmoO_allocateBase(state, sizeof(CObjMethod), COBJ_METHOD);
|
CObjMethod *method = (CObjMethod*)cosmoO_allocateBase(state, sizeof(CObjMethod), COBJ_METHOD);
|
||||||
method->func = cosmoV_newObj(func);
|
method->func = func;
|
||||||
method->obj = obj;
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
CObjMethod *cosmoO_newMethod(CState *state, CObjClosure *func, CObjObject *obj) {
|
|
||||||
CObjMethod *method = (CObjMethod*)cosmoO_allocateBase(state, sizeof(CObjMethod), COBJ_METHOD);
|
|
||||||
method->func = cosmoV_newObj(func);
|
|
||||||
method->obj = obj;
|
method->obj = obj;
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
@ -304,8 +298,10 @@ bool cosmoO_getRawObject(CState *state, CObjObject *object, CValue key, CValue *
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object->proto != NULL && cosmoO_getRawObject(state, object->proto, key, val))
|
if (object->_obj.proto != NULL && cosmoO_getRawObject(state, object->_obj.proto, key, val))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
*val = cosmoV_newNil();
|
||||||
return false; // no protoobject to check against / key not found
|
return false; // no protoobject to check against / key not found
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +321,7 @@ void cosmoO_setRawObject(CState *state, CObjObject *object, CValue key, CValue v
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the key is an IString, we need to reset the cache
|
// if the key is an IString, we need to reset the cache
|
||||||
if (IS_STRING(key) && ((CObjString*)cosmoV_readObj(key))->isIString)
|
if (IS_STRING(key) && cosmoV_readString(key)->isIString)
|
||||||
object->istringFlags = 0; // reset cache
|
object->istringFlags = 0; // reset cache
|
||||||
|
|
||||||
if (IS_NIL(val)) { // if we're setting an index to nil, we can safely mark that as a tombstone
|
if (IS_NIL(val)) { // if we're setting an index to nil, we can safely mark that as a tombstone
|
||||||
@ -371,7 +367,7 @@ bool cosmoO_getIString(CState *state, CObjObject *object, int flag, CValue *val)
|
|||||||
do {
|
do {
|
||||||
if (rawgetIString(state, obj, flag, val))
|
if (rawgetIString(state, obj, flag, val))
|
||||||
return true;
|
return true;
|
||||||
} while ((obj = obj->proto) != NULL); // sets obj to it's proto and compares it to NULL
|
} while ((obj = obj->_obj.proto) != NULL); // sets obj to it's proto and compares it to NULL
|
||||||
|
|
||||||
return false; // obj->proto was false, the istring doesn't exist in this object chain
|
return false; // obj->proto was false, the istring doesn't exist in this object chain
|
||||||
}
|
}
|
||||||
@ -409,25 +405,13 @@ bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
CObjString *cosmoO_toString(CState *state, CObj *obj) {
|
CObjString *cosmoO_toString(CState *state, CObj *obj) {
|
||||||
switch (obj->type) {
|
CObjObject *protoObject = cosmoO_grabProto(obj);
|
||||||
case COBJ_STRING: {
|
|
||||||
return (CObjString*)obj;
|
|
||||||
}
|
|
||||||
case COBJ_CLOSURE: { // should be transparent to the user imo
|
|
||||||
CObjClosure *closure = (CObjClosure*)obj;
|
|
||||||
return cosmoO_toString(state, (CObj*)closure->function);
|
|
||||||
}
|
|
||||||
case COBJ_FUNCTION: {
|
|
||||||
CObjFunction *func = (CObjFunction*)obj;
|
|
||||||
return func->name != NULL ? func->name : cosmoO_copyString(state, UNNAMEDCHUNK, strlen(UNNAMEDCHUNK));
|
|
||||||
}
|
|
||||||
case COBJ_OBJECT: {
|
|
||||||
CObjObject *object = (CObjObject*)obj;
|
|
||||||
CValue res;
|
CValue res;
|
||||||
|
|
||||||
if (cosmoO_getIString(state, object, ISTRING_TOSTRING, &res)) {
|
// use user-defined __tostring
|
||||||
|
if (protoObject != NULL && cosmoO_getIString(state, protoObject, ISTRING_TOSTRING, &res)) {
|
||||||
cosmoV_pushValue(state, res);
|
cosmoV_pushValue(state, res);
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(object));
|
cosmoV_pushValue(state, cosmoV_newObj(obj));
|
||||||
if (cosmoV_call(state, 1, 1) != COSMOVM_OK)
|
if (cosmoV_call(state, 1, 1) != COSMOVM_OK)
|
||||||
return cosmoO_copyString(state, "<err>", 5);
|
return cosmoO_copyString(state, "<err>", 5);
|
||||||
|
|
||||||
@ -441,12 +425,25 @@ CObjString *cosmoO_toString(CState *state, CObj *obj) {
|
|||||||
// return string
|
// return string
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
return (CObjString*)cosmoV_readObj(*ret);
|
return (CObjString*)cosmoV_readObj(*ret);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
switch (obj->type) {
|
||||||
|
case COBJ_STRING: {
|
||||||
|
return (CObjString*)obj;
|
||||||
|
}
|
||||||
|
case COBJ_CLOSURE: { // should be transparent to the user imo
|
||||||
|
CObjClosure *closure = (CObjClosure*)obj;
|
||||||
|
return cosmoO_toString(state, (CObj*)closure->function);
|
||||||
|
}
|
||||||
|
case COBJ_FUNCTION: {
|
||||||
|
CObjFunction *func = (CObjFunction*)obj;
|
||||||
|
return func->name != NULL ? func->name : cosmoO_copyString(state, UNNAMEDCHUNK, strlen(UNNAMEDCHUNK));
|
||||||
|
}
|
||||||
|
case COBJ_OBJECT: {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
int sz = sprintf(buf, "<obj> %p", (void*)obj) + 1; // +1 for the null character
|
int sz = sprintf(buf, "<obj> %p", (void*)obj) + 1; // +1 for the null character
|
||||||
return cosmoO_copyString(state, buf, sz);
|
return cosmoO_copyString(state, buf, sz);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
case COBJ_ERROR: {
|
case COBJ_ERROR: {
|
||||||
CObjError *err = (CObjError*)obj;
|
CObjError *err = (CObjError*)obj;
|
||||||
return cosmoV_toString(state, err->err);
|
return cosmoV_toString(state, err->err);
|
||||||
|
35
src/cobj.h
35
src/cobj.h
@ -2,14 +2,6 @@
|
|||||||
#define COBJ_H
|
#define COBJ_H
|
||||||
|
|
||||||
#include "cosmo.h"
|
#include "cosmo.h"
|
||||||
#include "cstate.h"
|
|
||||||
#include "cchunk.h"
|
|
||||||
#include "cvalue.h"
|
|
||||||
#include "ctable.h"
|
|
||||||
|
|
||||||
typedef struct CState CState;
|
|
||||||
typedef struct CCallFrame CCallFrame;
|
|
||||||
typedef uint32_t cosmo_Flag;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
COBJ_STRING,
|
COBJ_STRING,
|
||||||
@ -22,8 +14,18 @@ typedef enum {
|
|||||||
COBJ_METHOD,
|
COBJ_METHOD,
|
||||||
COBJ_CLOSURE,
|
COBJ_CLOSURE,
|
||||||
COBJ_UPVALUE,
|
COBJ_UPVALUE,
|
||||||
|
COBJ_MAX
|
||||||
} CObjType;
|
} CObjType;
|
||||||
|
|
||||||
|
#include "cstate.h"
|
||||||
|
#include "cchunk.h"
|
||||||
|
#include "cvalue.h"
|
||||||
|
#include "ctable.h"
|
||||||
|
|
||||||
|
typedef struct CState CState;
|
||||||
|
typedef struct CCallFrame CCallFrame;
|
||||||
|
typedef uint32_t cosmo_Flag;
|
||||||
|
|
||||||
#define CommonHeader CObj _obj
|
#define CommonHeader CObj _obj
|
||||||
#define readFlag(x, flag) (x & (1u << flag))
|
#define readFlag(x, flag) (x & (1u << flag))
|
||||||
#define setFlagOn(x, flag) (x |= (1u << flag))
|
#define setFlagOn(x, flag) (x |= (1u << flag))
|
||||||
@ -35,6 +37,7 @@ typedef struct CObj {
|
|||||||
bool isMarked; // for the GC
|
bool isMarked; // for the GC
|
||||||
struct CObj *next;
|
struct CObj *next;
|
||||||
struct CObj *nextRoot; // for the root linked list
|
struct CObj *nextRoot; // for the root linked list
|
||||||
|
struct CObjObject *proto; // protoobject, describes the behavior of the object
|
||||||
} CObj;
|
} CObj;
|
||||||
|
|
||||||
typedef struct CObjString {
|
typedef struct CObjString {
|
||||||
@ -62,7 +65,6 @@ typedef struct CObjObject {
|
|||||||
void *userP;
|
void *userP;
|
||||||
int userI;
|
int userI;
|
||||||
};
|
};
|
||||||
struct CObjObject *proto; // protoobject, describes the behavior of the object
|
|
||||||
} CObjObject;
|
} CObjObject;
|
||||||
|
|
||||||
typedef struct CObjDict { // dictionary, a wrapper for CTable
|
typedef struct CObjDict { // dictionary, a wrapper for CTable
|
||||||
@ -94,7 +96,7 @@ typedef struct CObjClosure {
|
|||||||
|
|
||||||
typedef struct CObjMethod {
|
typedef struct CObjMethod {
|
||||||
CommonHeader; // "is a " CObj
|
CommonHeader; // "is a " CObj
|
||||||
CObjObject *obj; // obj this method is bound too
|
CObj *obj; // obj this method is bound too
|
||||||
CValue func;
|
CValue func;
|
||||||
} CObjMethod;
|
} CObjMethod;
|
||||||
|
|
||||||
@ -141,12 +143,21 @@ CObjDict *cosmoO_newDictionary(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);
|
||||||
CObjMethod *cosmoO_newMethod(CState *state, CObjClosure *func, CObjObject *obj);
|
CObjMethod *cosmoO_newMethod(CState *state, CValue func, CObj *obj);
|
||||||
CObjMethod *cosmoO_newCMethod(CState *state, CObjCFunction *func, CObjObject *obj);
|
|
||||||
CObjClosure *cosmoO_newClosure(CState *state, CObjFunction *func);
|
CObjClosure *cosmoO_newClosure(CState *state, CObjFunction *func);
|
||||||
CObjString *cosmoO_toString(CState *state, CObj *val);
|
CObjString *cosmoO_toString(CState *state, CObj *val);
|
||||||
CObjUpval *cosmoO_newUpvalue(CState *state, CValue *val);
|
CObjUpval *cosmoO_newUpvalue(CState *state, CValue *val);
|
||||||
|
|
||||||
|
// grabs the base proto of the CObj* (if CObj is a CObjObject, that is returned)
|
||||||
|
static inline CObjObject *cosmoO_grabProto(CObj *obj) {
|
||||||
|
CObjObject *object = obj->proto;
|
||||||
|
|
||||||
|
if (obj->type == COBJ_OBJECT)
|
||||||
|
object = (CObjObject*)obj;
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
bool cosmoO_getRawObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
bool cosmoO_getRawObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
||||||
void cosmoO_setRawObject(CState *state, CObjObject *object, CValue key, CValue val);
|
void cosmoO_setRawObject(CState *state, CObjObject *object, CValue key, CValue val);
|
||||||
bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
||||||
|
@ -1357,7 +1357,7 @@ static void forLoop(CParseState *pstate) {
|
|||||||
startLoop(pstate);
|
startLoop(pstate);
|
||||||
|
|
||||||
int iteratorStart = getChunk(pstate)->count;
|
int iteratorStart = getChunk(pstate)->count;
|
||||||
expression(pstate, 0, true);
|
expressionPrecedence(pstate, 0, PREC_ASSIGNMENT, true); // any expression (including assignment)
|
||||||
consume(pstate, TOKEN_RIGHT_PAREN, "Expected ')' after iterator");
|
consume(pstate, TOKEN_RIGHT_PAREN, "Expected ')' after iterator");
|
||||||
|
|
||||||
writeJmpBack(pstate, loopStart);
|
writeJmpBack(pstate, loopStart);
|
||||||
|
@ -32,7 +32,6 @@ CState *cosmoV_newState() {
|
|||||||
state->frameCount = 0;
|
state->frameCount = 0;
|
||||||
state->openUpvalues = NULL;
|
state->openUpvalues = NULL;
|
||||||
|
|
||||||
state->protoObj = NULL;
|
|
||||||
state->error = NULL;
|
state->error = NULL;
|
||||||
|
|
||||||
cosmoT_initTable(state, &state->strings, 8); // init string table
|
cosmoT_initTable(state, &state->strings, 8); // init string table
|
||||||
@ -63,6 +62,10 @@ CState *cosmoV_newState() {
|
|||||||
for (int i = 0; i < ISTRING_MAX; i++)
|
for (int i = 0; i < ISTRING_MAX; i++)
|
||||||
state->iStrings[i]->isIString = true;
|
state->iStrings[i]->isIString = true;
|
||||||
|
|
||||||
|
// set default proto objects
|
||||||
|
for (int i = 0; i < COBJ_MAX; i++)
|
||||||
|
state->protoObjects[i] = NULL;
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#define CSTATE_H
|
#define CSTATE_H
|
||||||
|
|
||||||
#include "cosmo.h"
|
#include "cosmo.h"
|
||||||
#include "cvalue.h"
|
|
||||||
#include "cobj.h"
|
#include "cobj.h"
|
||||||
|
#include "cvalue.h"
|
||||||
#include "ctable.h"
|
#include "ctable.h"
|
||||||
|
|
||||||
typedef struct CCallFrame {
|
typedef struct CCallFrame {
|
||||||
@ -36,7 +36,6 @@ typedef struct CState {
|
|||||||
int freezeGC; // when > 0, GC events will be ignored (for internal use)
|
int freezeGC; // when > 0, GC events will be ignored (for internal use)
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
CObjObject *protoObj; // start met obj for all objects (NULL by default)
|
|
||||||
CObjError *error; // NULL, unless panic is true
|
CObjError *error; // NULL, unless panic is true
|
||||||
CObj *objects; // tracks all of our allocated objects
|
CObj *objects; // tracks all of our allocated objects
|
||||||
CObj *userRoots; // user definable roots, this holds CObjs that should be considered "roots", lets the VM know you are holding a reference to a CObj in your code
|
CObj *userRoots; // user definable roots, this holds CObjs that should be considered "roots", lets the VM know you are holding a reference to a CObj in your code
|
||||||
@ -49,6 +48,7 @@ typedef struct CState {
|
|||||||
CTable globals;
|
CTable globals;
|
||||||
|
|
||||||
CValue *top; // top of the stack
|
CValue *top; // top of the stack
|
||||||
|
CObjObject *protoObjects[COBJ_MAX]; // proto object for each COBJ type [NULL = no default proto]
|
||||||
CObjString *iStrings[ISTRING_MAX]; // strings used internally by the VM, eg. __init, __index & friends
|
CObjString *iStrings[ISTRING_MAX]; // strings used internally by the VM, eg. __init, __index & friends
|
||||||
CCallFrame callFrame[FRAME_MAX]; // call frames
|
CCallFrame callFrame[FRAME_MAX]; // call frames
|
||||||
CValue stack[STACK_MAX]; // stack
|
CValue stack[STACK_MAX]; // stack
|
||||||
|
185
src/cvm.c
185
src/cvm.c
@ -173,7 +173,7 @@ void cosmoV_concat(CState *state, int vals) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cosmoV_execute(CState *state);
|
int cosmoV_execute(CState *state);
|
||||||
bool invokeMethod(CState* state, CObjObject *obj, CValue func, int args, int nresults, int offset);
|
bool invokeMethod(CState* state, CObj *obj, CValue func, int args, int nresults, int offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
calls a native C Function with # args on the stack, nresults are pushed onto the stack upon return.
|
calls a native C Function with # args on the stack, nresults are pushed onto the stack upon return.
|
||||||
@ -293,12 +293,12 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
|||||||
case COBJ_OBJECT: { // object is being instantiated, making another object
|
case COBJ_OBJECT: { // object is being instantiated, making another object
|
||||||
CObjObject *protoObj = (CObjObject*)cosmoV_readObj(func);
|
CObjObject *protoObj = (CObjObject*)cosmoV_readObj(func);
|
||||||
CObjObject *newObj = cosmoO_newObject(state);
|
CObjObject *newObj = cosmoO_newObject(state);
|
||||||
newObj->proto = protoObj;
|
newObj->_obj.proto = protoObj;
|
||||||
CValue ret;
|
CValue ret;
|
||||||
|
|
||||||
// check if they defined an initializer (we accept 0 return values)
|
// check if they defined an initializer (we accept 0 return values)
|
||||||
if (cosmoO_getIString(state, protoObj, ISTRING_INIT, &ret)) {
|
if (cosmoO_getIString(state, protoObj, ISTRING_INIT, &ret)) {
|
||||||
if (!invokeMethod(state, newObj, ret, args, 0, offset + 1))
|
if (!invokeMethod(state, (CObj*)newObj, ret, args, 0, offset + 1))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// no default initializer
|
// no default initializer
|
||||||
@ -324,7 +324,7 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool invokeMethod(CState* state, CObjObject *obj, CValue func, int args, int nresults, int offset) {
|
bool invokeMethod(CState* state, CObj *obj, CValue func, int args, int nresults, int offset) {
|
||||||
// first, set the first argument to the object
|
// first, set the first argument to the object
|
||||||
StkPtr temp = cosmoV_getTop(state, args);
|
StkPtr temp = cosmoV_getTop(state, args);
|
||||||
*temp = cosmoV_newObj(obj);
|
*temp = cosmoV_newObj(obj);
|
||||||
@ -409,27 +409,46 @@ COSMO_API void cosmoV_makeDictionary(CState *state, int pairs) {
|
|||||||
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
||||||
}
|
}
|
||||||
|
|
||||||
COSMO_API bool cosmoV_getObject(CState *state, CObjObject *object, CValue key, CValue *val) {
|
COSMO_API bool cosmoV_get(CState *state, CObj *_obj, CValue key, CValue *val) {
|
||||||
|
CObjObject *object = cosmoO_grabProto(_obj);
|
||||||
|
|
||||||
|
// no proto to get from
|
||||||
|
if (object == NULL) {
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't get from type %s", cosmoO_typeStr(_obj));
|
||||||
|
*val = cosmoV_newNil();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(object));
|
cosmoV_pushValue(state, cosmoV_newObj(object));
|
||||||
|
|
||||||
if (cosmoO_getRawObject(state, object, key, val)) {
|
if (cosmoO_getRawObject(state, object, key, val)) {
|
||||||
if (IS_OBJ(*val)) {
|
// is it a function? if so, make it a method to the current object
|
||||||
if (cosmoV_readObj(*val)->type == COBJ_CLOSURE) { // is it a function? if so, make it a method to the current object
|
if (IS_OBJ(*val) && (cosmoV_readObj(*val)->type == COBJ_CLOSURE || cosmoV_readObj(*val)->type == COBJ_CFUNCTION)) {
|
||||||
CObjMethod *method = cosmoO_newMethod(state, (CObjClosure*)cosmoV_readObj(*val), object);
|
CObjMethod *method = cosmoO_newMethod(state, *val, _obj);
|
||||||
*val = cosmoV_newObj(method);
|
|
||||||
} else if (cosmoV_readObj(*val)->type == COBJ_CFUNCTION) {
|
|
||||||
CObjMethod *method = cosmoO_newCMethod(state, (CObjCFunction*)cosmoV_readObj(*val), object);
|
|
||||||
*val = cosmoV_newObj(method);
|
*val = cosmoV_newObj(method);
|
||||||
} // else, just pass the raw object
|
} // else, just pass the raw object
|
||||||
}
|
|
||||||
|
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
COSMO_API bool cosmoV_set(CState *state, CObj *_obj, CValue key, CValue val) {
|
||||||
|
CObjObject *object = cosmoO_grabProto(_obj);
|
||||||
|
|
||||||
|
// no proto to set to
|
||||||
|
if (object == NULL) {
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't set to type %s", cosmoO_typeStr(_obj));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cosmoO_setRawObject(state, object, key, val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int _dict__next(CState *state, int nargs, CValue *args) {
|
int _dict__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);
|
||||||
@ -615,17 +634,19 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoT_get(&dict->tbl, *key, &val);
|
cosmoT_get(&dict->tbl, *key, &val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: { // check for __index
|
default: { // check for __index metamethod
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
CObjObject *object = cosmoO_grabProto(cosmoV_readObj(*temp));
|
||||||
|
|
||||||
|
if (object == NULL) {
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't __index from type %s", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!cosmoO_indexObject(state, object, *key, &val)) // if returns false, cosmoV_error was called
|
if (!cosmoO_indexObject(state, object, *key, &val)) // if returns false, cosmoV_error was called
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
cosmoV_error(state, "Couldn't index type %s!", cosmoV_typeStr(*temp));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_setTop(state, 2); // pops the object & the key
|
cosmoV_setTop(state, 2); // pops the object & the key
|
||||||
@ -651,17 +672,19 @@ int cosmoV_execute(CState *state) {
|
|||||||
*newVal = *value; // set the index
|
*newVal = *value; // set the index
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: { // check for __newindex
|
default: { // check for __newindex
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
CObjObject *object = cosmoO_grabProto(cosmoV_readObj(*temp));
|
||||||
|
|
||||||
|
if (object == NULL) {
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't __newindex from type %s", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!cosmoO_newIndexObject(state, object, *key, *value)) // if it returns false, cosmoV_error was called
|
if (!cosmoO_newIndexObject(state, object, *key, *value)) // if it returns false, cosmoV_error was called
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
cosmoV_error(state, "Couldn't set index with type %s!", cosmoV_typeStr(*temp));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop everything off the stack
|
// pop everything off the stack
|
||||||
@ -692,14 +715,8 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoT_get(&dict->tbl, constants[ident], &val);
|
cosmoT_get(&dict->tbl, constants[ident], &val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: {
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
|
||||||
|
|
||||||
cosmoV_getObject(state, object, constants[ident], &val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
cosmoV_error(state, "Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
if (!cosmoV_get(state, cosmoV_readObj(*temp), constants[ident], &val))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -726,14 +743,8 @@ int cosmoV_execute(CState *state) {
|
|||||||
*newVal = *value; // set the index
|
*newVal = *value; // set the index
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: {
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
|
||||||
|
|
||||||
cosmoO_setRawObject(state, object, constants[ident], *value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
cosmoV_error(state, "Couldn't set a field on type %s!", cosmoV_typeStr(*temp));
|
if (!cosmoV_set(state, cosmoV_readObj(*temp), constants[ident], *value))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -765,18 +776,20 @@ int cosmoV_execute(CState *state) {
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: {
|
default: {
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
CObjObject *object = cosmoO_grabProto(cosmoV_readObj(*temp));
|
||||||
|
|
||||||
cosmoO_getRawObject(state, object, *key, &val); // we use cosmoO_getRawObject instead of the cosmoV_getObject wrapper so we get the raw value from the object instead of the CObjMethod wrapper
|
if (object == NULL) {
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cosmoO_getRawObject(state, object, *key, &val); // we use cosmoO_getRawObject instead of the wrapper so we get the raw value from the object instead of the CObjMethod wrapper
|
||||||
|
|
||||||
// now invoke the method!
|
// now invoke the method!
|
||||||
invokeMethod(state, object, val, args, nres, 0);
|
invokeMethod(state, cosmoV_readObj(*temp), val, args, nres, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
cosmoV_error(state, "Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
||||||
@ -793,9 +806,10 @@ int cosmoV_execute(CState *state) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
CObj *obj = cosmoV_readObj(*temp);
|
||||||
|
switch (obj->type) {
|
||||||
case COBJ_DICT: {
|
case COBJ_DICT: {
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjDict *dict = (CObjDict*)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(dict)); // value
|
||||||
@ -810,18 +824,23 @@ 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_newCMethod(state, dict_next, obj);
|
CObjMethod *method = cosmoO_newMethod(state, cosmoV_newObj(dict_next), (CObj*)obj);
|
||||||
|
|
||||||
cosmoV_setTop(state, 2); // pops the object & the dict
|
cosmoV_setTop(state, 2); // pops the object & the dict
|
||||||
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;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: {
|
default: {
|
||||||
CObjObject *obj = cosmoV_readObject(*temp);
|
CObjObject *object = cosmoO_grabProto(obj);
|
||||||
CValue val;
|
CValue val;
|
||||||
|
|
||||||
|
if (object == NULL) {
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't get from type %s", cosmoO_typeStr(obj));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// grab __iter & call it
|
// grab __iter & call it
|
||||||
if (cosmoO_getIString(state, obj, ISTRING_ITER, &val)) {
|
if (cosmoO_getIString(state, object, ISTRING_ITER, &val)) {
|
||||||
cosmoV_pop(state); // pop the object from the stack
|
cosmoV_pop(state); // pop the object from the stack
|
||||||
cosmoV_pushValue(state, val);
|
cosmoV_pushValue(state, val);
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(obj));
|
cosmoV_pushValue(state, cosmoV_newObj(obj));
|
||||||
@ -831,13 +850,12 @@ int cosmoV_execute(CState *state) {
|
|||||||
StkPtr iObj = cosmoV_getTop(state, 0);
|
StkPtr iObj = cosmoV_getTop(state, 0);
|
||||||
|
|
||||||
if (!IS_OBJECT(*iObj)) {
|
if (!IS_OBJECT(*iObj)) {
|
||||||
cosmoV_error(state, "Expected iterable object! '__iter' returned %s, expected object!", cosmoV_typeStr(*iObj));
|
cosmoV_error(state, "Expected iterable object! '__iter' returned %s, expected <object>!", cosmoV_typeStr(*iObj));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjObject *obj = (CObjObject*)cosmoV_readObj(*iObj);
|
// get __next method and place it at the top of the stack
|
||||||
|
cosmoV_get(state, cosmoV_readObj(*iObj), cosmoV_newObj(state->iStrings[ISTRING_NEXT]), iObj);
|
||||||
cosmoV_getObject(state, obj, cosmoV_newObj(state->iStrings[ISTRING_NEXT]), iObj);
|
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected iterable object! '__iter' not defined!");
|
cosmoV_error(state, "Expected iterable object! '__iter' not defined!");
|
||||||
return -1;
|
return -1;
|
||||||
@ -845,9 +863,6 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
cosmoV_error(state, "Couldn't iterate over non-iterator type %s!", cosmoV_typeStr(*temp));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1005,27 +1020,32 @@ int cosmoV_execute(CState *state) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: {
|
default: {
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
CObjObject *object = cosmoO_grabProto(cosmoV_readObj(*temp));
|
||||||
CValue val;
|
CValue val;
|
||||||
|
|
||||||
|
if (object == NULL) {
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't __index from type %s", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// call __index
|
// call __index
|
||||||
if (cosmoO_indexObject(state, object, *key, &val)) {
|
if (cosmoO_indexObject(state, object, *key, &val)) {
|
||||||
if (IS_NUMBER(val)) {
|
if (IS_NUMBER(val)) {
|
||||||
cosmoV_pushValue(state, val); // pushes old value onto the stack :)
|
cosmoV_pushValue(state, val); // pushes old value onto the stack :)
|
||||||
|
|
||||||
// call __newindex
|
// call __newindex
|
||||||
cosmoO_newIndexObject(state, object, *key, cosmoV_newNumber(cosmoV_readNumber(val) + inc));
|
if (!cosmoO_newIndexObject(state, object, *key, cosmoV_newNumber(cosmoV_readNumber(val) + inc)))
|
||||||
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
cosmoV_error(state, "Couldn't set index with type %s!", cosmoV_typeStr(*temp));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Couldn't set index with type %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Couldn't set index with type %s!", cosmoV_typeStr(*temp));
|
||||||
@ -1043,25 +1063,6 @@ 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_OBJECT: {
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
|
||||||
CValue val;
|
|
||||||
|
|
||||||
cosmoO_getRawObject(state, object, ident, &val);
|
|
||||||
|
|
||||||
// pop the object off the stack
|
|
||||||
cosmoV_pop(state);
|
|
||||||
|
|
||||||
// check that it's a number value
|
|
||||||
if (IS_NUMBER(val)) {
|
|
||||||
cosmoV_pushValue(state, val); // pushes old value onto the stack :)
|
|
||||||
cosmoO_setRawObject(state, object, ident, cosmoV_newNumber(cosmoV_readNumber(val) + inc));
|
|
||||||
} else {
|
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COBJ_DICT: {
|
case COBJ_DICT: {
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
||||||
CValue *val = cosmoT_insert(state, &dict->tbl, ident);
|
CValue *val = cosmoT_insert(state, &dict->tbl, ident);
|
||||||
@ -1078,9 +1079,27 @@ int cosmoV_execute(CState *state) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
cosmoV_error(state, "Couldn't set a field on type %s!", cosmoV_typeStr(*temp));
|
CObj *obj = cosmoV_readObj(*temp);
|
||||||
|
CValue val;
|
||||||
|
|
||||||
|
if (!cosmoV_get(state, obj, ident, &val))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
// pop the object off the stack
|
||||||
|
cosmoV_pop(state);
|
||||||
|
|
||||||
|
// check that it's a number value
|
||||||
|
if (IS_NUMBER(val)) {
|
||||||
|
cosmoV_pushValue(state, val); // pushes old value onto the stack :)
|
||||||
|
if (!cosmoV_set(state, obj, ident, cosmoV_newNumber(cosmoV_readNumber(val) + inc)))
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Couldn't set a field on type %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Couldn't set a field on type %s!", cosmoV_typeStr(*temp));
|
||||||
|
@ -17,7 +17,6 @@ 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_makeDictionary(CState *state, int pairs);
|
||||||
COSMO_API bool cosmoV_getObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
|
||||||
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);
|
||||||
@ -25,6 +24,9 @@ COSMO_API CObjError* cosmoV_throw(CState *state);
|
|||||||
COSMO_API void cosmoV_error(CState *state, const char *format, ...);
|
COSMO_API void cosmoV_error(CState *state, const char *format, ...);
|
||||||
COSMO_API void cosmo_insert(CState *state, int indx, CValue val);
|
COSMO_API void cosmo_insert(CState *state, int indx, CValue val);
|
||||||
|
|
||||||
|
COSMO_API bool cosmoV_get(CState *state, CObj *obj, CValue key, CValue *val);
|
||||||
|
COSMO_API bool cosmoV_set(CState *state, CObj *obj, CValue key, CValue val);
|
||||||
|
|
||||||
// nice to have wrappers
|
// nice to have wrappers
|
||||||
|
|
||||||
// pushes value to the stack
|
// pushes value to the stack
|
||||||
|
Loading…
Reference in New Issue
Block a user