mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-21 23:10:05 +00:00
even more error handling refactoring
removing all of these useless checks has actually made cosmoV_execute just a lil bit faster :)
This commit is contained in:
parent
cc9eb4a5ec
commit
89be01aaf6
25
src/cobj.c
25
src/cobj.c
@ -397,7 +397,7 @@ bool cosmoO_isDescendant(CObj *obj, CObjObject *proto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns false if error thrown
|
// returns false if error thrown
|
||||||
bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj)
|
void cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj)
|
||||||
{
|
{
|
||||||
if (!cosmoT_get(state, &proto->tbl, key,
|
if (!cosmoT_get(state, &proto->tbl, key,
|
||||||
val)) { // if the field doesn't exist in the object, check the proto
|
val)) { // if the field doesn't exist in the object, check the proto
|
||||||
@ -407,18 +407,17 @@ bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *v
|
|||||||
cosmoV_pushRef(state, (CObj *)obj); // push object
|
cosmoV_pushRef(state, (CObj *)obj); // 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
|
||||||
*val = *cosmoV_pop(state); // set value to the return value of __index
|
*val = *cosmoV_pop(state); // set value to the return value of __index
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto->_obj.proto != NULL &&
|
// maybe the field is defined in the proto?
|
||||||
cosmoO_getRawObject(state, proto->_obj.proto, key, val, obj))
|
if (proto->_obj.proto != NULL) {
|
||||||
return true;
|
cosmoO_getRawObject(state, proto->_obj.proto, key, val, obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
*val = cosmoV_newNil();
|
*val = cosmoV_newNil();
|
||||||
return true; // no protoobject to check against / key not found
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj)
|
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj)
|
||||||
@ -519,7 +518,7 @@ bool cosmoO_getIString(CState *state, CObjObject *object, int flag, CValue *val)
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val)
|
void cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val)
|
||||||
{
|
{
|
||||||
if (cosmoO_getIString(state, object, ISTRING_INDEX, val)) {
|
if (cosmoO_getIString(state, object, ISTRING_INDEX, val)) {
|
||||||
cosmoV_pushValue(state, *val); // push function
|
cosmoV_pushValue(state, *val); // push function
|
||||||
@ -527,15 +526,12 @@ bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *v
|
|||||||
cosmoV_pushValue(state, key); // push key
|
cosmoV_pushValue(state, key); // push key
|
||||||
cosmoV_call(state, 2, 1); // call the function with the 2 arguments
|
cosmoV_call(state, 2, 1); // call the function with the 2 arguments
|
||||||
*val = *cosmoV_pop(state); // set value to the return value of __index
|
*val = *cosmoV_pop(state); // set value to the return value of __index
|
||||||
return true;
|
|
||||||
} else { // there's no __index function defined!
|
} else { // there's no __index function defined!
|
||||||
cosmoV_error(state, "Couldn't index object without __index function!");
|
cosmoV_error(state, "Couldn't index object without __index function!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val)
|
void cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val)
|
||||||
{
|
{
|
||||||
CValue ret; // return value for cosmoO_getIString
|
CValue ret; // return value for cosmoO_getIString
|
||||||
|
|
||||||
@ -545,12 +541,9 @@ bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue
|
|||||||
cosmoV_pushValue(state, key); // push key & value pair
|
cosmoV_pushValue(state, key); // push key & value pair
|
||||||
cosmoV_pushValue(state, val);
|
cosmoV_pushValue(state, val);
|
||||||
cosmoV_call(state, 3, 0);
|
cosmoV_call(state, 3, 0);
|
||||||
return true;
|
|
||||||
} else { // there's no __newindex function defined
|
} else { // there's no __newindex function defined
|
||||||
cosmoV_error(state, "Couldn't set index on object without __newindex function!");
|
cosmoV_error(state, "Couldn't set index on object without __newindex function!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjString *cosmoO_toString(CState *state, CObj *obj)
|
CObjString *cosmoO_toString(CState *state, CObj *obj)
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "cosmo.h"
|
#include "cosmo.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
typedef enum CObjType
|
typedef enum CObjType
|
||||||
{
|
{
|
||||||
COBJ_STRING,
|
COBJ_STRING,
|
||||||
@ -172,10 +174,10 @@ static inline CObjObject *cosmoO_grabProto(CObj *obj)
|
|||||||
return obj->type == COBJ_OBJECT ? (CObjObject *)obj : obj->proto;
|
return obj->type == COBJ_OBJECT ? (CObjObject *)obj : obj->proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj);
|
void cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj);
|
||||||
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj);
|
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj);
|
||||||
bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
void cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
||||||
bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val);
|
void cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val);
|
||||||
|
|
||||||
// sets the user-defined pointer, if a user-define integer is already defined it will be over
|
// sets the user-defined pointer, if a user-define integer is already defined it will be over
|
||||||
// written
|
// written
|
||||||
|
101
src/cvm.c
101
src/cvm.c
@ -497,7 +497,7 @@ COSMO_API void cosmoV_makeTable(CState *state, int pairs)
|
|||||||
cosmoV_pushRef(state, (CObj *)newObj);
|
cosmoV_pushRef(state, (CObj *)newObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cosmoV_rawget(CState *state, CObj *_obj, CValue key, CValue *val)
|
void cosmoV_rawget(CState *state, CObj *_obj, CValue key, CValue *val)
|
||||||
{
|
{
|
||||||
CObjObject *object = cosmoO_grabProto(_obj);
|
CObjObject *object = cosmoO_grabProto(_obj);
|
||||||
|
|
||||||
@ -506,23 +506,16 @@ bool cosmoV_rawget(CState *state, CObj *_obj, CValue key, CValue *val)
|
|||||||
CObjString *field = cosmoV_toString(state, key);
|
CObjString *field = cosmoV_toString(state, key);
|
||||||
cosmoV_error(state, "No proto defined! Couldn't get field '%s' from type %s", field->str,
|
cosmoV_error(state, "No proto defined! Couldn't get field '%s' from type %s", field->str,
|
||||||
cosmoO_typeStr(_obj));
|
cosmoO_typeStr(_obj));
|
||||||
*val = cosmoV_newNil();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// push the object onto the stack so the GC can find it
|
// push the object onto the stack so the GC can find it
|
||||||
cosmoV_pushRef(state, (CObj *)object);
|
cosmoV_pushRef(state, (CObj *)object);
|
||||||
if (cosmoO_getRawObject(state, object, key, val, _obj)) {
|
cosmoO_getRawObject(state, object, key, val, _obj);
|
||||||
// *val now equals the response, pop the object
|
|
||||||
cosmoV_pop(state);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cosmoV_rawset(CState *state, CObj *_obj, CValue key, CValue val)
|
void cosmoV_rawset(CState *state, CObj *_obj, CValue key, CValue val)
|
||||||
{
|
{
|
||||||
CObjObject *object = cosmoO_grabProto(_obj);
|
CObjObject *object = cosmoO_grabProto(_obj);
|
||||||
|
|
||||||
@ -531,14 +524,12 @@ bool cosmoV_rawset(CState *state, CObj *_obj, CValue key, CValue val)
|
|||||||
CObjString *field = cosmoV_toString(state, key);
|
CObjString *field = cosmoV_toString(state, key);
|
||||||
cosmoV_error(state, "No proto defined! Couldn't set field '%s' to type %s", field->str,
|
cosmoV_error(state, "No proto defined! Couldn't set field '%s' to type %s", field->str,
|
||||||
cosmoO_typeStr(_obj));
|
cosmoO_typeStr(_obj));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoO_setRawObject(state, object, key, val, _obj);
|
cosmoO_setRawObject(state, object, key, val, _obj);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COSMO_API bool cosmoV_get(CState *state)
|
COSMO_API void cosmoV_get(CState *state)
|
||||||
{
|
{
|
||||||
CValue val;
|
CValue val;
|
||||||
StkPtr obj = cosmoV_getTop(state, 1); // object was pushed first
|
StkPtr obj = cosmoV_getTop(state, 1); // object was pushed first
|
||||||
@ -546,20 +537,17 @@ COSMO_API bool cosmoV_get(CState *state)
|
|||||||
|
|
||||||
if (!IS_REF(*obj)) {
|
if (!IS_REF(*obj)) {
|
||||||
cosmoV_error(state, "Couldn't get field from type %s!", cosmoV_typeStr(*obj));
|
cosmoV_error(state, "Couldn't get field from type %s!", cosmoV_typeStr(*obj));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cosmoV_rawget(state, cosmoV_readRef(*obj), *key, &val))
|
cosmoV_rawget(state, cosmoV_readRef(*obj), *key, &val);
|
||||||
return false;
|
|
||||||
|
|
||||||
// pop the obj & key, push the value
|
// pop the obj & key, push the value
|
||||||
cosmoV_setTop(state, 2);
|
cosmoV_setTop(state, 2);
|
||||||
cosmoV_pushValue(state, val);
|
cosmoV_pushValue(state, val);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// yes, this would technically make it possible to set fields of types other than <string>. go crazy
|
// yes, this would technically make it possible to set fields of types other than <string>. go crazy
|
||||||
COSMO_API bool cosmoV_set(CState *state)
|
COSMO_API void cosmoV_set(CState *state)
|
||||||
{
|
{
|
||||||
StkPtr obj = cosmoV_getTop(state, 2); // object was pushed first
|
StkPtr obj = cosmoV_getTop(state, 2); // object was pushed first
|
||||||
StkPtr key = cosmoV_getTop(state, 1); // then the key
|
StkPtr key = cosmoV_getTop(state, 1); // then the key
|
||||||
@ -567,21 +555,17 @@ COSMO_API bool cosmoV_set(CState *state)
|
|||||||
|
|
||||||
if (!IS_REF(*obj)) {
|
if (!IS_REF(*obj)) {
|
||||||
cosmoV_error(state, "Couldn't set field on type %s!", cosmoV_typeStr(*obj));
|
cosmoV_error(state, "Couldn't set field on type %s!", cosmoV_typeStr(*obj));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cosmoV_rawset(state, cosmoV_readRef(*obj), *key, *val))
|
cosmoV_rawset(state, cosmoV_readRef(*obj), *key, *val);
|
||||||
return false;
|
|
||||||
|
|
||||||
// pop the obj, key & value
|
// pop the obj, key & value
|
||||||
cosmoV_setTop(state, 3);
|
cosmoV_setTop(state, 3);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COSMO_API bool cosmoV_getMethod(CState *state, CObj *obj, CValue key, CValue *val)
|
COSMO_API void cosmoV_getMethod(CState *state, CObj *obj, CValue key, CValue *val)
|
||||||
{
|
{
|
||||||
if (!cosmoV_rawget(state, obj, key, val))
|
cosmoV_rawget(state, obj, key, val);
|
||||||
return false;
|
|
||||||
|
|
||||||
// if the result is callable, wrap it in an method
|
// if the result is callable, wrap it in an method
|
||||||
if (IS_CALLABLE(*val)) {
|
if (IS_CALLABLE(*val)) {
|
||||||
@ -591,8 +575,6 @@ COSMO_API bool cosmoV_getMethod(CState *state, CObj *obj, CValue key, CValue *va
|
|||||||
cosmoV_pop(state); // pop the object
|
cosmoV_pop(state); // pop the object
|
||||||
*val = cosmoV_newRef(method);
|
*val = cosmoV_newRef(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _tbl__next(CState *state, int nargs, CValue *args)
|
int _tbl__next(CState *state, int nargs, CValue *args)
|
||||||
@ -849,7 +831,6 @@ int cosmoV_execute(CState *state)
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (!IS_REF(*temp)) {
|
if (!IS_REF(*temp)) {
|
||||||
cosmoV_error(state, "Couldn't index type %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Couldn't index type %s!", cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObj *obj = cosmoV_readRef(*temp);
|
CObj *obj = cosmoV_readRef(*temp);
|
||||||
@ -858,9 +839,7 @@ int cosmoV_execute(CState *state)
|
|||||||
|
|
||||||
if (proto != NULL) {
|
if (proto != NULL) {
|
||||||
// check for __index metamethod
|
// check for __index metamethod
|
||||||
if (!cosmoO_indexObject(state, proto, *key,
|
cosmoO_indexObject(state, proto, *key, &val);
|
||||||
&val)) // if returns false, cosmoV_error was called
|
|
||||||
return -1;
|
|
||||||
} else if (obj->type == COBJ_TABLE) {
|
} else if (obj->type == COBJ_TABLE) {
|
||||||
CObjTable *tbl = (CObjTable *)obj;
|
CObjTable *tbl = (CObjTable *)obj;
|
||||||
|
|
||||||
@ -868,7 +847,6 @@ int cosmoV_execute(CState *state)
|
|||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "No proto defined! Couldn't __index from type %s",
|
cosmoV_error(state, "No proto defined! Couldn't __index from type %s",
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_setTop(state, 2); // pops the table & the key
|
cosmoV_setTop(state, 2); // pops the table & the key
|
||||||
@ -883,17 +861,13 @@ int cosmoV_execute(CState *state)
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (!IS_REF(*temp)) {
|
if (!IS_REF(*temp)) {
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObj *obj = cosmoV_readRef(*temp);
|
CObj *obj = cosmoV_readRef(*temp);
|
||||||
CObjObject *proto = cosmoO_grabProto(obj);
|
CObjObject *proto = cosmoO_grabProto(obj);
|
||||||
|
|
||||||
if (proto != NULL) {
|
if (proto != NULL) {
|
||||||
if (!cosmoO_newIndexObject(
|
cosmoO_newIndexObject(state, proto, *key, *value);
|
||||||
state, proto, *key,
|
|
||||||
*value)) // if it returns false, cosmoV_error was called
|
|
||||||
return -1;
|
|
||||||
} else if (obj->type == COBJ_TABLE) {
|
} else if (obj->type == COBJ_TABLE) {
|
||||||
CObjTable *tbl = (CObjTable *)obj;
|
CObjTable *tbl = (CObjTable *)obj;
|
||||||
CValue *newVal = cosmoT_insert(state, &tbl->tbl, *key);
|
CValue *newVal = cosmoT_insert(state, &tbl->tbl, *key);
|
||||||
@ -902,7 +876,6 @@ int cosmoV_execute(CState *state)
|
|||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "No proto defined! Couldn't __newindex from type %s",
|
cosmoV_error(state, "No proto defined! Couldn't __newindex from type %s",
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop everything off the stack
|
// pop everything off the stack
|
||||||
@ -921,13 +894,11 @@ int cosmoV_execute(CState *state)
|
|||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (IS_REF(*temp)) {
|
if (IS_REF(*temp)) {
|
||||||
if (!cosmoV_rawset(state, cosmoV_readRef(*temp), constants[ident], *value))
|
cosmoV_rawset(state, cosmoV_readRef(*temp), constants[ident], *value);
|
||||||
return -1;
|
|
||||||
} else {
|
} else {
|
||||||
CObjString *field = cosmoV_toString(state, constants[ident]);
|
CObjString *field = cosmoV_toString(state, constants[ident]);
|
||||||
cosmoV_error(state, "Couldn't set field '%s' on type %s!", field->str,
|
cosmoV_error(state, "Couldn't set field '%s' on type %s!", field->str,
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop everything off the stack
|
// pop everything off the stack
|
||||||
@ -941,13 +912,11 @@ int cosmoV_execute(CState *state)
|
|||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (IS_REF(*temp)) {
|
if (IS_REF(*temp)) {
|
||||||
if (!cosmoV_rawget(state, cosmoV_readRef(*temp), constants[ident], &val))
|
cosmoV_rawget(state, cosmoV_readRef(*temp), constants[ident], &val);
|
||||||
return -1;
|
|
||||||
} else {
|
} else {
|
||||||
CObjString *field = cosmoV_toString(state, constants[ident]);
|
CObjString *field = cosmoV_toString(state, constants[ident]);
|
||||||
cosmoV_error(state, "Couldn't get field '%s' from type %s!", field->str,
|
cosmoV_error(state, "Couldn't get field '%s' from type %s!", field->str,
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_setTop(state, 1); // pops the object
|
cosmoV_setTop(state, 1); // pops the object
|
||||||
@ -962,13 +931,11 @@ int cosmoV_execute(CState *state)
|
|||||||
// this is almost identical to GETOBJECT, however cosmoV_getMethod is used instead
|
// this is almost identical to GETOBJECT, however cosmoV_getMethod is used instead
|
||||||
// of just cosmoV_get
|
// of just cosmoV_get
|
||||||
if (IS_REF(*temp)) {
|
if (IS_REF(*temp)) {
|
||||||
if (!cosmoV_getMethod(state, cosmoV_readRef(*temp), constants[ident], &val))
|
cosmoV_getMethod(state, cosmoV_readRef(*temp), constants[ident], &val);
|
||||||
return -1;
|
|
||||||
} else {
|
} else {
|
||||||
CObjString *field = cosmoV_toString(state, constants[ident]);
|
CObjString *field = cosmoV_toString(state, constants[ident]);
|
||||||
cosmoV_error(state, "Couldn't get field '%s' from type %s!", field->str,
|
cosmoV_error(state, "Couldn't get field '%s' from type %s!", field->str,
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_setTop(state, 1); // pops the object
|
cosmoV_setTop(state, 1); // pops the object
|
||||||
@ -985,14 +952,12 @@ int cosmoV_execute(CState *state)
|
|||||||
// sanity check
|
// sanity check
|
||||||
if (IS_REF(*temp)) {
|
if (IS_REF(*temp)) {
|
||||||
// get the field from the object
|
// get the field from the object
|
||||||
if (!cosmoV_rawget(state, cosmoV_readRef(*temp), constants[ident], &val))
|
cosmoV_rawget(state, cosmoV_readRef(*temp), constants[ident], &val);
|
||||||
return -1;
|
|
||||||
|
|
||||||
// now invoke the method!
|
// now invoke the method!
|
||||||
invokeMethod(state, cosmoV_readRef(*temp), val, args, nres, 1);
|
invokeMethod(state, cosmoV_readRef(*temp), val, args, nres, 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));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_ITER) :
|
CASE(OP_ITER) :
|
||||||
@ -1002,7 +967,6 @@ int cosmoV_execute(CState *state)
|
|||||||
if (!IS_REF(*temp)) {
|
if (!IS_REF(*temp)) {
|
||||||
cosmoV_error(state, "Couldn't iterate over non-iterator type %s!",
|
cosmoV_error(state, "Couldn't iterate over non-iterator type %s!",
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObj *obj = cosmoV_readRef(*temp);
|
CObj *obj = cosmoV_readRef(*temp);
|
||||||
@ -1026,7 +990,6 @@ int cosmoV_execute(CState *state)
|
|||||||
"Expected iterable object! '__iter' returned %s, expected "
|
"Expected iterable object! '__iter' returned %s, expected "
|
||||||
"<object>!",
|
"<object>!",
|
||||||
cosmoV_typeStr(*iObj));
|
cosmoV_typeStr(*iObj));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get __next method and place it at the top of the stack
|
// get __next method and place it at the top of the stack
|
||||||
@ -1034,7 +997,6 @@ int cosmoV_execute(CState *state)
|
|||||||
cosmoV_newRef(state->iStrings[ISTRING_NEXT]), iObj);
|
cosmoV_newRef(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;
|
|
||||||
}
|
}
|
||||||
} else if (obj->type == COBJ_TABLE) {
|
} else if (obj->type == COBJ_TABLE) {
|
||||||
CObjTable *tbl = (CObjTable *)obj;
|
CObjTable *tbl = (CObjTable *)obj;
|
||||||
@ -1059,7 +1021,6 @@ int cosmoV_execute(CState *state)
|
|||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "No proto defined! Couldn't get from type %s",
|
cosmoV_error(state, "No proto defined! Couldn't get from type %s",
|
||||||
cosmoO_typeStr(obj));
|
cosmoO_typeStr(obj));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_NEXT) :
|
CASE(OP_NEXT) :
|
||||||
@ -1071,7 +1032,6 @@ 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_error(state, "Expected '__next' to be a method, got type %s!",
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pushValue(state, *temp);
|
cosmoV_pushValue(state, *temp);
|
||||||
@ -1114,7 +1074,6 @@ int cosmoV_execute(CState *state)
|
|||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA),
|
cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA),
|
||||||
cosmoV_typeStr(*valB));
|
cosmoV_typeStr(*valB));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_POW) :
|
CASE(OP_POW) :
|
||||||
@ -1128,7 +1087,6 @@ int cosmoV_execute(CState *state)
|
|||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA),
|
cosmoV_error(state, "Expected numbers, got %s and %s!", cosmoV_typeStr(*valA),
|
||||||
cosmoV_typeStr(*valB));
|
cosmoV_typeStr(*valB));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_NOT) :
|
CASE(OP_NOT) :
|
||||||
@ -1144,7 +1102,6 @@ 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_COUNT) :
|
CASE(OP_COUNT) :
|
||||||
@ -1153,7 +1110,6 @@ int cosmoV_execute(CState *state)
|
|||||||
|
|
||||||
if (!IS_REF(*temp)) {
|
if (!IS_REF(*temp)) {
|
||||||
cosmoV_error(state, "Expected non-primitive, got %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Expected non-primitive, got %s!", cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = cosmoO_count(state, cosmoV_readRef(*temp));
|
int count = cosmoO_count(state, cosmoV_readRef(*temp));
|
||||||
@ -1178,7 +1134,6 @@ 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_INCGLOBAL) :
|
CASE(OP_INCGLOBAL) :
|
||||||
@ -1194,7 +1149,6 @@ 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_INCUPVAL) :
|
CASE(OP_INCUPVAL) :
|
||||||
@ -1209,7 +1163,6 @@ 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_INCINDEX) :
|
CASE(OP_INCINDEX) :
|
||||||
@ -1221,7 +1174,6 @@ int cosmoV_execute(CState *state)
|
|||||||
if (!IS_REF(*temp)) {
|
if (!IS_REF(*temp)) {
|
||||||
cosmoV_error(state, "Couldn't index non-indexable type %s!",
|
cosmoV_error(state, "Couldn't index non-indexable type %s!",
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObj *obj = cosmoV_readRef(*temp);
|
CObj *obj = cosmoV_readRef(*temp);
|
||||||
@ -1230,27 +1182,23 @@ int cosmoV_execute(CState *state)
|
|||||||
|
|
||||||
// call __index if the proto was found
|
// call __index if the proto was found
|
||||||
if (proto != NULL) {
|
if (proto != NULL) {
|
||||||
if (cosmoO_indexObject(state, proto, *key, &val)) {
|
cosmoO_indexObject(state, proto, *key, &val);
|
||||||
|
|
||||||
if (!IS_NUMBER(val)) {
|
if (!IS_NUMBER(val)) {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(val));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pushValue(state, val); // pushes old value onto the stack :)
|
cosmoV_pushValue(state, val); // pushes old value onto the stack :)
|
||||||
|
|
||||||
// call __newindex
|
// call __newindex
|
||||||
if (!cosmoO_newIndexObject(state, proto, *key,
|
cosmoO_newIndexObject(state, proto, *key,
|
||||||
cosmoV_newNumber(cosmoV_readNumber(val) + inc)))
|
cosmoV_newNumber(cosmoV_readNumber(val) + inc));
|
||||||
return -1;
|
|
||||||
} else
|
|
||||||
return -1; // cosmoO_indexObject failed and threw an error
|
|
||||||
} else if (obj->type == COBJ_TABLE) {
|
} else if (obj->type == COBJ_TABLE) {
|
||||||
CObjTable *tbl = (CObjTable *)obj;
|
CObjTable *tbl = (CObjTable *)obj;
|
||||||
CValue *val = cosmoT_insert(state, &tbl->tbl, *key);
|
CValue *val = cosmoT_insert(state, &tbl->tbl, *key);
|
||||||
|
|
||||||
if (!IS_NUMBER(*val)) {
|
if (!IS_NUMBER(*val)) {
|
||||||
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
cosmoV_error(state, "Expected number, got %s!", cosmoV_typeStr(*val));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pops tbl & key from stack
|
// pops tbl & key from stack
|
||||||
@ -1260,7 +1208,6 @@ int cosmoV_execute(CState *state)
|
|||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "No proto defined! Couldn't __index from type %s",
|
cosmoV_error(state, "No proto defined! Couldn't __index from type %s",
|
||||||
cosmoV_typeStr(*temp));
|
cosmoV_typeStr(*temp));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_INCOBJECT) :
|
CASE(OP_INCOBJECT) :
|
||||||
@ -1275,8 +1222,7 @@ int cosmoV_execute(CState *state)
|
|||||||
CObj *obj = cosmoV_readRef(*temp);
|
CObj *obj = cosmoV_readRef(*temp);
|
||||||
CValue val;
|
CValue val;
|
||||||
|
|
||||||
if (!cosmoV_rawget(state, obj, ident, &val))
|
cosmoV_rawget(state, obj, ident, &val);
|
||||||
return -1;
|
|
||||||
|
|
||||||
// pop the object off the stack
|
// pop the object off the stack
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
@ -1284,16 +1230,13 @@ 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 :)
|
||||||
if (!cosmoV_rawset(state, obj, ident,
|
cosmoV_rawset(state, obj, ident,
|
||||||
cosmoV_newNumber(cosmoV_readNumber(val) + inc)))
|
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;
|
|
||||||
}
|
}
|
||||||
} 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));
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CASE(OP_EQUAL) :
|
CASE(OP_EQUAL) :
|
||||||
|
20
src/cvm.h
20
src/cvm.h
@ -67,27 +67,17 @@ COSMO_API bool cosmoV_compileString(CState *state, const char *src, const char *
|
|||||||
COSMO_API bool cosmoV_undump(CState *state, cosmo_Reader reader, const void *ud);
|
COSMO_API bool cosmoV_undump(CState *state, cosmo_Reader reader, const void *ud);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
expects object to be pushed, then the key.
|
expects object to be pushed, then the key. pops the key & object and pushes the value
|
||||||
|
|
||||||
returns false if an error was thrown, returns true if the value was pushed onto the stack and
|
|
||||||
the object and key were popped
|
|
||||||
*/
|
*/
|
||||||
COSMO_API bool cosmoV_get(CState *state);
|
COSMO_API void cosmoV_get(CState *state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
expects object to be pushed, then the key, and finally the new value.
|
expects object to be pushed, then the key, and finally the new value. pops the key & object
|
||||||
|
|
||||||
returns false if an error was thrown, returns true if the value was set and the object key, and
|
|
||||||
value were popped
|
|
||||||
*/
|
*/
|
||||||
COSMO_API bool cosmoV_set(CState *state);
|
COSMO_API void cosmoV_set(CState *state);
|
||||||
|
|
||||||
// wraps the closure into a CObjMethod, so the function is called as an invoked method
|
// wraps the closure into a CObjMethod, so the function is called as an invoked method
|
||||||
COSMO_API bool cosmoV_getMethod(CState *state, CObj *obj, CValue key, CValue *val);
|
COSMO_API void cosmoV_getMethod(CState *state, CObj *obj, CValue key, CValue *val);
|
||||||
|
|
||||||
// clears the stack, callstack and restores the state into a usable state after a calloverflow or
|
|
||||||
// another hard to recover error (keeps the global table intact)
|
|
||||||
COSMO_API bool cosmoV_restore(CState *state);
|
|
||||||
|
|
||||||
// nice to have wrappers
|
// nice to have wrappers
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user