2020-10-28 05:16:30 +00:00
|
|
|
#ifndef COBJ_H
|
|
|
|
#define COBJ_H
|
|
|
|
|
|
|
|
#include "cosmo.h"
|
|
|
|
|
2023-09-05 01:14:53 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
typedef enum CObjType
|
|
|
|
{
|
2020-10-28 05:16:30 +00:00
|
|
|
COBJ_STRING,
|
2020-11-04 04:10:51 +00:00
|
|
|
COBJ_OBJECT,
|
2021-01-08 20:37:36 +00:00
|
|
|
COBJ_TABLE,
|
2020-10-28 05:16:30 +00:00
|
|
|
COBJ_FUNCTION,
|
|
|
|
COBJ_CFUNCTION,
|
2020-11-03 04:32:39 +00:00
|
|
|
// internal use
|
2021-01-24 18:17:46 +00:00
|
|
|
COBJ_ERROR,
|
2020-11-13 23:39:47 +00:00
|
|
|
COBJ_METHOD,
|
2020-11-03 04:32:39 +00:00
|
|
|
COBJ_CLOSURE,
|
|
|
|
COBJ_UPVALUE,
|
2021-01-08 01:50:36 +00:00
|
|
|
COBJ_MAX
|
2020-10-28 05:16:30 +00:00
|
|
|
} CObjType;
|
|
|
|
|
2021-01-08 01:50:36 +00:00
|
|
|
#include "cchunk.h"
|
2023-02-09 18:32:48 +00:00
|
|
|
#include "cstate.h"
|
2021-01-08 01:50:36 +00:00
|
|
|
#include "ctable.h"
|
2023-02-09 18:32:48 +00:00
|
|
|
#include "cvalue.h"
|
2021-01-08 01:50:36 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
#define CommonHeader CObj _obj
|
|
|
|
#define readFlag(x, flag) (x & (1u << flag))
|
|
|
|
#define setFlagOn(x, flag) (x |= (1u << flag))
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2020-12-13 03:53:12 +00:00
|
|
|
typedef int (*CosmoCFunction)(CState *state, int argCount, CValue *args);
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObj
|
|
|
|
{
|
2020-10-28 05:16:30 +00:00
|
|
|
struct CObj *next;
|
2021-01-08 01:50:36 +00:00
|
|
|
struct CObjObject *proto; // protoobject, describes the behavior of the object
|
2021-02-07 00:51:47 +00:00
|
|
|
CObjType type;
|
|
|
|
bool isMarked; // for the GC
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjString
|
|
|
|
{
|
|
|
|
CommonHeader; // "is a" CObj
|
2023-05-26 00:40:15 +00:00
|
|
|
char *str; // NULL terminated string
|
2020-10-28 05:16:30 +00:00
|
|
|
uint32_t hash; // for hashtable lookup
|
2021-02-07 00:51:47 +00:00
|
|
|
int length;
|
|
|
|
bool isIString;
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjError
|
|
|
|
{
|
Added CObjError, cosmoV_throw(), pcall(), and cosmoV_printError()
Errors are now handled very differently, parser errors and VM errors are now treated the same.
When cosmoV_error is called, cosmoV_throw is also called, which formats the error object and sets the panic state.
state->error now points to the latest CObjError when state->panic is true. To get a nice formatted Objection message, use
cosmoV_printError() and pass the state->error. pcall() was added to the standard base library. When called, the first argument
passed is called with the subsequent arguments given. If the call completed successfully, `true`,`nil` is returned. However
when an error occurs during the call, `false`,`<error>` is returned. Simply print the `<error>` to retrieve the error string.
2021-01-06 04:27:59 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
2023-02-09 18:32:48 +00:00
|
|
|
CValue err; // error string
|
Added CObjError, cosmoV_throw(), pcall(), and cosmoV_printError()
Errors are now handled very differently, parser errors and VM errors are now treated the same.
When cosmoV_error is called, cosmoV_throw is also called, which formats the error object and sets the panic state.
state->error now points to the latest CObjError when state->panic is true. To get a nice formatted Objection message, use
cosmoV_printError() and pass the state->error. pcall() was added to the standard base library. When called, the first argument
passed is called with the subsequent arguments given. If the call completed successfully, `true`,`nil` is returned. However
when an error occurs during the call, `false`,`<error>` is returned. Simply print the `<error>` to retrieve the error string.
2021-01-06 04:27:59 +00:00
|
|
|
CCallFrame *frames;
|
2021-02-07 00:51:47 +00:00
|
|
|
int frameCount;
|
2023-02-09 18:32:48 +00:00
|
|
|
int line; // reserved for parser errors
|
2021-02-07 00:51:47 +00:00
|
|
|
bool parserError; // if true, cosmoV_printError will format the error to the lexer
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
Added CObjError, cosmoV_throw(), pcall(), and cosmoV_printError()
Errors are now handled very differently, parser errors and VM errors are now treated the same.
When cosmoV_error is called, cosmoV_throw is also called, which formats the error object and sets the panic state.
state->error now points to the latest CObjError when state->panic is true. To get a nice formatted Objection message, use
cosmoV_printError() and pass the state->error. pcall() was added to the standard base library. When called, the first argument
passed is called with the subsequent arguments given. If the call completed successfully, `true`,`nil` is returned. However
when an error occurs during the call, `false`,`<error>` is returned. Simply print the `<error>` to retrieve the error string.
2021-01-06 04:27:59 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjObject
|
|
|
|
{
|
2020-10-28 05:16:30 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
2020-11-03 04:32:39 +00:00
|
|
|
CTable tbl;
|
2023-02-09 18:32:48 +00:00
|
|
|
cosmo_Flag istringFlags; // enables us to have a much faster lookup for reserved IStrings (like
|
|
|
|
// __init, __index, etc.)
|
|
|
|
union
|
|
|
|
{ // userdata (NULL by default)
|
2020-12-18 01:44:04 +00:00
|
|
|
void *userP;
|
|
|
|
int userI;
|
|
|
|
};
|
2021-02-07 00:51:47 +00:00
|
|
|
int userT; // user-defined type (for describing the userdata pointer/integer)
|
|
|
|
bool isLocked;
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjTable
|
|
|
|
{ // table, a wrapper for CTable
|
2020-12-10 02:32:42 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
CTable tbl;
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-12-10 02:32:42 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjFunction
|
|
|
|
{
|
2020-10-28 05:16:30 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
CChunk chunk;
|
2021-02-07 00:51:47 +00:00
|
|
|
CObjString *name;
|
|
|
|
CObjString *module; // name of the "module"
|
2020-10-28 05:16:30 +00:00
|
|
|
int args;
|
|
|
|
int upvals;
|
2020-12-27 19:36:17 +00:00
|
|
|
bool variadic;
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjCFunction
|
|
|
|
{
|
2020-10-28 05:16:30 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
CosmoCFunction cfunc;
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
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;
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjMethod
|
|
|
|
{
|
2020-11-10 01:44:12 +00:00
|
|
|
CommonHeader; // "is a " CObj
|
2020-11-17 21:07:56 +00:00
|
|
|
CValue func;
|
2021-02-07 00:51:47 +00:00
|
|
|
CObj *obj; // obj this method is bound too
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-11-10 01:44:12 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
struct CObjUpval
|
|
|
|
{
|
2020-11-03 04:32:39 +00:00
|
|
|
CommonHeader; // "is a" CObj
|
|
|
|
CValue closed;
|
2021-02-07 00:51:47 +00:00
|
|
|
CValue *val;
|
2020-11-03 04:32:39 +00:00
|
|
|
struct CObjUpval *next;
|
2021-02-15 22:20:04 +00:00
|
|
|
};
|
2020-11-03 04:32:39 +00:00
|
|
|
|
2020-11-17 01:58:16 +00:00
|
|
|
#undef CommonHeader
|
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
#define IS_STRING(x) isObjType(x, COBJ_STRING)
|
|
|
|
#define IS_OBJECT(x) isObjType(x, COBJ_OBJECT)
|
|
|
|
#define IS_TABLE(x) isObjType(x, COBJ_TABLE)
|
|
|
|
#define IS_FUNCTION(x) isObjType(x, COBJ_FUNCTION)
|
|
|
|
#define IS_CFUNCTION(x) isObjType(x, COBJ_CFUNCTION)
|
|
|
|
#define IS_METHOD(x) isObjType(x, COBJ_METHOD)
|
|
|
|
#define IS_CLOSURE(x) isObjType(x, COBJ_CLOSURE)
|
|
|
|
|
|
|
|
#define cosmoV_readString(x) ((CObjString *)cosmoV_readRef(x))
|
|
|
|
#define cosmoV_readCString(x) (((CObjString *)cosmoV_readRef(x))->str)
|
|
|
|
#define cosmoV_readObject(x) ((CObjObject *)cosmoV_readRef(x))
|
|
|
|
#define cosmoV_readTable(x) ((CObjTable *)cosmoV_readRef(x))
|
|
|
|
#define cosmoV_readFunction(x) ((CObjFunction *)cosmoV_readRef(x))
|
|
|
|
#define cosmoV_readCFunction(x) (((CObjCFunction *)cosmoV_readRef(x))->cfunc)
|
|
|
|
#define cosmoV_readMethod(x) ((CObjMethod *)cosmoV_readRef(x))
|
|
|
|
#define cosmoV_readClosure(x) ((CObjClosure *)cosmoV_readRef(x))
|
2023-08-29 19:07:45 +00:00
|
|
|
#define cosmoV_readError(x) ((CObjError *)cosmoV_readRef(x))
|
2023-02-09 18:32:48 +00:00
|
|
|
|
|
|
|
#define cosmoO_readCString(x) ((CObjString *)x)->str
|
2023-05-26 00:40:15 +00:00
|
|
|
#define cosmoO_readType(x) ((CObj *)x)->type
|
2023-02-09 18:32:48 +00:00
|
|
|
|
|
|
|
static inline bool isObjType(CValue val, CObjType type)
|
|
|
|
{
|
2021-02-07 20:32:39 +00:00
|
|
|
return IS_REF(val) && cosmoV_readRef(val)->type == type;
|
2020-10-28 05:16:30 +00:00
|
|
|
}
|
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
static inline bool IS_CALLABLE(CValue val)
|
|
|
|
{
|
2020-12-13 03:17:31 +00:00
|
|
|
return IS_CLOSURE(val) || IS_CFUNCTION(val) || IS_METHOD(val);
|
2023-02-09 18:32:48 +00:00
|
|
|
}
|
2020-12-13 00:16:31 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
void cosmoO_free(CState *state, CObj *obj);
|
|
|
|
bool cosmoO_equal(CState *state, CObj *obj1, CObj *obj2);
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2021-02-06 22:01:59 +00:00
|
|
|
// walks the protos of obj and checks for proto
|
|
|
|
bool cosmoO_isDescendant(CObj *obj, CObjObject *proto);
|
|
|
|
|
2020-11-10 01:44:12 +00:00
|
|
|
CObjObject *cosmoO_newObject(CState *state);
|
2021-01-08 20:37:36 +00:00
|
|
|
CObjTable *cosmoO_newTable(CState *state);
|
2020-10-28 05:16:30 +00:00
|
|
|
CObjFunction *cosmoO_newFunction(CState *state);
|
|
|
|
CObjCFunction *cosmoO_newCFunction(CState *state, CosmoCFunction func);
|
Added CObjError, cosmoV_throw(), pcall(), and cosmoV_printError()
Errors are now handled very differently, parser errors and VM errors are now treated the same.
When cosmoV_error is called, cosmoV_throw is also called, which formats the error object and sets the panic state.
state->error now points to the latest CObjError when state->panic is true. To get a nice formatted Objection message, use
cosmoV_printError() and pass the state->error. pcall() was added to the standard base library. When called, the first argument
passed is called with the subsequent arguments given. If the call completed successfully, `true`,`nil` is returned. However
when an error occurs during the call, `false`,`<error>` is returned. Simply print the `<error>` to retrieve the error string.
2021-01-06 04:27:59 +00:00
|
|
|
CObjError *cosmoO_newError(CState *state, CValue err);
|
2021-01-08 01:50:36 +00:00
|
|
|
CObjMethod *cosmoO_newMethod(CState *state, CValue func, CObj *obj);
|
2020-10-28 05:16:30 +00:00
|
|
|
CObjClosure *cosmoO_newClosure(CState *state, CObjFunction *func);
|
|
|
|
CObjUpval *cosmoO_newUpvalue(CState *state, CValue *val);
|
|
|
|
|
2021-01-08 01:50:36 +00:00
|
|
|
// grabs the base proto of the CObj* (if CObj is a CObjObject, that is returned)
|
2023-02-09 18:32:48 +00:00
|
|
|
static inline CObjObject *cosmoO_grabProto(CObj *obj)
|
|
|
|
{
|
|
|
|
return obj->type == COBJ_OBJECT ? (CObjObject *)obj : obj->proto;
|
2021-01-08 01:50:36 +00:00
|
|
|
}
|
|
|
|
|
2023-09-05 01:14:53 +00:00
|
|
|
void cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj);
|
2021-01-13 00:27:29 +00:00
|
|
|
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj);
|
2023-09-05 01:14:53 +00:00
|
|
|
void cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
|
|
|
void cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val);
|
2020-11-06 01:53:55 +00:00
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
// sets the user-defined pointer, if a user-define integer is already defined it will be over
|
|
|
|
// written
|
2021-02-07 00:51:47 +00:00
|
|
|
void cosmoO_setUserP(CObjObject *object, void *p);
|
|
|
|
// gets the user-defined pointer
|
|
|
|
void *cosmoO_getUserP(CObjObject *object);
|
2023-02-09 18:32:48 +00:00
|
|
|
// sets the user-defined integer, if a user-define pointer is already defined it will be over
|
|
|
|
// written
|
2021-02-07 00:51:47 +00:00
|
|
|
void cosmoO_setUserI(CObjObject *object, int i);
|
|
|
|
// gets the user-defined integer
|
|
|
|
int cosmoO_getUserI(CObjObject *object);
|
|
|
|
// sets the user-defined type
|
|
|
|
void cosmoO_setUserT(CObjObject *object, int t);
|
|
|
|
// gets the user type
|
|
|
|
int cosmoO_getUserT(CObjObject *object);
|
|
|
|
// locks the object
|
|
|
|
void cosmoO_lock(CObjObject *object);
|
|
|
|
// unlocks the object
|
|
|
|
void cosmoO_unlock(CObjObject *object);
|
2020-12-06 19:38:05 +00:00
|
|
|
|
2020-11-17 01:58:16 +00:00
|
|
|
// internal string
|
|
|
|
bool cosmoO_getIString(CState *state, CObjObject *object, int flag, CValue *val);
|
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
// copies the *str buffer to the heap and returns a CObjString struct which is also on the heap
|
|
|
|
// (length should not include the null terminator)
|
2021-02-02 03:07:43 +00:00
|
|
|
CObjString *cosmoO_copyString(CState *state, const char *str, size_t length);
|
|
|
|
|
2023-02-09 18:32:48 +00:00
|
|
|
// length shouldn't include the null terminator! str should be a null terminated string! (char array
|
|
|
|
// should also have been allocated using cosmoM_xmalloc!)
|
2021-02-02 03:07:43 +00:00
|
|
|
CObjString *cosmoO_takeString(CState *state, char *str, size_t length);
|
|
|
|
|
2020-10-28 05:16:30 +00:00
|
|
|
// allocates a CObjStruct pointing directly to *str
|
2021-02-02 03:07:43 +00:00
|
|
|
CObjString *cosmoO_allocateString(CState *state, const char *str, size_t length, uint32_t hash);
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2020-12-22 21:13:11 +00:00
|
|
|
/*
|
2021-02-06 22:01:59 +00:00
|
|
|
limited format strings to push onto the VM stack, formatting supported:
|
2020-12-22 21:13:11 +00:00
|
|
|
|
2021-01-16 21:40:58 +00:00
|
|
|
'%d' - integers [int]
|
2020-12-22 21:13:11 +00:00
|
|
|
'%f' - floating point [double]
|
2021-02-06 22:01:59 +00:00
|
|
|
'%s' - strings [char*]
|
|
|
|
'%s' also accepts '%*s' which looks for a length specifier before the char* array
|
2020-12-22 21:13:11 +00:00
|
|
|
*/
|
|
|
|
CObjString *cosmoO_pushVFString(CState *state, const char *format, va_list args);
|
|
|
|
|
2020-10-28 05:16:30 +00:00
|
|
|
COSMO_API void printObject(CObj *o);
|
2023-02-09 18:32:48 +00:00
|
|
|
const char *cosmoO_typeStr(CObj *obj);
|
2020-10-28 05:16:30 +00:00
|
|
|
|
2021-01-13 20:13:55 +00:00
|
|
|
CObjString *cosmoO_toString(CState *state, CObj *obj);
|
|
|
|
cosmo_Number cosmoO_toNumber(CState *state, CObj *obj);
|
2021-01-22 21:22:30 +00:00
|
|
|
int cosmoO_count(CState *state, CObj *obj);
|
2021-01-13 20:13:55 +00:00
|
|
|
|
2021-01-02 05:06:24 +00:00
|
|
|
#endif
|