Track length of stringObj().

Use this to simplify catObjects().
This commit is contained in:
Sage Vaillancourt 2022-03-24 23:07:34 -04:00
parent 68a7a55fc0
commit 3398729ab8
3 changed files with 55 additions and 40 deletions

View File

@ -262,51 +262,59 @@ static const char* errorText[] = {"MISMATCHED_PARENS",
* @param dest The string to copy the list text into
* @param obj The list Object to make a string from
*/
void stringList(char* dest, const Object* obj)
int stringList(char* dest, const Object* obj)
{
if (!dest || !isListy(*obj)) {
return;
return 0;
}
dest[0] = '(';
dest[1] = '\0';
int length = 1;
FOR_POINTER_IN_LIST(obj) {
strcat(dest, " ");
length += 1;
char tok[90] = "";
stringObj(tok, POINTER);
length += stringObj(tok, POINTER);
strcat(dest, tok);
}
strcat(dest, " )");
length += 2;
return length;
}
/**
* Creates a string from a given struct Object
* Blocks out with curly braces
*/
void stringStruct(char* dest, const Object* obj)
int stringStruct(char* dest, const Object* obj)
{
struct StructObject* so = obj->structObject;
dest[0] = '{';
dest[1] = '\0';
int length = 1;
for (int i = 0; i < global()->structDefs[so->definition].fieldCount; i++) {
strcat(dest, " ");
strcat(dest, global()->structDefs[so->definition].names[i]);
strcat(dest, ": ");
length += 3;
int isString = so->fields[i].type == TYPE_STRING;
if (isString) {
strcat(dest, "\"");
}
char tok[90] = "";
stringObj(tok, &so->fields[i]);
length += stringObj(tok, &so->fields[i]);
strcat(dest, tok);
if (isString) {
strcat(dest, "\"");
length += 1;
}
strcat(dest, ",");
length += 1;
}
int i = 0;
while (dest[i]) {
@ -314,7 +322,9 @@ void stringStruct(char* dest, const Object* obj)
}
dest[i - 1] = ' ';
dest[i + 0] = '}';
length += 2;
dest[i + 1] = '\0';
return length;
}
/**
* Creates a string from a given Object
@ -338,79 +348,88 @@ void stringStruct(char* dest, const Object* obj)
#define stringf(_dest, _len, _format, args...) snprintf(_dest, _len, _format, ## args)
#endif
char* stringNObj(char* dest, const Object* obj, const size_t len)
int stringNObj(char* dest, const Object* obj, const size_t len)
{
int size = 0;
if (!dest || !obj) {
return NULL;
return 0;
}
switch (obj->type) {
case TYPE_NUMBER:
stringf(dest, len, "%d", obj->number);
size += stringf(dest, len, "%d", obj->number);
break;
case TYPE_BOOL:
stringf(dest, len, "%s", obj->number ? "T" : "F");
size += stringf(dest, len, "%s", obj->number ? "T" : "F");
break;
case TYPE_STRING:
stringf(dest, len, "%s", obj->string);
size += stringf(dest, len, "%s", obj->string);
break;
case TYPE_SYMBOL:
stringf(dest, len, "`%s`", obj->string);
size += stringf(dest, len, "`%s`", obj->string);
break;
case TYPE_STRUCT:
//snprintf(dest, len, "{%s}", obj->structObject->definition->names[0]);
stringStruct(dest, obj);
size += stringStruct(dest, obj);
break;
case TYPE_LIST:
case TYPE_SLIST:
stringList(dest, obj);
size += stringList(dest, obj);
break;
case TYPE_ERROR: {
int code = getErrorCode(*obj);
#ifdef SIMPLE_ERRORS
stringf(dest, len, "E[%d]", (int)code);
size += stringf(dest, len, "E[%d]", (int)code);
#else
if (obj->error->context && obj->error->context[0] != '\0') {
stringf(dest, len, "'%s': %s", errorText[code],
obj->error->context);
size += stringf(dest, len, "'%s': %s", errorText[code],
obj->error->context);
} else if (code >= 0 && code <= INDEX_PAST_END) {
stringf(dest, len, "%s", errorText[code]);
size += stringf(dest, len, "%s", errorText[code]);
} else {
stringf(dest, len, "BROKEN ERROR CODE: %d", code);
size += stringf(dest, len, "BROKEN ERROR CODE: %d", code);
}
#endif
break;
}
case TYPE_FUNC:
stringf(dest, len, "F%d", obj->number);
size += stringf(dest, len, "F%d", obj->number);
break;
case TYPE_LAMBDA:
case TYPE_LAMBDA: {
#ifdef STANDALONE
dest += stringf(dest, len, "\\x%d", obj->number);
stringNObj(dest, &obj->lambda->params, len);
dest += strlen(dest);
int n = stringf(dest, len, "\\x%d", obj->number);
dest += n;
size += n;
n = stringNObj(dest, &obj->lambda->params, len);
dest += n;
size += n;
strcat(dest, " -> ");
dest += 4;
stringNObj(dest, &obj->lambda->body, len);
size += 4;
n = stringNObj(dest, &obj->lambda->body, len);
size += n;
dest += n;
dest += strlen(dest);
strcat(dest, ">");
size += 1;
#else
stringf(dest, len, "\\x%d", obj->number);
size += stringf(dest, len, "\\x%d", obj->number);
#endif
break;
}
case TYPE_OTHER:
stringf(dest, len, "%p", obj->other->data);
size += stringf(dest, len, "%p", obj->other->data);
break;
}
if (!isValidType(*obj)) {
stringf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number);
size += stringf(dest, len, "BAD_TYPE(%d) X%d", obj->type, obj->number);
}
return dest;
return size;
}
char* stringObj(char* dest, const Object* obj)
int stringObj(char* dest, const Object* obj)
{
return stringNObj(dest, obj, RESULT_LENGTH);
}

View File

@ -140,9 +140,9 @@ struct Other {
void* data;
};
char* stringNObj(char* dest, const Object* obj, size_t len);
int stringNObj(char* dest, const Object* obj, size_t len);
char* stringObj(char* dest, const Object* obj);
int stringObj(char* dest, const Object* obj);
void printList(const Object* list);

View File

@ -194,22 +194,18 @@ Object _catObjects(Object obj1, Object obj2, struct Environment* env)
{
Object evalObj1 = eval(&obj1, env);
Object evalObj2 = eval(&obj2, env);
if (isError(evalObj2, ONLY_ONE_ARGUMENT)) {
return evalObj1;
}
char str1[CAT_MAX] = "";
char str2[CAT_MAX] = "";
stringObj(str1, &evalObj1);
stringObj(str2, &evalObj2);
int length = stringObj(str1, &evalObj1);
length += stringObj(str2, &evalObj2);
cleanObject(&evalObj1);
cleanObject(&evalObj2);
size_t strLength = strlen(str1) + strlen(str2) + 1;
Object o = newObject(TYPE_STRING);
o.string = calloc(sizeof(char), strLength);
strcat(o.string, str1);
strcat(o.string, str2);
o.string = malloc(sizeof(char) * length + 1);
sprintf(o.string, "%s%s", str1, str2);
return o;
}