mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-10 18:30:05 +00:00
fixed __getter and __setter tables
This commit is contained in:
parent
32162ce50c
commit
8cd0112c48
20
examples/getters_setters.cosmo
Normal file
20
examples/getters_setters.cosmo
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
var object = {
|
||||||
|
__setter = [
|
||||||
|
"field1" = function(self, val)
|
||||||
|
print("setter for field1 called!")
|
||||||
|
self.x = val
|
||||||
|
end
|
||||||
|
],
|
||||||
|
|
||||||
|
__getter = [
|
||||||
|
"field1" = function(self)
|
||||||
|
print("getter for field1 called!")
|
||||||
|
|
||||||
|
return self.x + 1
|
||||||
|
end
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
object.field1 = 1337
|
||||||
|
|
||||||
|
print("got field: " .. object.field1)
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "cstate.h"
|
#include "cstate.h"
|
||||||
|
|
||||||
#define GC_STRESS
|
//#define GC_STRESS
|
||||||
//#define GC_DEBUG
|
//#define GC_DEBUG
|
||||||
// arrays will grow by a factor of 2
|
// arrays will grow by a factor of 2
|
||||||
#define GROW_FACTOR 2
|
#define GROW_FACTOR 2
|
||||||
|
26
src/cobj.c
26
src/cobj.c
@ -288,34 +288,36 @@ 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_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
|
// returns false if error thrown
|
||||||
if (cosmoO_getIString(state, object, ISTRING_GETTER, val) && IS_OBJECT(*val) && cosmoO_getRawObject(state, cosmoV_readObject(*val), key, val)) {
|
bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj) {
|
||||||
|
if (!cosmoT_get(&proto->tbl, key, val)) { // if the field doesn't exist in the object, check the proto
|
||||||
|
if (cosmoO_getIString(state, proto, ISTRING_GETTER, val) && IS_TABLE(*val) && cosmoT_get(&cosmoV_readTable(*val)->tbl, 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(obj)); // push object
|
||||||
if (cosmoV_call(state, 1, 1) != COSMOVM_OK) // call the function with the 1 argument
|
if (cosmoV_call(state, 1, 1) != COSMOVM_OK) // call the function with the 1 argument
|
||||||
return false;
|
return false;
|
||||||
*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 true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object->_obj.proto != NULL && cosmoO_getRawObject(state, object->_obj.proto, key, val))
|
if (proto->_obj.proto != NULL && cosmoO_getRawObject(state, proto->_obj.proto, key, val, obj))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
*val = cosmoV_newNil();
|
*val = cosmoV_newNil();
|
||||||
return false; // no protoobject to check against / key not found
|
return true; // no protoobject to check against / key not found
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cosmoO_setRawObject(CState *state, CObjObject *object, CValue key, CValue val) {
|
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj) {
|
||||||
CValue ret;
|
CValue ret;
|
||||||
|
|
||||||
// first check for __setters
|
// first check for __setters
|
||||||
if (cosmoO_getIString(state, object, ISTRING_SETTER, &ret) && IS_OBJECT(ret) && cosmoO_getRawObject(state, cosmoV_readObject(ret), key, &ret)) {
|
if (cosmoO_getIString(state, proto, ISTRING_SETTER, &ret) && IS_TABLE(ret) && cosmoT_get(&cosmoV_readTable(ret)->tbl, 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(obj)); // push object
|
||||||
cosmoV_pushValue(state, val); // push new value
|
cosmoV_pushValue(state, val); // push new value
|
||||||
cosmoV_call(state, 2, 0);
|
cosmoV_call(state, 2, 0);
|
||||||
return;
|
return;
|
||||||
@ -323,12 +325,12 @@ 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) && cosmoV_readString(key)->isIString)
|
if (IS_STRING(key) && cosmoV_readString(key)->isIString)
|
||||||
object->istringFlags = 0; // reset cache
|
proto->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
|
||||||
cosmoT_remove(state, &object->tbl, key);
|
cosmoT_remove(state, &proto->tbl, key);
|
||||||
} else {
|
} else {
|
||||||
CValue *newVal = cosmoT_insert(state, &object->tbl, key);
|
CValue *newVal = cosmoT_insert(state, &proto->tbl, key);
|
||||||
*newVal = val;
|
*newVal = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ typedef struct CObjUpval {
|
|||||||
|
|
||||||
#define cosmoV_readString(x) ((CObjString*)cosmoV_readObj(x))
|
#define cosmoV_readString(x) ((CObjString*)cosmoV_readObj(x))
|
||||||
#define cosmoV_readObject(x) ((CObjObject*)cosmoV_readObj(x))
|
#define cosmoV_readObject(x) ((CObjObject*)cosmoV_readObj(x))
|
||||||
|
#define cosmoV_readTable(x) ((CObjTable*)cosmoV_readObj(x))
|
||||||
#define cosmoV_readFunction(x) ((CObjFunction*)cosmoV_readObj(x))
|
#define cosmoV_readFunction(x) ((CObjFunction*)cosmoV_readObj(x))
|
||||||
#define cosmoV_readCFunction(x) (((CObjCFunction*)cosmoV_readObj(x))->cfunc)
|
#define cosmoV_readCFunction(x) (((CObjCFunction*)cosmoV_readObj(x))->cfunc)
|
||||||
#define cosmoV_readMethod(x) ((CObjMethod*)cosmoV_readObj(x))
|
#define cosmoV_readMethod(x) ((CObjMethod*)cosmoV_readObj(x))
|
||||||
@ -158,8 +159,8 @@ static inline CObjObject *cosmoO_grabProto(CObj *obj) {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cosmoO_getRawObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj);
|
||||||
void cosmoO_setRawObject(CState *state, CObjObject *object, CValue key, CValue val);
|
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj);
|
||||||
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);
|
||||||
|
|
||||||
|
10
src/cvm.c
10
src/cvm.c
@ -434,14 +434,15 @@ COSMO_API bool cosmoV_get(CState *state, CObj *_obj, CValue key, CValue *val) {
|
|||||||
|
|
||||||
// no proto to get from
|
// no proto to get from
|
||||||
if (object == NULL) {
|
if (object == NULL) {
|
||||||
cosmoV_error(state, "No proto defined! Couldn't get from type %s", cosmoO_typeStr(_obj));
|
CObjString *field = cosmoV_toString(state, key);
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't get field '%s' from type %s", field->str, cosmoO_typeStr(_obj));
|
||||||
*val = cosmoV_newNil();
|
*val = cosmoV_newNil();
|
||||||
return false;
|
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_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, _obj)) {
|
||||||
// *val now equals the response, pop the object
|
// *val now equals the response, pop the object
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
return true;
|
return true;
|
||||||
@ -456,11 +457,12 @@ COSMO_API bool cosmoV_set(CState *state, CObj *_obj, CValue key, CValue val) {
|
|||||||
|
|
||||||
// no proto to set to
|
// no proto to set to
|
||||||
if (object == NULL) {
|
if (object == NULL) {
|
||||||
cosmoV_error(state, "No proto defined! Couldn't set to type %s", cosmoO_typeStr(_obj));
|
CObjString *field = cosmoV_toString(state, key);
|
||||||
|
cosmoV_error(state, "No proto defined! Couldn't set field '%s' to type %s", field->str, cosmoO_typeStr(_obj));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoO_setRawObject(state, object, key, val);
|
cosmoO_setRawObject(state, object, key, val, _obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user