cosmoV_register now uses the stack to pass params

This commit is contained in:
CPunch 2020-12-19 21:15:12 -06:00
parent f6aaeb3417
commit de3a89ad4f
5 changed files with 23 additions and 53 deletions

View File

@ -5,10 +5,9 @@
#include "cmem.h"
void cosmoB_loadLibrary(CState *state) {
cosmoM_freezeGC(state);
cosmoV_register(state, "print", cosmoV_newObj(cosmoO_newCFunction(state, cosmoB_print)));
cosmoV_register(state, "foreach", cosmoV_newObj(cosmoO_newCFunction(state, cosmoB_foreach)));
cosmoM_unfreezeGC(state);
cosmoV_pushString(state, "print");
cosmoV_pushCFunction(state, cosmoB_print);
cosmoV_register(state, 1); // sets "print" global to cosmoB_print
}
int cosmoB_print(CState *state, int nargs, CValue *args) {
@ -21,40 +20,6 @@ int cosmoB_print(CState *state, int nargs, CValue *args) {
return 0; // print doesn't return any args
}
int cosmoB_foreach(CState *state, int nargs, CValue *args) {
if (nargs != 2) {
cosmoV_error(state, "foreach() expected 2 parameters, got %d!", nargs);
return 0;
}
if (!IS_DICT(args[0])) {
cosmoV_error(state, "foreach() expected first parameter to be <dictionary>, got %s!", cosmoV_typeStr(args[0]));
return 0;
}
if (!IS_CALLABLE(args[1])) {
cosmoV_error(state, "foreach() expected second parameter to be callable, got %s!", cosmoV_typeStr(args[1]));
return 0;
}
// loop through dictionary table, calling args[1] on active entries
CObjDict *dict = (CObjDict*)cosmoV_readObj(args[0]);
for (int i = 0; i < dict->tbl.capacity; i++) {
CTableEntry *entry = &dict->tbl.table[i];
if (!IS_NIL(entry->key)) {
// push key & value, then call args[1]
cosmoV_pushValue(state, args[1]);
cosmoV_pushValue(state, entry->key);
cosmoV_pushValue(state, entry->val);
cosmoV_call(state, 2, 0);
}
}
return 0;
}
int cosmoB_dsetProto(CState *state, int nargs, CValue *args) {
if (nargs == 2) {
CObjObject *obj = cosmoV_readObject(args[0]); // object to set proto too

View File

@ -88,15 +88,17 @@ void cosmoV_freeState(CState *state) {
free(state);
}
void cosmoV_register(CState *state, const char *identifier, CValue val) {
// we push the values so the garbage collector can find them
cosmoV_pushValue(state, val);
cosmoV_pushValue(state, cosmoV_newObj(cosmoO_copyString(state, identifier, strlen(identifier))));
// expects 2*pairs values on the stack, each pair should consist of 1 key and 1 value
void cosmoV_register(CState *state, int pairs) {
for (int i = 0; i < pairs; i++) {
StkPtr key = cosmoV_getTop(state, 1);
StkPtr val = cosmoV_getTop(state, 0);
CValue *oldVal = cosmoT_insert(state, &state->globals, *cosmoV_getTop(state, 0));
*oldVal = val;
CValue *oldVal = cosmoT_insert(state, &state->globals, *key);
*oldVal = *val;
cosmoV_setTop(state, 2); // pops the 2 values off the stack
cosmoV_setTop(state, 2); // pops the 2 values off the stack
}
}
void cosmoV_printStack(CState *state) {

View File

@ -53,7 +53,8 @@ typedef struct CState {
} CState;
COSMO_API CState *cosmoV_newState();
COSMO_API void cosmoV_register(CState *state, const char *identifier, CValue val);
// expects 2*pairs values on the stack, each pair should consist of 1 key and 1 value
COSMO_API void cosmoV_register(CState *state, int pairs);
COSMO_API void cosmoV_freeState(CState *state);
COSMO_API void cosmoV_printStack(CState *state);

View File

@ -611,7 +611,7 @@ int cosmoV_execute(CState *state) {
cosmoV_pushValue(state, cosmoV_newObj(state->iStrings[ISTRING_RESERVED])); // key
cosmoV_pushValue(state, cosmoV_newObj(dict)); // value
cosmoV_pushLString(state, "__next", 6); // key
cosmoV_pushString(state, "__next"); // key
CObjCFunction *dict_next = cosmoO_newCFunction(state, _dict__next);
cosmoV_pushValue(state, cosmoV_newObj(dict_next)); // value

View File

@ -52,9 +52,13 @@ static void repl() {
cosmoB_loadLibrary(state);
cosmoB_loadDebug(state);
// TODO: there's gotta be a better way to do this
cosmoV_register(state, "quit", cosmoV_newObj(cosmoO_newCFunction(state, cosmoB_quitRepl)));
cosmoV_register(state, "input", cosmoV_newObj(cosmoO_newCFunction(state, cosmoB_input)));
cosmoV_pushString(state, "quit");
cosmoV_pushCFunction(state, cosmoB_quitRepl);
cosmoV_pushString(state, "input");
cosmoV_pushCFunction(state, cosmoB_input);
cosmoV_register(state, 2);
while (_ACTIVE) {
printf("> ");
@ -107,8 +111,6 @@ static void runFile(const char* fileName) {
CState *state = cosmoV_newState();
cosmoB_loadLibrary(state);
cosmoV_register(state, "input", cosmoV_newObj(cosmoO_newCFunction(state, cosmoB_input)));
interpret(state, script, fileName);
cosmoV_freeState(state);