From 8151cde6f36a6d8ab3120921ab399f78423fce6b Mon Sep 17 00:00:00 2001 From: CPunch Date: Sat, 6 Feb 2021 16:01:59 -0600 Subject: [PATCH] Refactored cosmo_pushFString - remove %t support - added length specifier to %s --- src/cobj.c | 32 ++++++++++++++++++-------------- src/cobj.h | 14 ++++++-------- src/cparse.c | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/cobj.c b/src/cobj.c index fd18ba2..b70b13d 100644 --- a/src/cobj.c +++ b/src/cobj.c @@ -245,34 +245,38 @@ CObjString *cosmoO_allocateString(CState *state, const char *str, size_t sz, uin CObjString *cosmoO_pushVFString(CState *state, const char *format, va_list args) { StkPtr start = state->top; + const char *end; + char c; + int len; while (true) { - const char *end = strchr(format, '%'); // grab the next occurrence of '%' + end = strchr(format, '%'); // grab the next occurrence of '%' + len = -1; // -1 means no length specified if (end == NULL) // the end, no '%' found break; // push the string before '%' cosmoV_pushLString(state, format, (end - format)); - char c = *(end+1); // the character right after '%' + reentry: + c = end[1]; // the character right after '%' switch (c) { - case 'd': { // int + case 'd': // int cosmoV_pushNumber(state, va_arg(args, int)); break; - } - case 'f': { // double + case 'f': // double cosmoV_pushNumber(state, va_arg(args, double)); break; - } - case 's': { // const char * - cosmoV_pushString(state, va_arg(args, char *)); + case 's': // char * + if (len >= 0) // the length is specified + cosmoV_pushLString(state, va_arg(args, char *), len); + else + cosmoV_pushString(state, va_arg(args, char *)); break; - } - case 't': { // CToken * - CToken *token = va_arg(args, CToken *); - cosmoV_pushLString(state, token->start, token->length); - break; - } + case '*': // length specifier + len = va_arg(args, int); + end++; // skip '*' + goto reentry; default: { char temp[2]; temp[0] = '%'; diff --git a/src/cobj.h b/src/cobj.h index b83031b..fd15cfe 100644 --- a/src/cobj.h +++ b/src/cobj.h @@ -136,11 +136,12 @@ static inline bool IS_CALLABLE(CValue val) { return IS_CLOSURE(val) || IS_CFUNCTION(val) || IS_METHOD(val); } -CObj *cosmoO_allocateBase(CState *state, size_t sz, CObjType type); void cosmoO_free(CState *state, CObj* obj); - bool cosmoO_equal(CObj* obj1, CObj* obj2); +// walks the protos of obj and checks for proto +bool cosmoO_isDescendant(CObj *obj, CObjObject *proto); + CObjObject *cosmoO_newObject(CState *state); CObjTable *cosmoO_newTable(CState *state); CObjFunction *cosmoO_newFunction(CState *state); @@ -155,9 +156,6 @@ static inline CObjObject *cosmoO_grabProto(CObj *obj) { return obj->type == COBJ_OBJECT ? (CObjObject*)obj : obj->proto; } -// walks the protos of obj and checks for proto -bool cosmoO_isDescendant(CObj *obj, CObjObject *proto); - bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *val, CObj *obj); void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj); bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val); @@ -181,12 +179,12 @@ CObjString *cosmoO_takeString(CState *state, char *str, size_t length); CObjString *cosmoO_allocateString(CState *state, const char *str, size_t length, uint32_t hash); /* - formats strings to push onto the VM stack, formatting supported: + limited format strings to push onto the VM stack, formatting supported: '%d' - integers [int] '%f' - floating point [double] - '%s' - strings [const char*] - '%t' - cosmo tokens [CToken *] + '%s' - strings [char*] + '%s' also accepts '%*s' which looks for a length specifier before the char* array */ CObjString *cosmoO_pushVFString(CState *state, const char *format, va_list args); diff --git a/src/cparse.c b/src/cparse.c index ecc2db0..950264d 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -146,7 +146,7 @@ static void errorAt(CParseState *pstate, CToken *token, const char *format, va_l if (token->type == TOKEN_EOF) { cosmoV_pushString(pstate->state, "At end: "); } else if (!(token->type == TOKEN_ERROR)) { - cosmoV_pushFString(pstate->state, "At '%t': ", token); // this is why the '%t' exist in cosmoO_pushFString lol + cosmoV_pushFString(pstate->state, "At '%*s': ", token->length, token->start); } else { cosmoV_pushString(pstate->state, "Lexer error: "); }