mirror of
https://github.com/CPunch/Cosmo.git
synced 2026-01-02 22:00:17 +00:00
Added cosmoV_pushFString(), and cosmoO_pushVFString().
cosmoV_error now pushes the error string onto the stack, as well as uses cosmoO_VFString to format strings. cosmoV_concat is now entirely self contained, and is now stack based. Push the CValues you want to concat into strings onto the stack and call cosmoV_concat with the # of values you pushed.
This commit is contained in:
40
src/cobj.c
40
src/cobj.c
@@ -224,6 +224,46 @@ CObjString *cosmoO_allocateString(CState *state, const char *str, size_t sz, uin
|
||||
return strObj;
|
||||
}
|
||||
|
||||
CObjString *cosmoO_pushVFString(CState *state, const char *format, va_list args) {
|
||||
StkPtr start = state->top;
|
||||
|
||||
while (true) {
|
||||
const char *end = strchr(format, '%'); // grab the next occurrence of '%'
|
||||
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 '%'
|
||||
|
||||
switch (c) {
|
||||
case 'd': { // int
|
||||
cosmoV_pushNumber(state, va_arg(args, int));
|
||||
break;
|
||||
}
|
||||
case 'f': { // double
|
||||
cosmoV_pushNumber(state, va_arg(args, double));
|
||||
break;
|
||||
}
|
||||
case 's': { // const char *
|
||||
cosmoV_pushString(state, va_arg(args, char *));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
char temp[2];
|
||||
temp[0] = '%';
|
||||
temp[1] = c;
|
||||
cosmoV_pushLString(state, temp, 2);
|
||||
}
|
||||
}
|
||||
format = end + 2; // + 2 because of % and the following character
|
||||
}
|
||||
|
||||
cosmoV_pushString(state, format); // push the rest of the string
|
||||
cosmoV_concat(state, state->top - start); // use cosmoV_concat to concat all the strings on the stack
|
||||
return cosmoV_readString(*start); // start should be state->top - 1
|
||||
}
|
||||
|
||||
bool cosmoO_getObject(CState *state, CObjObject *object, CValue key, CValue *val) {
|
||||
if (!cosmoT_get(&object->tbl, key, val)) { // if the field doesn't exist in the object, check the proto
|
||||
if (cosmoO_getIString(state, object, ISTRING_GETTER, val) && IS_OBJECT(*val) && cosmoO_getObject(state, cosmoV_readObject(*val), key, val)) {
|
||||
|
||||
Reference in New Issue
Block a user