mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 00:00:10 +00:00
Added .
get/set support for dictionaries.
cosmoO_getObject and cosmoO_setObject were renamed to cosmoV_getRawObject and cosmoV_setRawObject respectively `__init` is now required to be defined for a proto object to be instantiated. other minor refactoring work done in src/cvm.c
This commit is contained in:
parent
9012f9231b
commit
e993cdd9fa
@ -1,5 +1,7 @@
|
|||||||
// crafts a dummy proto
|
// crafts a dummy proto
|
||||||
proto test end
|
proto test
|
||||||
|
function __init(self) end
|
||||||
|
end
|
||||||
|
|
||||||
// instance of test
|
// instance of test
|
||||||
var obj = test()
|
var obj = test()
|
||||||
|
10
src/cobj.c
10
src/cobj.c
@ -265,9 +265,9 @@ CObjString *cosmoO_pushVFString(CState *state, const char *format, va_list args)
|
|||||||
return cosmoV_readString(*start); // start should be state->top - 1
|
return cosmoV_readString(*start); // start should be state->top - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cosmoO_getObject(CState *state, CObjObject *object, CValue key, CValue *val) {
|
bool cosmoO_getRawObject(CState *state, CObjObject *object, CValue key, CValue *val) {
|
||||||
if (!cosmoT_get(&object->tbl, key, val)) { // if the field doesn't exist in the object, check the proto
|
if (!cosmoT_get(&object->tbl, key, val)) { // if the field doesn't exist in the object, check the proto
|
||||||
if (cosmoO_getIString(state, object, ISTRING_GETTER, val) && IS_OBJECT(*val) && cosmoO_getObject(state, cosmoV_readObject(*val), key, val)) {
|
if (cosmoO_getIString(state, object, ISTRING_GETTER, val) && IS_OBJECT(*val) && cosmoO_getRawObject(state, cosmoV_readObject(*val), key, val)) {
|
||||||
cosmoV_pushValue(state, *val); // push function
|
cosmoV_pushValue(state, *val); // push function
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(object)); // push object
|
cosmoV_pushValue(state, cosmoV_newObj(object)); // push object
|
||||||
cosmoV_call(state, 1, 1); // call the function with the 1 argument
|
cosmoV_call(state, 1, 1); // call the function with the 1 argument
|
||||||
@ -275,7 +275,7 @@ bool cosmoO_getObject(CState *state, CObjObject *object, CValue key, CValue *val
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object->proto != NULL && cosmoO_getObject(state, object->proto, key, val))
|
if (object->proto != NULL && cosmoO_getRawObject(state, object->proto, key, val))
|
||||||
return true;
|
return true;
|
||||||
return false; // no protoobject to check against / key not found
|
return false; // no protoobject to check against / key not found
|
||||||
}
|
}
|
||||||
@ -283,11 +283,11 @@ bool cosmoO_getObject(CState *state, CObjObject *object, CValue key, CValue *val
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cosmoO_setObject(CState *state, CObjObject *object, CValue key, CValue val) {
|
void cosmoO_setRawObject(CState *state, CObjObject *object, CValue key, CValue val) {
|
||||||
CValue ret;
|
CValue ret;
|
||||||
|
|
||||||
// first check for __setters
|
// first check for __setters
|
||||||
if (cosmoO_getIString(state, object, ISTRING_SETTER, &ret) && IS_OBJECT(ret) && cosmoO_getObject(state, cosmoV_readObject(ret), key, &ret)) {
|
if (cosmoO_getIString(state, object, ISTRING_SETTER, &ret) && IS_OBJECT(ret) && cosmoO_getRawObject(state, cosmoV_readObject(ret), key, &ret)) {
|
||||||
cosmoV_pushValue(state, ret); // push function
|
cosmoV_pushValue(state, ret); // push function
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(object)); // push object
|
cosmoV_pushValue(state, cosmoV_newObj(object)); // push object
|
||||||
cosmoV_pushValue(state, val); // push new value
|
cosmoV_pushValue(state, val); // push new value
|
||||||
|
@ -135,8 +135,8 @@ 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);
|
||||||
|
|
||||||
bool cosmoO_getObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
bool cosmoO_getRawObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
||||||
void cosmoO_setObject(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);
|
||||||
bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val);
|
bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val);
|
||||||
|
|
||||||
|
202
src/cvm.c
202
src/cvm.c
@ -180,7 +180,6 @@ bool call(CState *state, CObjClosure *closure, int args, int nresults, int offse
|
|||||||
// load function into callframe
|
// load function into callframe
|
||||||
pushCallFrame(state, closure, func->args);
|
pushCallFrame(state, closure, func->args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
int nres = cosmoV_execute(state);
|
int nres = cosmoV_execute(state);
|
||||||
@ -256,10 +255,8 @@ COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults) {
|
|||||||
invokeMethod(state, newObj, ret, args, nresults, 1);
|
invokeMethod(state, newObj, ret, args, nresults, 1);
|
||||||
} else {
|
} else {
|
||||||
// no default initializer
|
// no default initializer
|
||||||
if (args != 0) {
|
cosmoV_error(state, "Expected __init() in proto, object cannot be instantiated!");
|
||||||
cosmoV_error(state, "Expected 0 parameters, got %d!", args);
|
return 0;
|
||||||
return COSMOVM_RUNTIME_ERR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pop(state); // pops the return value, it's unused
|
cosmoV_pop(state); // pops the return value, it's unused
|
||||||
@ -273,7 +270,7 @@ COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
cosmoV_error(state, "Cannot call non-function value!");
|
cosmoV_error(state, "Cannot call non-function value %s!", cosmoV_typeStr(*val));
|
||||||
return COSMOVM_RUNTIME_ERR;
|
return COSMOVM_RUNTIME_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +321,7 @@ COSMO_API void cosmoV_makeDictionary(CState *state, int pairs) {
|
|||||||
|
|
||||||
COSMO_API bool cosmoV_getObject(CState *state, CObjObject *object, CValue key, CValue *val) {
|
COSMO_API bool cosmoV_getObject(CState *state, CObjObject *object, CValue key, CValue *val) {
|
||||||
cosmoV_pushValue(state, cosmoV_newObj(object));
|
cosmoV_pushValue(state, cosmoV_newObj(object));
|
||||||
if (cosmoO_getObject(state, object, key, val)) {
|
if (cosmoO_getRawObject(state, object, key, val)) {
|
||||||
if (IS_OBJ(*val)) {
|
if (IS_OBJ(*val)) {
|
||||||
if (cosmoV_readObj(*val)->type == COBJ_CLOSURE) { // 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
|
||||||
CObjMethod *method = cosmoO_newMethod(state, (CObjClosure*)cosmoV_readObj(*val), object);
|
CObjMethod *method = cosmoO_newMethod(state, (CObjClosure*)cosmoV_readObj(*val), object);
|
||||||
@ -332,7 +329,7 @@ COSMO_API bool cosmoV_getObject(CState *state, CObjObject *object, CValue key, C
|
|||||||
} else if (cosmoV_readObj(*val)->type == COBJ_CFUNCTION) {
|
} else if (cosmoV_readObj(*val)->type == COBJ_CFUNCTION) {
|
||||||
CObjMethod *method = cosmoO_newCMethod(state, (CObjCFunction*)cosmoV_readObj(*val), object);
|
CObjMethod *method = cosmoO_newCMethod(state, (CObjCFunction*)cosmoV_readObj(*val), object);
|
||||||
*val = cosmoV_newObj(method);
|
*val = cosmoV_newObj(method);
|
||||||
}
|
} // else, just pass the raw object
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
@ -390,9 +387,10 @@ int _dict__next(CState *state, int nargs, CValue *args) {
|
|||||||
cosmoV_pushValue(state, typeConst(cosmoV_readNumber(*valA) op cosmoV_readNumber(*valB))); \
|
cosmoV_pushValue(state, typeConst(cosmoV_readNumber(*valA) op cosmoV_readNumber(*valB))); \
|
||||||
} else { \
|
} else { \
|
||||||
cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA), cosmoV_typeStr(*valB)); \
|
cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA), cosmoV_typeStr(*valB)); \
|
||||||
|
return -1; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
// returns false if panic
|
// returns -1 if panic
|
||||||
int cosmoV_execute(CState *state) {
|
int cosmoV_execute(CState *state) {
|
||||||
CCallFrame* frame = &state->callFrame[state->frameCount - 1]; // grabs the current frame
|
CCallFrame* frame = &state->callFrame[state->frameCount - 1]; // grabs the current frame
|
||||||
CValue *constants = frame->closure->function->chunk.constants.values; // cache the pointer :)
|
CValue *constants = frame->closure->function->chunk.constants.values; // cache the pointer :)
|
||||||
@ -521,17 +519,24 @@ int cosmoV_execute(CState *state) {
|
|||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
CValue val; // to hold our value
|
CValue val; // to hold our value
|
||||||
|
|
||||||
if (cosmoV_readObj(*temp)->type == COBJ_DICT) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
case COBJ_DICT: {
|
||||||
cosmoT_get(&dict->tbl, *key, &val);
|
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
||||||
} else if (cosmoV_readObj(*temp)->type == COBJ_OBJECT) { // check for __index!
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
|
||||||
|
|
||||||
if (!cosmoO_indexObject(state, object, *key, &val))
|
cosmoT_get(&dict->tbl, *key, &val);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
cosmoV_error(state, "Couldn't index type %s!", cosmoV_typeStr(*temp));
|
case COBJ_OBJECT: { // check for __index
|
||||||
break;
|
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
|
if (!cosmoO_indexObject(state, object, *key, &val)) // if returns false, cosmoV_error was called
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
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
|
||||||
@ -549,25 +554,32 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (IS_OBJ(*temp)) {
|
if (IS_OBJ(*temp)) {
|
||||||
if (cosmoV_readObj(*temp)->type == COBJ_DICT) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
case COBJ_DICT: { // index and set table
|
||||||
CValue *newVal = cosmoT_insert(state, &dict->tbl, *key);
|
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
||||||
|
CValue *newVal = cosmoT_insert(state, &dict->tbl, *key);
|
||||||
|
|
||||||
*newVal = *value; // set the index
|
*newVal = *value; // set the index
|
||||||
} else if (cosmoV_readObj(*temp)->type == COBJ_OBJECT) { // check for __newindex!
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
|
||||||
|
|
||||||
if (!cosmoO_newIndexObject(state, object, *key, *value))
|
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
cosmoV_error(state, "Couldn't set index with type %s!", cosmoV_typeStr(*temp));
|
case COBJ_OBJECT: { // check for __newindex
|
||||||
break;
|
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
|
if (!cosmoO_newIndexObject(state, object, *key, *value)) // if it returns false, cosmoV_error was called
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
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
|
||||||
cosmoV_setTop(state, 3);
|
cosmoV_setTop(state, 3);
|
||||||
} 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));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -578,19 +590,34 @@ int cosmoV_execute(CState *state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_GETOBJECT: {
|
case OP_GETOBJECT: {
|
||||||
|
CValue val; // to hold our value
|
||||||
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 object
|
StkPtr temp = cosmoV_getTop(state, 1); // after that should be the object
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_OBJECT) {
|
if (IS_OBJ(*temp)) {
|
||||||
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
|
case COBJ_DICT: { // syntax sugar, makes "namespaces" possible
|
||||||
|
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
|
cosmoT_get(&dict->tbl, *key, &val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COBJ_OBJECT: {
|
||||||
|
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
|
cosmoV_getObject(state, object, *key, &val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cosmoV_error(state, "Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} 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));
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
|
||||||
CValue val; // to hold our value
|
|
||||||
|
|
||||||
cosmoV_getObject(state, object, *key, &val);
|
|
||||||
cosmoV_setTop(state, 2); // pops the object & the key
|
cosmoV_setTop(state, 2); // pops the object & the key
|
||||||
cosmoV_pushValue(state, val); // pushes the field result
|
cosmoV_pushValue(state, val); // pushes the field result
|
||||||
break;
|
break;
|
||||||
@ -601,37 +628,78 @@ int cosmoV_execute(CState *state) {
|
|||||||
StkPtr temp = cosmoV_getTop(state, 2); // object is after the key
|
StkPtr temp = cosmoV_getTop(state, 2); // object is after the key
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_OBJECT) {
|
if (IS_OBJ(*temp)) {
|
||||||
cosmoV_error(state, "Couldn't set a field on type %s!", cosmoV_typeStr(*temp));
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
break;
|
case COBJ_DICT: { // index and set the table
|
||||||
}
|
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
||||||
|
CValue *newVal = cosmoT_insert(state, &dict->tbl, *key);
|
||||||
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
*newVal = *value; // set the index
|
||||||
cosmoO_setObject(state, object, *key, *value);
|
break;
|
||||||
|
}
|
||||||
|
case COBJ_OBJECT: {
|
||||||
|
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
|
cosmoO_setRawObject(state, object, *key, *value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cosmoV_error(state, "Couldn't set a field on type %s!", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cosmoV_error(state, "Couldn't set a field on type %s!", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// pop everything off the stack
|
// pop everything off the stack
|
||||||
cosmoV_setTop(state, 3);
|
cosmoV_setTop(state, 3);
|
||||||
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();
|
||||||
StkPtr key = cosmoV_getTop(state, args); // grabs key from stack
|
StkPtr key = cosmoV_getTop(state, args); // grabs key from stack
|
||||||
StkPtr temp = cosmoV_getTop(state, args+1); // grabs object from stack
|
StkPtr temp = cosmoV_getTop(state, args+1); // grabs object from stack
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_OBJECT) {
|
if (IS_OBJ(*temp)) {
|
||||||
cosmoV_error(state, "Couldn't get from non-object type %s!", cosmoV_typeStr(*temp));
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
break;
|
case COBJ_DICT: { // again, syntax sugar ("""""namespaces""""")
|
||||||
|
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
||||||
|
|
||||||
|
cosmoT_get(&dict->tbl, *key, &val);
|
||||||
|
|
||||||
|
// call closure/cfunction
|
||||||
|
if (IS_CFUNCTION(val)) {
|
||||||
|
callCFunction(state, cosmoV_readCFunction(val), args, nres, 0);
|
||||||
|
} else if (IS_CLOSURE(val)) {
|
||||||
|
call(state, cosmoV_readClosure(val), args, nres, 0);
|
||||||
|
} else {
|
||||||
|
cosmoV_error(state, "Cannot call non-function value %s!", cosmoV_typeStr(val));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COBJ_OBJECT: {
|
||||||
|
CObjObject *object = (CObjObject*)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
|
||||||
|
|
||||||
|
// now invoke the method!
|
||||||
|
invokeMethod(state, object, val, args, nres, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cosmoV_error(state, "Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cosmoV_error(state, "Couldn't get from type %s!", cosmoV_typeStr(*temp));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
|
||||||
CValue val; // to hold our value
|
|
||||||
|
|
||||||
cosmoO_getObject(state, object, *key, &val); // we use cosmoO_getObject instead of the cosmoV_getObject wrapper so we get the raw value from the object instead of the CObjMethod wrapper
|
|
||||||
|
|
||||||
// now invoke the method!
|
|
||||||
invokeMethod(state, object, val, args, nres, 0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_ITER: {
|
case OP_ITER: {
|
||||||
@ -639,7 +707,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
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));
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cosmoV_readObj(*temp)->type) {
|
switch (cosmoV_readObj(*temp)->type) {
|
||||||
@ -680,7 +748,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
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));
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjObject *obj = (CObjObject*)cosmoV_readObj(*iObj);
|
CObjObject *obj = (CObjObject*)cosmoV_readObj(*iObj);
|
||||||
@ -688,14 +756,14 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoV_getObject(state, obj, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
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));
|
||||||
break;
|
return -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -706,7 +774,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
if (!IS_METHOD(*temp)) {
|
if (!IS_METHOD(*temp)) {
|
||||||
cosmoV_error(state, "Expected '__next' to be a method, got type %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Expected '__next' to be a method, got type %s!", cosmoV_typeStr(*temp));
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pushValue(state, *temp);
|
cosmoV_pushValue(state, *temp);
|
||||||
@ -746,6 +814,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoV_pushNumber(state, -(cosmoV_readNumber(*val)));
|
cosmoV_pushNumber(state, -(cosmoV_readNumber(*val)));
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -754,7 +823,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_DICT) {
|
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_DICT) {
|
||||||
cosmoV_error(state, "Expected object, got %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Expected object, got %s!", cosmoV_typeStr(*temp));
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
CObjDict *dict = (CObjDict*)cosmoV_readObj(*temp);
|
||||||
@ -778,6 +847,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -794,6 +864,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -809,6 +880,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -831,7 +903,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
*val = cosmoV_newNumber(cosmoV_readNumber(*val) + inc);
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (cosmoV_readObj(*temp)->type == COBJ_OBJECT) { // check for __newindex!
|
} else if (cosmoV_readObj(*temp)->type == COBJ_OBJECT) { // check for __newindex!
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
||||||
@ -846,15 +918,16 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoO_newIndexObject(state, object, *key, cosmoV_newNumber(cosmoV_readNumber(val) + inc));
|
cosmoO_newIndexObject(state, object, *key, cosmoV_newNumber(cosmoV_readNumber(val) + inc));
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
||||||
break;
|
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));
|
||||||
break;
|
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));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -868,13 +941,13 @@ int cosmoV_execute(CState *state) {
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_OBJECT) {
|
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_OBJECT) {
|
||||||
cosmoV_error(state, "Couldn't set a field on non-object type %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Couldn't set a field on non-object type %s!", cosmoV_typeStr(*temp));
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
CObjObject *object = (CObjObject*)cosmoV_readObj(*temp);
|
||||||
CValue val;
|
CValue val;
|
||||||
|
|
||||||
cosmoO_getObject(state, object, ident, &val);
|
cosmoO_getRawObject(state, object, ident, &val);
|
||||||
|
|
||||||
// pop the object off the stack
|
// pop the object off the stack
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
@ -882,9 +955,10 @@ int cosmoV_execute(CState *state) {
|
|||||||
// check that it's a number value
|
// check that it's a number value
|
||||||
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 :)
|
||||||
cosmoO_setObject(state, object, ident, cosmoV_newNumber(cosmoV_readNumber(val) + inc));
|
cosmoO_setRawObject(state, object, ident, cosmoV_newNumber(cosmoV_readNumber(val) + inc));
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user