2020-10-28 05:16:30 +00:00
|
|
|
#ifndef COBJ_H
|
|
|
|
#define COBJ_H
|
|
|
|
|
|
|
|
#include "cosmo.h"
|
|
|
|
#include "cchunk.h"
|
|
|
|
#include "cvalue.h"
|
2020-11-03 04:32:39 +00:00
|
|
|
#include "ctable.h"
|
2020-10-28 05:16:30 +00:00
|
|
|
|
|
|
|
typedef struct CState CState;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
COBJ_STRING,
|
2020-11-04 04:10:51 +00:00
|
|
|
COBJ_OBJECT,
|
2020-10-28 05:16:30 +00:00
|
|
|
COBJ_FUNCTION,
|
|
|
|
COBJ_CFUNCTION,
|
2020-11-03 04:32:39 +00:00
|
|
|
// internal use
|
2020-11-13 23:39:47 +00:00
|
|
|
COBJ_METHOD,
|
2020-11-03 04:32:39 +00:00
|
|
|
COBJ_CLOSURE,
|
|
|
|
COBJ_UPVALUE,
|
2020-10-28 05:16:30 +00:00
|
|
|
} CObjType;
|
|
|
|
|
2020-11-10 01:44:12 +00:00
|
|
|
#define CommonHeader CObj _obj;
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2020-11-10 01:44:12 +00:00
|
|
|
typedef CValue (*CosmoCFunction)(CState *state, int argCount, CValue *args);
|
2020-10-28 05:16:30 +00:00
|
|
|
|
|
|
|
typedef struct CObj {
|
|
|
|
CObjType type;
|
|
|
|
bool isMarked; // for the GC
|
|
|
|
struct CObj *next;
|
|
|
|
} CObj;
|
|
|
|
|
|
|
|
typedef struct CObjString {
|
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
int length;
|
|
|
|
char *str;
|
|
|
|
uint32_t hash; // for hashtable lookup
|
|
|
|
} CObjString;
|
|
|
|
|
2020-11-04 04:10:51 +00:00
|
|
|
typedef struct CObjObject {
|
2020-10-28 05:16:30 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
2020-11-03 04:32:39 +00:00
|
|
|
CTable tbl;
|
2020-11-13 23:39:47 +00:00
|
|
|
void *user; // userdata (NULL by default)
|
2020-11-10 01:44:12 +00:00
|
|
|
struct CObjObject *meta; // metaobject, describes the behavior of the object
|
2020-11-04 04:10:51 +00:00
|
|
|
} CObjObject;
|
2020-10-28 05:16:30 +00:00
|
|
|
|
|
|
|
typedef struct CObjFunction {
|
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
CChunk chunk;
|
|
|
|
int args;
|
|
|
|
int upvals;
|
|
|
|
CObjString *name;
|
|
|
|
} CObjFunction;
|
|
|
|
|
|
|
|
typedef struct CObjCFunction {
|
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
CosmoCFunction cfunc;
|
|
|
|
} CObjCFunction;
|
|
|
|
|
|
|
|
typedef struct CObjClosure {
|
2020-11-03 04:32:39 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
2020-10-28 05:16:30 +00:00
|
|
|
CObjFunction *function;
|
|
|
|
CObjUpval **upvalues;
|
|
|
|
int upvalueCount;
|
|
|
|
} CObjClosure;
|
|
|
|
|
2020-11-10 01:44:12 +00:00
|
|
|
typedef struct CObjMethod {
|
|
|
|
CommonHeader; // "is a " CObj
|
|
|
|
CObjObject *obj; // obj this method is bound too
|
2020-11-13 05:04:09 +00:00
|
|
|
union {
|
|
|
|
CObjClosure *closure;
|
|
|
|
CObjCFunction *cfunc;
|
|
|
|
};
|
|
|
|
bool isCFunc;
|
2020-11-10 01:44:12 +00:00
|
|
|
} CObjMethod;
|
|
|
|
|
2020-11-03 04:32:39 +00:00
|
|
|
typedef struct CObjUpval {
|
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
CValue *val;
|
|
|
|
CValue closed;
|
|
|
|
struct CObjUpval *next;
|
|
|
|
} CObjUpval;
|
|
|
|
|
2020-10-28 05:16:30 +00:00
|
|
|
#define IS_STRING(x) isObjType(x, COBJ_STRING)
|
2020-11-04 04:10:51 +00:00
|
|
|
#define IS_TABLE(x) isObjType(x, COBJ_OBJECT)
|
2020-10-28 05:16:30 +00:00
|
|
|
#define IS_FUNCTION(x) isObjType(x, COBJ_FUNCTION)
|
|
|
|
#define IS_CFUNCTION(x) isObjType(x, COBJ_CFUNCTION)
|
2020-11-10 01:44:12 +00:00
|
|
|
#define IS_METHOD(x) isObjType(x, COBJ_METHOD)
|
2020-10-28 05:16:30 +00:00
|
|
|
#define IS_CLOSURE(x) isObjType(x, COBJ_CLOSURE)
|
|
|
|
|
2020-11-13 05:04:09 +00:00
|
|
|
#define cosmoV_readString(x) ((CObjString*)cosmoV_readObj((x)))
|
|
|
|
#define cosmoV_readObject(x) ((CObjObject*)cosmoV_readObj((x)))
|
|
|
|
#define cosmoV_readFunction(x) ((CObjFunction*)cosmoV_readObj((x)))
|
|
|
|
#define cosmoV_readCFunction(x) (((CObjCFunction*)cosmoV_readObj((x)))->cfunc)
|
|
|
|
#define cosmoV_readMethod(x) ((CObjMethod*)cosmoV_readObj((x)))
|
|
|
|
#define cosmoV_readClosure(x) ((CObjClosure*)cosmoV_readObj((x)))
|
2020-10-28 05:16:30 +00:00
|
|
|
|
|
|
|
static inline bool isObjType(CValue val, CObjType type) {
|
|
|
|
return IS_OBJ(val) && cosmoV_readObj(val)->type == type;
|
|
|
|
}
|
|
|
|
|
2020-11-06 01:53:55 +00:00
|
|
|
CObj *cosmoO_allocateBase(CState *state, size_t sz, CObjType type);
|
|
|
|
void cosmoO_free(CState *state, CObj* obj);
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2020-11-06 01:53:55 +00:00
|
|
|
bool cosmoO_equal(CObj* obj1, CObj* obj2);
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2020-11-10 01:44:12 +00:00
|
|
|
CObjObject *cosmoO_newObject(CState *state);
|
2020-10-28 05:16:30 +00:00
|
|
|
CObjFunction *cosmoO_newFunction(CState *state);
|
|
|
|
CObjCFunction *cosmoO_newCFunction(CState *state, CosmoCFunction func);
|
2020-11-10 01:44:12 +00:00
|
|
|
CObjMethod *cosmoO_newMethod(CState *state, CObjClosure *func, CObjObject *obj);
|
2020-11-13 05:04:09 +00:00
|
|
|
CObjMethod *cosmoO_newCMethod(CState *state, CObjCFunction *func, CObjObject *obj);
|
2020-10-28 05:16:30 +00:00
|
|
|
CObjClosure *cosmoO_newClosure(CState *state, CObjFunction *func);
|
|
|
|
CObjString *cosmoO_toString(CState *state, CObj *val);
|
|
|
|
CObjUpval *cosmoO_newUpvalue(CState *state, CValue *val);
|
|
|
|
|
2020-11-06 01:53:55 +00:00
|
|
|
bool cosmoO_getObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
|
|
|
void cosmoO_setObject(CState *state, CObjObject *object, CValue key, CValue val);
|
|
|
|
|
2020-10-28 05:16:30 +00:00
|
|
|
// copies the *str buffer to the heap and returns a CObjString struct which is also on the heap
|
|
|
|
CObjString *cosmoO_copyString(CState *state, const char *str, size_t sz);
|
|
|
|
// pass an already allocated str buffer!
|
|
|
|
CObjString *cosmoO_takeString(CState *state, char *str, size_t sz);
|
|
|
|
// allocates a CObjStruct pointing directly to *str
|
|
|
|
CObjString *cosmoO_allocateString(CState *state, const char *str, size_t sz, uint32_t hash);
|
|
|
|
|
|
|
|
COSMO_API void printObject(CObj *o);
|
|
|
|
|
|
|
|
#define cosmoO_readCString(x) ((CObjString*)x)->str
|
|
|
|
|
|
|
|
#endif
|