mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 08:10:05 +00:00
added push wrappers
This commit is contained in:
parent
ffe4fc6930
commit
279714f3e0
@ -1,4 +1,5 @@
|
||||
#include "cbaselib.h"
|
||||
#include "cvm.h"
|
||||
#include "cvalue.h"
|
||||
#include "cobj.h"
|
||||
#include "cmem.h"
|
||||
|
38
src/cvm.c
38
src/cvm.c
@ -243,6 +243,25 @@ static inline bool isFalsey(StkPtr val) {
|
||||
return val->type == COSMO_TNIL || (val->type == COSMO_TBOOLEAN && !val->val.b);
|
||||
}
|
||||
|
||||
COSMO_API void cosmoV_pushObject(CState *state, int pairs) {
|
||||
StkPtr key, val;
|
||||
CObjObject *newObj = cosmoO_newObject(state); // start the table with enough space to hopefully prevent reallocation since that's costly
|
||||
cosmoV_pushValue(state, cosmoV_newObj(newObj)); // so our GC doesn't free our new object
|
||||
|
||||
for (int i = 0; i < pairs; i++) {
|
||||
val = cosmoV_getTop(state, (i*2) + 1);
|
||||
key = cosmoV_getTop(state, (i*2) + 2);
|
||||
|
||||
// set key/value pair
|
||||
CValue *newVal = cosmoT_insert(state, &newObj->tbl, *key);
|
||||
*newVal = *val;
|
||||
}
|
||||
|
||||
// once done, pop everything off the stack + push new object
|
||||
cosmoV_setTop(state, (pairs * 2) + 1);
|
||||
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
||||
}
|
||||
|
||||
#define BINARYOP(typeConst, op) \
|
||||
StkPtr valA = cosmoV_getTop(state, 1); \
|
||||
StkPtr valB = cosmoV_getTop(state, 0); \
|
||||
@ -367,23 +386,8 @@ bool cosmoV_execute(CState *state) {
|
||||
break;
|
||||
}
|
||||
case OP_NEWOBJECT: {
|
||||
uint8_t entries = READBYTE();
|
||||
StkPtr key, val;
|
||||
CObjObject *newObj = cosmoO_newObject(state); // start the table with enough space to hopefully prevent reallocation since that's costly
|
||||
cosmoV_pushValue(state, cosmoV_newObj(newObj)); // so our GC doesn't free our new object
|
||||
|
||||
for (int i = 0; i < entries; i++) {
|
||||
val = cosmoV_getTop(state, (i*2) + 1);
|
||||
key = cosmoV_getTop(state, (i*2) + 2);
|
||||
|
||||
// set key/value pair
|
||||
CValue *newVal = cosmoT_insert(state, &newObj->tbl, *key);
|
||||
*newVal = *val;
|
||||
}
|
||||
|
||||
// once done, pop everything off the stack + push new object
|
||||
cosmoV_setTop(state, (entries * 2) + 1);
|
||||
cosmoV_pushValue(state, cosmoV_newObj(newObj));
|
||||
uint8_t pairs = READBYTE();
|
||||
cosmoV_pushObject(state, pairs);
|
||||
break;
|
||||
}
|
||||
case OP_GETOBJECT: {
|
||||
|
29
src/cvm.h
29
src/cvm.h
@ -1,6 +1,8 @@
|
||||
#ifndef COSMOVM_H
|
||||
#define COSMOVM_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "cosmo.h"
|
||||
#include "cstate.h"
|
||||
|
||||
@ -12,5 +14,32 @@ typedef enum {
|
||||
|
||||
// args = # of pass parameters, nresults = # of expected results
|
||||
COSMO_API COSMOVMRESULT cosmoV_call(CState *state, int args);
|
||||
COSMO_API void cosmoV_pushObject(CState *state, int pairs);
|
||||
|
||||
// nice to have wrappers
|
||||
|
||||
// pushes a cosmo_Number to the stack
|
||||
static inline void cosmoV_pushNumber(CState *state, cosmo_Number num) {
|
||||
cosmoV_pushValue(state, cosmoV_newNumber(num));
|
||||
}
|
||||
|
||||
// pushes a boolean to the stack
|
||||
static inline void cosmoV_pushBoolean(CState *state, bool b) {
|
||||
cosmoV_pushValue(state, cosmoV_newBoolean(b));
|
||||
}
|
||||
|
||||
// pushes a C Function to the stack
|
||||
static inline void cosmoV_pushCFunction(CState *state, CosmoCFunction func) {
|
||||
cosmoV_pushValue(state, cosmoV_newObj(cosmoO_newCFunction(state, func)));
|
||||
}
|
||||
|
||||
static inline void cosmoV_pushLString(CState *state, const char *str, size_t len) {
|
||||
cosmoV_pushValue(state, cosmoV_newObj(cosmoO_copyString(state, str, len)));
|
||||
}
|
||||
|
||||
// accepts a null terminated string and copys the buffer to the VM heap
|
||||
static inline void cosmoV_pushString(CState *state, const char *str) {
|
||||
cosmoV_pushLString(state, str, strlen(str));
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user