From e253129e505e8a40738f266edee6de200f3bba79 Mon Sep 17 00:00:00 2001 From: CPunch Date: Thu, 31 Dec 2020 02:26:06 -0600 Subject: [PATCH] added string.sub() --- src/cbaselib.c | 82 ++++++++++++++++++++++++++++++++++++++++++-------- src/cbaselib.h | 1 - src/cparse.c | 1 - src/cvm.c | 4 +-- 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/src/cbaselib.c b/src/cbaselib.c index b763892..0f0f09c 100644 --- a/src/cbaselib.c +++ b/src/cbaselib.c @@ -4,18 +4,6 @@ #include "cobj.h" #include "cmem.h" -void cosmoB_loadLibrary(CState *state) { - // print - cosmoV_pushString(state, "print"); - cosmoV_pushCFunction(state, cosmoB_print); - - // assert (for unit testing) - cosmoV_pushString(state, "assert"); - cosmoV_pushCFunction(state, cosmoB_assert); - - cosmoV_register(state, 2); -} - int cosmoB_print(CState *state, int nargs, CValue *args) { for (int i = 0; i < nargs; i++) { CObjString *str = cosmoV_toString(state, args[i]); @@ -33,7 +21,7 @@ int cosmoB_assert(CState *state, int nargs, CValue *args) { } if (!IS_BOOLEAN(args[0])) { - cosmoV_error(state, "assert() expected , got %s!", cosmoV_typeStr(args[0])); + cosmoV_error(state, "assert() expected (), got (%s!)", cosmoV_typeStr(args[0])); return 0; } @@ -44,6 +32,51 @@ int cosmoB_assert(CState *state, int nargs, CValue *args) { return 0; } +// ================================================================ [STRING.*] ================================================================ + +// string.sub +int cosmoB_sSub(CState *state, int nargs, CValue *args) { + if (nargs == 2) { + if (!IS_STRING(args[0]) || !IS_NUMBER(args[1])) { + cosmoV_error(state, "string.sub() expected (, ), got (%s, %s)!", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); + return 0; + } + + CObjString *str = cosmoV_readString(args[0]); + cosmo_Number indx = cosmoV_readNumber(args[1]); + + // make sure we stay within memory + if (indx < 0 || indx >= str->length) { + cosmoV_error(state, "string.sub() Expected index to be 0-%d, got %d!", str->length, indx); + return 0; + } + + cosmoV_pushLString(state, str->str + ((int)indx), str->length - ((int)indx)); + } else if (nargs == 3) { + if (!IS_STRING(args[0]) || !IS_NUMBER(args[1]) || !IS_NUMBER(args[2])) { + cosmoV_error(state, "string.sub() expected (, , ), got (%s, %s, %s)!", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]), cosmoV_typeStr(args[2])); + return 0; + } + + CObjString *str = cosmoV_readString(args[0]); + cosmo_Number indx = cosmoV_readNumber(args[1]); + cosmo_Number length = cosmoV_readNumber(args[2]); + + // make sure we stay within memory + if (indx + length < 0 || indx + length >= str->length || indx < 0 || indx >= str->length) { + cosmoV_error(state, "string.sub() Expected subbed string goes out of bounds, max length is %d!", str->length); + return 0; + } + + cosmoV_pushLString(state, str->str + ((int)indx), ((int)length)); + } else { + cosmoV_error(state, "Expected 2 or 3 parameters, got %d!", nargs); + return 0; + } + + return 1; +} + int cosmoB_dsetProto(CState *state, int nargs, CValue *args) { if (nargs == 2) { CObjObject *obj = cosmoV_readObject(args[0]); // object to set proto too @@ -67,6 +100,29 @@ int cosmoB_dgetProto(CState *state, int nargs, CValue *args) { return 1; // 1 result } +void cosmoB_loadLibrary(CState *state) { + // print + cosmoV_pushString(state, "print"); + cosmoV_pushCFunction(state, cosmoB_print); + + // assert (for unit testing) + cosmoV_pushString(state, "assert"); + cosmoV_pushCFunction(state, cosmoB_assert); + + // string. + cosmoV_pushString(state, "string"); + + // sub + cosmoV_pushString(state, "sub"); + cosmoV_pushCFunction(state, cosmoB_sSub); + + cosmoV_makeDictionary(state, 1); + // string. + + // register these all to the global table + cosmoV_register(state, 3); +} + void cosmoB_loadDebug(CState *state) { // make __getter object for debug proto cosmoV_pushString(state, "__getter"); diff --git a/src/cbaselib.h b/src/cbaselib.h index 2b92971..9f6acb4 100644 --- a/src/cbaselib.h +++ b/src/cbaselib.h @@ -3,7 +3,6 @@ #include "cstate.h" - COSMO_API void cosmoB_loadLibrary(CState *state); COSMO_API void cosmoB_loadDebug(CState *state); COSMO_API int cosmoB_print(CState *state, int nargs, CValue *args); diff --git a/src/cparse.c b/src/cparse.c index 6c3b144..512797a 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -371,7 +371,6 @@ static void alignStack(CParseState *pstate, int alignment) { writePop(pstate, pstate->compiler->pushedValues - alignment); } else if (pstate->compiler->pushedValues < alignment) { error(pstate, "Missing expression!"); - printf("%d < %d\n", pstate->compiler->pushedValues, alignment); } pstate->compiler->pushedValues = alignment; diff --git a/src/cvm.c b/src/cvm.c index 9f7d49b..3fad491 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -673,9 +673,9 @@ int cosmoV_execute(CState *state) { // call closure/cfunction if (IS_CFUNCTION(val)) { - callCFunction(state, cosmoV_readCFunction(val), args, nres, 0); + callCFunction(state, cosmoV_readCFunction(val), args, nres, -1); } else if (IS_CLOSURE(val)) { - call(state, cosmoV_readClosure(val), args, nres, 0); + call(state, cosmoV_readClosure(val), args, nres, -1); } else { cosmoV_error(state, "Cannot call non-function value %s!", cosmoV_typeStr(val)); return -1;