mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-22 07:20:05 +00:00
Refactored cosmo_pushFString
- remove %t support - added length specifier to %s
This commit is contained in:
parent
2f9ff08cd3
commit
8151cde6f3
30
src/cobj.c
30
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) {
|
CObjString *cosmoO_pushVFString(CState *state, const char *format, va_list args) {
|
||||||
StkPtr start = state->top;
|
StkPtr start = state->top;
|
||||||
|
const char *end;
|
||||||
|
char c;
|
||||||
|
int len;
|
||||||
|
|
||||||
while (true) {
|
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
|
if (end == NULL) // the end, no '%' found
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// push the string before '%'
|
// push the string before '%'
|
||||||
cosmoV_pushLString(state, format, (end - format));
|
cosmoV_pushLString(state, format, (end - format));
|
||||||
char c = *(end+1); // the character right after '%'
|
|
||||||
|
|
||||||
|
reentry:
|
||||||
|
c = end[1]; // the character right after '%'
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'd': { // int
|
case 'd': // int
|
||||||
cosmoV_pushNumber(state, va_arg(args, int));
|
cosmoV_pushNumber(state, va_arg(args, int));
|
||||||
break;
|
break;
|
||||||
}
|
case 'f': // double
|
||||||
case 'f': { // double
|
|
||||||
cosmoV_pushNumber(state, va_arg(args, double));
|
cosmoV_pushNumber(state, va_arg(args, double));
|
||||||
break;
|
break;
|
||||||
}
|
case 's': // char *
|
||||||
case 's': { // const char *
|
if (len >= 0) // the length is specified
|
||||||
|
cosmoV_pushLString(state, va_arg(args, char *), len);
|
||||||
|
else
|
||||||
cosmoV_pushString(state, va_arg(args, char *));
|
cosmoV_pushString(state, va_arg(args, char *));
|
||||||
break;
|
break;
|
||||||
}
|
case '*': // length specifier
|
||||||
case 't': { // CToken *
|
len = va_arg(args, int);
|
||||||
CToken *token = va_arg(args, CToken *);
|
end++; // skip '*'
|
||||||
cosmoV_pushLString(state, token->start, token->length);
|
goto reentry;
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
char temp[2];
|
char temp[2];
|
||||||
temp[0] = '%';
|
temp[0] = '%';
|
||||||
|
14
src/cobj.h
14
src/cobj.h
@ -136,11 +136,12 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
CObj *cosmoO_allocateBase(CState *state, size_t sz, CObjType type);
|
|
||||||
void cosmoO_free(CState *state, CObj* obj);
|
void cosmoO_free(CState *state, CObj* obj);
|
||||||
|
|
||||||
bool cosmoO_equal(CObj* obj1, CObj* obj2);
|
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);
|
CObjObject *cosmoO_newObject(CState *state);
|
||||||
CObjTable *cosmoO_newTable(CState *state);
|
CObjTable *cosmoO_newTable(CState *state);
|
||||||
CObjFunction *cosmoO_newFunction(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;
|
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);
|
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);
|
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj);
|
||||||
bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
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);
|
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]
|
'%d' - integers [int]
|
||||||
'%f' - floating point [double]
|
'%f' - floating point [double]
|
||||||
'%s' - strings [const char*]
|
'%s' - strings [char*]
|
||||||
'%t' - cosmo tokens [CToken *]
|
'%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);
|
CObjString *cosmoO_pushVFString(CState *state, const char *format, va_list args);
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ static void errorAt(CParseState *pstate, CToken *token, const char *format, va_l
|
|||||||
if (token->type == TOKEN_EOF) {
|
if (token->type == TOKEN_EOF) {
|
||||||
cosmoV_pushString(pstate->state, "At end: ");
|
cosmoV_pushString(pstate->state, "At end: ");
|
||||||
} else if (!(token->type == TOKEN_ERROR)) {
|
} 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 {
|
} else {
|
||||||
cosmoV_pushString(pstate->state, "Lexer error: ");
|
cosmoV_pushString(pstate->state, "Lexer error: ");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user