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

View File

@ -140,9 +140,9 @@ struct Other {
void* data; 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); 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 evalObj1 = eval(&obj1, env);
Object evalObj2 = eval(&obj2, env); Object evalObj2 = eval(&obj2, env);
if (isError(evalObj2, ONLY_ONE_ARGUMENT)) {
return evalObj1;
}
char str1[CAT_MAX] = ""; char str1[CAT_MAX] = "";
char str2[CAT_MAX] = ""; char str2[CAT_MAX] = "";
stringObj(str1, &evalObj1); int length = stringObj(str1, &evalObj1);
stringObj(str2, &evalObj2); length += stringObj(str2, &evalObj2);
cleanObject(&evalObj1); cleanObject(&evalObj1);
cleanObject(&evalObj2); cleanObject(&evalObj2);
size_t strLength = strlen(str1) + strlen(str2) + 1;
Object o = newObject(TYPE_STRING); Object o = newObject(TYPE_STRING);
o.string = calloc(sizeof(char), strLength); o.string = malloc(sizeof(char) * length + 1);
strcat(o.string, str1); sprintf(o.string, "%s%s", str1, str2);
strcat(o.string, str2);
return o; return o;
} }