Track length of stringObj().
Use this to simplify catObjects().
This commit is contained in:
parent
68a7a55fc0
commit
3398729ab8
75
src/object.c
75
src/object.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
14
src/plfunc.c
14
src/plfunc.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue