mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 16:20:06 +00:00
refactoring and cleanup
cosmoB_loadOSLib -> cosmoB_loadOS
This commit is contained in:
parent
dcf6a09dae
commit
5c3e24fc39
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
|||||||
# make clean && make && ./bin/cosmo
|
# make clean && make && ./bin/cosmo
|
||||||
|
|
||||||
CC=clang
|
CC=clang
|
||||||
CFLAGS=-fPIE -Wall -O3 -Isrc -std=c99
|
CFLAGS=-fPIE -Wall -Isrc -O3 -std=c99
|
||||||
LDFLAGS=-lm #-fsanitize=address
|
LDFLAGS=-lm #-fsanitize=address
|
||||||
OUT=bin/cosmo
|
OUT=bin/cosmo
|
||||||
|
|
||||||
|
15
main.c
15
main.c
@ -49,9 +49,8 @@ static bool interpret(CState *state, const char *script, const char *mod)
|
|||||||
|
|
||||||
// cosmoV_compileString pushes the result onto the stack (COBJ_ERROR or COBJ_CLOSURE)
|
// cosmoV_compileString pushes the result onto the stack (COBJ_ERROR or COBJ_CLOSURE)
|
||||||
if (cosmoV_compileString(state, script, mod)) {
|
if (cosmoV_compileString(state, script, mod)) {
|
||||||
COSMOVMRESULT res = cosmoV_call(state, 0, 0); // 0 args being passed, 0 results expected
|
// 0 args being passed, 0 results expected
|
||||||
|
if (!cosmoV_call(state, 0, 0))
|
||||||
if (res == COSMOVM_RUNTIME_ERR)
|
|
||||||
cosmoV_printError(state, state->error);
|
cosmoV_printError(state, state->error);
|
||||||
} else {
|
} else {
|
||||||
cosmoV_pop(state); // pop the error off the stack
|
cosmoV_pop(state); // pop the error off the stack
|
||||||
@ -171,9 +170,7 @@ void compileScript(CState *state, const char *in, const char *out)
|
|||||||
|
|
||||||
void loadScript(CState *state, const char *in)
|
void loadScript(CState *state, const char *in)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file = fopen(in, "rb");
|
||||||
|
|
||||||
file = fopen(in, "rb");
|
|
||||||
if (!cosmoV_undump(state, fileReader, file)) {
|
if (!cosmoV_undump(state, fileReader, file)) {
|
||||||
cosmoV_pop(state); // pop the error off the stack
|
cosmoV_pop(state); // pop the error off the stack
|
||||||
cosmoV_printError(state, state->error);
|
cosmoV_printError(state, state->error);
|
||||||
@ -181,9 +178,7 @@ void loadScript(CState *state, const char *in)
|
|||||||
};
|
};
|
||||||
|
|
||||||
printf("[!] loaded %s!\n", in);
|
printf("[!] loaded %s!\n", in);
|
||||||
COSMOVMRESULT res = cosmoV_call(state, 0, 0); // 0 args being passed, 0 results expected
|
if (!cosmoV_call(state, 0, 0))
|
||||||
|
|
||||||
if (res == COSMOVM_RUNTIME_ERR)
|
|
||||||
cosmoV_printError(state, state->error);
|
cosmoV_printError(state, state->error);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@ -203,7 +198,7 @@ int main(int argc, char *const argv[])
|
|||||||
{
|
{
|
||||||
CState *state = cosmoV_newState();
|
CState *state = cosmoV_newState();
|
||||||
cosmoB_loadLibrary(state);
|
cosmoB_loadLibrary(state);
|
||||||
cosmoB_loadOSLib(state);
|
cosmoB_loadOS(state);
|
||||||
cosmoB_loadVM(state);
|
cosmoB_loadVM(state);
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
|
@ -68,17 +68,12 @@ int cosmoB_pcall(CState *state, int nargs, CValue *args)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unfreeze the state GC before calling the function
|
// call the passed callable, the passed arguments are already in the
|
||||||
cosmoM_unfreezeGC(state);
|
// proper order lol, so we can just call it
|
||||||
|
bool res = cosmoV_pcall(state, nargs - 1, 1);
|
||||||
// call the passed callable
|
|
||||||
COSMOVMRESULT res = cosmoV_pcall(state, nargs - 1, 1);
|
|
||||||
|
|
||||||
// insert false before the result
|
// insert false before the result
|
||||||
cosmo_insert(state, 0, cosmoV_newBoolean(res == COSMOVM_OK));
|
cosmo_insert(state, 0, cosmoV_newBoolean(res));
|
||||||
|
|
||||||
// refreeze the state GC so it can be properly unfrozen
|
|
||||||
cosmoM_freezeGC(state);
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +327,7 @@ int cosmoB_osSystem(CState *state, int nargs, CValue *args)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
COSMO_API void cosmoB_loadOSLib(CState *state)
|
COSMO_API void cosmoB_loadOS(CState *state)
|
||||||
{
|
{
|
||||||
const char *identifiers[] = {"read", "time", "system"};
|
const char *identifiers[] = {"read", "time", "system"};
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ COSMO_API void cosmoB_loadObjLib(CState *state);
|
|||||||
- os.system()
|
- os.system()
|
||||||
- os.time()
|
- os.time()
|
||||||
*/
|
*/
|
||||||
COSMO_API void cosmoB_loadOSLib(CState *state);
|
COSMO_API void cosmoB_loadOS(CState *state);
|
||||||
|
|
||||||
/* loads the base string library, including:
|
/* loads the base string library, including:
|
||||||
- string.sub & <string>:sub()
|
- string.sub & <string>:sub()
|
||||||
|
@ -49,9 +49,10 @@ int addConstant(CState *state, CChunk *chunk, CValue value)
|
|||||||
return i; // we already have a matching constant!
|
return i; // we already have a matching constant!
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoM_freezeGC(state); // so our GC doesn't free it
|
cosmoV_pushValue(state, value); // push the value to the stack so our GC can see it
|
||||||
appendValArray(state, &chunk->constants, value);
|
appendValArray(state, &chunk->constants, value);
|
||||||
cosmoM_unfreezeGC(state);
|
cosmoV_pop(state);
|
||||||
|
|
||||||
return chunk->constants.count - 1; // return the index of the new constants
|
return chunk->constants.count - 1; // return the index of the new constants
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ void cleanChunk(CState *state, CChunk *chunk); // frees everything but the struc
|
|||||||
void freeChunk(CState *state, CChunk *chunk); // frees everything including the struct
|
void freeChunk(CState *state, CChunk *chunk); // frees everything including the struct
|
||||||
int addConstant(CState *state, CChunk *chunk, CValue value);
|
int addConstant(CState *state, CChunk *chunk, CValue value);
|
||||||
|
|
||||||
|
bool validateChunk(CState *state, CChunk *chunk);
|
||||||
|
|
||||||
// write to chunk
|
// write to chunk
|
||||||
void writeu8Chunk(CState *state, CChunk *chunk, INSTRUCTION i, int line);
|
void writeu8Chunk(CState *state, CChunk *chunk, INSTRUCTION i, int line);
|
||||||
void writeu16Chunk(CState *state, CChunk *chunk, uint16_t i, int line);
|
void writeu16Chunk(CState *state, CChunk *chunk, uint16_t i, int line);
|
||||||
|
15
src/cobj.c
15
src/cobj.c
@ -166,7 +166,7 @@ _eqFail:
|
|||||||
cosmoV_pushValue(state, eq1);
|
cosmoV_pushValue(state, eq1);
|
||||||
cosmoV_pushRef(state, obj1);
|
cosmoV_pushRef(state, obj1);
|
||||||
cosmoV_pushRef(state, obj2);
|
cosmoV_pushRef(state, obj2);
|
||||||
if (cosmoV_call(state, 2, 1) != COSMOVM_OK)
|
if (!cosmoV_call(state, 2, 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check return value and make sure it's a boolean
|
// check return value and make sure it's a boolean
|
||||||
@ -411,7 +411,7 @@ bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *v
|
|||||||
cosmoT_get(state, &cosmoV_readTable(*val)->tbl, key, val)) {
|
cosmoT_get(state, &cosmoV_readTable(*val)->tbl, key, val)) {
|
||||||
cosmoV_pushValue(state, *val); // push function
|
cosmoV_pushValue(state, *val); // push function
|
||||||
cosmoV_pushRef(state, (CObj *)obj); // push object
|
cosmoV_pushRef(state, (CObj *)obj); // push object
|
||||||
if (cosmoV_call(state, 1, 1) != COSMOVM_OK) // call the function with the 1 argument
|
if (!cosmoV_call(state, 1, 1)) // 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;
|
||||||
@ -532,7 +532,7 @@ bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *v
|
|||||||
cosmoV_pushValue(state, *val); // push function
|
cosmoV_pushValue(state, *val); // push function
|
||||||
cosmoV_pushRef(state, (CObj *)object); // push object
|
cosmoV_pushRef(state, (CObj *)object); // push object
|
||||||
cosmoV_pushValue(state, key); // push key
|
cosmoV_pushValue(state, key); // push key
|
||||||
if (cosmoV_call(state, 2, 1) != COSMOVM_OK) // call the function with the 2 arguments
|
if (!cosmoV_call(state, 2, 1)) // call the function with the 2 arguments
|
||||||
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;
|
||||||
@ -552,7 +552,7 @@ bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue
|
|||||||
cosmoV_pushRef(state, (CObj *)object); // push object
|
cosmoV_pushRef(state, (CObj *)object); // push object
|
||||||
cosmoV_pushValue(state, key); // push key & value pair
|
cosmoV_pushValue(state, key); // push key & value pair
|
||||||
cosmoV_pushValue(state, val);
|
cosmoV_pushValue(state, val);
|
||||||
return cosmoV_call(state, 3, 0) == COSMOVM_OK;
|
return cosmoV_call(state, 3, 0);
|
||||||
} 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!");
|
||||||
}
|
}
|
||||||
@ -569,7 +569,7 @@ CObjString *cosmoO_toString(CState *state, CObj *obj)
|
|||||||
if (protoObject != NULL && cosmoO_getIString(state, protoObject, ISTRING_TOSTRING, &res)) {
|
if (protoObject != NULL && cosmoO_getIString(state, protoObject, ISTRING_TOSTRING, &res)) {
|
||||||
cosmoV_pushValue(state, res);
|
cosmoV_pushValue(state, res);
|
||||||
cosmoV_pushRef(state, (CObj *)obj);
|
cosmoV_pushRef(state, (CObj *)obj);
|
||||||
if (cosmoV_call(state, 1, 1) != COSMOVM_OK)
|
if (!cosmoV_call(state, 1, 1))
|
||||||
return cosmoO_copyString(state, "<err>", 5);
|
return cosmoO_copyString(state, "<err>", 5);
|
||||||
|
|
||||||
// make sure the __tostring function returned a string
|
// make sure the __tostring function returned a string
|
||||||
@ -635,7 +635,7 @@ cosmo_Number cosmoO_toNumber(CState *state, CObj *obj)
|
|||||||
if (proto != NULL && cosmoO_getIString(state, proto, ISTRING_TONUMBER, &res)) {
|
if (proto != NULL && cosmoO_getIString(state, proto, ISTRING_TONUMBER, &res)) {
|
||||||
cosmoV_pushValue(state, res);
|
cosmoV_pushValue(state, res);
|
||||||
cosmoV_pushRef(state, (CObj *)obj);
|
cosmoV_pushRef(state, (CObj *)obj);
|
||||||
if (cosmoV_call(state, 1, 1) != COSMOVM_OK) // call res, expect 1 return val of <number>
|
if (!cosmoV_call(state, 1, 1)) // call res, expect 1 return val of <number>
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
StkPtr temp = cosmoV_getTop(state, 0);
|
StkPtr temp = cosmoV_getTop(state, 0);
|
||||||
@ -668,8 +668,7 @@ int cosmoO_count(CState *state, CObj *obj)
|
|||||||
if (proto != NULL && cosmoO_getIString(state, proto, ISTRING_COUNT, &res)) {
|
if (proto != NULL && cosmoO_getIString(state, proto, ISTRING_COUNT, &res)) {
|
||||||
cosmoV_pushValue(state, res);
|
cosmoV_pushValue(state, res);
|
||||||
cosmoV_pushRef(state, (CObj *)obj);
|
cosmoV_pushRef(state, (CObj *)obj);
|
||||||
if (cosmoV_call(state, 1, 1) !=
|
if (!cosmoV_call(state, 1, 1)) // call res, we expect 1 return value of type <number>
|
||||||
COSMOVM_OK) // call res, we expect 1 return value of type <number>
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
StkPtr ret = cosmoV_getTop(state, 0);
|
StkPtr ret = cosmoV_getTop(state, 0);
|
||||||
|
@ -145,7 +145,6 @@ static inline bool isObjType(CValue val, CObjType type)
|
|||||||
return IS_REF(val) && cosmoV_readRef(val)->type == type;
|
return IS_REF(val) && cosmoV_readRef(val)->type == type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// just protects against macro expansion
|
|
||||||
static inline bool IS_CALLABLE(CValue val)
|
static inline bool IS_CALLABLE(CValue val)
|
||||||
{
|
{
|
||||||
return IS_CLOSURE(val) || IS_CFUNCTION(val) || IS_METHOD(val);
|
return IS_CLOSURE(val) || IS_CFUNCTION(val) || IS_METHOD(val);
|
||||||
|
42
src/cvm.c
42
src/cvm.c
@ -346,6 +346,7 @@ static bool rawCall(CState *state, CObjClosure *closure, int args, int nresults,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns true if successful, false if error
|
||||||
bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
||||||
{
|
{
|
||||||
#ifdef VM_DEBUG
|
#ifdef VM_DEBUG
|
||||||
@ -418,7 +419,8 @@ bool invokeMethod(CState *state, CObj *obj, CValue func, int args, int nresults,
|
|||||||
|
|
||||||
// wraps cosmoV_call in a protected state, CObjError will be pushed onto the stack if function call
|
// wraps cosmoV_call in a protected state, CObjError will be pushed onto the stack if function call
|
||||||
// failed, else return values are passed
|
// failed, else return values are passed
|
||||||
COSMOVMRESULT cosmoV_pcall(CState *state, int args, int nresults)
|
// returns false if function call failed, true if function call succeeded
|
||||||
|
bool cosmoV_pcall(CState *state, int args, int nresults)
|
||||||
{
|
{
|
||||||
StkPtr base = cosmoV_getTop(state, args);
|
StkPtr base = cosmoV_getTop(state, args);
|
||||||
|
|
||||||
@ -434,25 +436,20 @@ COSMOVMRESULT cosmoV_pcall(CState *state, int args, int nresults)
|
|||||||
cosmoV_pushValue(state, cosmoV_newNil());
|
cosmoV_pushValue(state, cosmoV_newNil());
|
||||||
}
|
}
|
||||||
|
|
||||||
return COSMOVM_RUNTIME_ERR;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return COSMOVM_OK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// calls a callable object at stack->top - args - 1, passing the # of args to the callable, and
|
||||||
calls a callable object at stack->top - args - 1, passing the # of args to the callable, and
|
// ensuring nresults are returned
|
||||||
ensuring nresults are returned
|
// returns false if an error was thrown, else true if successful
|
||||||
|
bool cosmoV_call(CState *state, int args, int nresults)
|
||||||
returns:
|
|
||||||
COSMOVM_OK: callable object exited normally
|
|
||||||
COSMOVM_RUNTIME_ERR: an error occurred, grab the error from state->error
|
|
||||||
*/
|
|
||||||
COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults)
|
|
||||||
{
|
{
|
||||||
StkPtr val = cosmoV_getTop(state, args); // function will always be right above the args
|
StkPtr val = cosmoV_getTop(state, args); // function will always be right above the args
|
||||||
|
|
||||||
return callCValue(state, *val, args, nresults, 0) ? COSMOVM_OK : COSMOVM_RUNTIME_ERR;
|
return callCValue(state, *val, args, nresults, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool isFalsey(StkPtr val)
|
static inline bool isFalsey(StkPtr val)
|
||||||
@ -813,7 +810,7 @@ int cosmoV_execute(CState *state)
|
|||||||
{
|
{
|
||||||
uint8_t args = READBYTE(frame);
|
uint8_t args = READBYTE(frame);
|
||||||
uint8_t nres = READBYTE(frame);
|
uint8_t nres = READBYTE(frame);
|
||||||
if (cosmoV_call(state, args, nres) != COSMOVM_OK) {
|
if (!cosmoV_call(state, args, nres)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1040,9 +1037,7 @@ int cosmoV_execute(CState *state)
|
|||||||
cosmoV_pop(state); // pop the object from the stack
|
cosmoV_pop(state); // pop the object from the stack
|
||||||
cosmoV_pushValue(state, val);
|
cosmoV_pushValue(state, val);
|
||||||
cosmoV_pushRef(state, (CObj *)obj);
|
cosmoV_pushRef(state, (CObj *)obj);
|
||||||
if (cosmoV_call(state, 1, 1) !=
|
if (!cosmoV_call(state, 1, 1)) // we expect 1 return value on the stack, the iterable object
|
||||||
COSMOVM_OK) // we expect 1 return value on the stack, the iterable
|
|
||||||
// object
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
StkPtr iObj = cosmoV_getTop(state, 0);
|
StkPtr iObj = cosmoV_getTop(state, 0);
|
||||||
@ -1101,7 +1096,7 @@ int cosmoV_execute(CState *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cosmoV_pushValue(state, *temp);
|
cosmoV_pushValue(state, *temp);
|
||||||
if (cosmoV_call(state, 0, nresults) != COSMOVM_OK)
|
if (!cosmoV_call(state, 0, nresults))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (IS_NIL(*(cosmoV_getTop(
|
if (IS_NIL(*(cosmoV_getTop(
|
||||||
@ -1332,20 +1327,23 @@ int cosmoV_execute(CState *state)
|
|||||||
// compare & push
|
// compare & push
|
||||||
cosmoV_pushBoolean(state, cosmoV_equal(state, *valA, *valB));
|
cosmoV_pushBoolean(state, cosmoV_equal(state, *valA, *valB));
|
||||||
}
|
}
|
||||||
|
CASE(OP_LESS) :
|
||||||
|
{
|
||||||
|
NUMBEROP(cosmoV_newBoolean, <);
|
||||||
|
}
|
||||||
CASE(OP_GREATER) :
|
CASE(OP_GREATER) :
|
||||||
{
|
{
|
||||||
NUMBEROP(cosmoV_newBoolean, >);
|
NUMBEROP(cosmoV_newBoolean, >);
|
||||||
}
|
}
|
||||||
CASE(OP_LESS) :
|
CASE(OP_LESS_EQUAL) :
|
||||||
{
|
{
|
||||||
NUMBEROP(cosmoV_newBoolean, <);
|
NUMBEROP(cosmoV_newBoolean, <=);
|
||||||
}
|
}
|
||||||
CASE(OP_GREATER_EQUAL) :
|
CASE(OP_GREATER_EQUAL) :
|
||||||
{
|
{
|
||||||
NUMBEROP(cosmoV_newBoolean, >=);
|
NUMBEROP(cosmoV_newBoolean, >=);
|
||||||
}
|
}
|
||||||
CASE(OP_LESS_EQUAL)
|
CASE(OP_TRUE) : cosmoV_pushBoolean(state, true);
|
||||||
: {NUMBEROP(cosmoV_newBoolean, <=)} CASE(OP_TRUE) : cosmoV_pushBoolean(state, true);
|
|
||||||
CASE(OP_FALSE) : cosmoV_pushBoolean(state, false);
|
CASE(OP_FALSE) : cosmoV_pushBoolean(state, false);
|
||||||
CASE(OP_NIL) : cosmoV_pushValue(state, cosmoV_newNil());
|
CASE(OP_NIL) : cosmoV_pushValue(state, cosmoV_newNil());
|
||||||
CASE(OP_RETURN) :
|
CASE(OP_RETURN) :
|
||||||
|
11
src/cvm.h
11
src/cvm.h
@ -21,16 +21,9 @@
|
|||||||
# define VM_JUMPTABLE
|
# define VM_JUMPTABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
COSMOVM_OK,
|
|
||||||
COSMOVM_RUNTIME_ERR,
|
|
||||||
COSMOVM_BUILDTIME_ERR
|
|
||||||
} COSMOVMRESULT;
|
|
||||||
|
|
||||||
// args = # of pass parameters, nresults = # of expected results
|
// args = # of pass parameters, nresults = # of expected results
|
||||||
COSMO_API COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults);
|
COSMO_API bool cosmoV_call(CState *state, int args, int nresults);
|
||||||
COSMO_API COSMOVMRESULT cosmoV_pcall(CState *state, int args, int nresults);
|
COSMO_API bool cosmoV_pcall(CState *state, int args, int nresults);
|
||||||
|
|
||||||
// pushes new object onto the stack & returns a pointer to the new object
|
// pushes new object onto the stack & returns a pointer to the new object
|
||||||
COSMO_API CObjObject *cosmoV_makeObject(CState *state, int pairs);
|
COSMO_API CObjObject *cosmoV_makeObject(CState *state, int pairs);
|
||||||
|
Loading…
Reference in New Issue
Block a user