From 55d39431b1bc9682de6849fcca38dfcdc3837df7 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Wed, 15 Dec 2021 14:30:16 -0500 Subject: [PATCH] Add TYPE_SLIST. Not yet stable, but allows manipulation of lists without immediate evaluation. --- src/object.c | 40 +++++++++++++++++++++++++++------------- src/object.h | 4 +++- src/pebblisp.c | 20 +++++++++++++++++--- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/object.c b/src/object.c index 42093ae..671a5b4 100644 --- a/src/object.c +++ b/src/object.c @@ -23,7 +23,7 @@ */ int listLength(const Object *listObj) { - if(!listObj || listObj->type != TYPE_LIST) + if(!listObj || !isListy(*listObj)) return -1; int len = 0; @@ -48,7 +48,7 @@ Object len(Object obj1, Object o_ignore, struct Environment *e_ignore) */ Object *itemAt(const Object *listObj, int n) { - if(!listObj || listObj->type != TYPE_LIST) + if(!listObj || !isListy(*listObj)) return NULL; FOR_POINTER_IN_LIST(listObj) { @@ -67,7 +67,7 @@ Object *itemAt(const Object *listObj, int n) */ Object *tail(const Object *listObj) { - if(!listObj || listObj->type != TYPE_LIST) + if(!listObj || !isListy(*listObj)) return NULL; Object *tail = NULL; @@ -96,6 +96,7 @@ inline int isEmpty(const Object *obj) case TYPE_BOOL: return obj->number == 0; case TYPE_LIST: + case TYPE_SLIST: return obj->list == NULL; case TYPE_LAMBDA: return obj->lambda == NULL; @@ -139,7 +140,7 @@ void allocObject(Object **spot, const Object src) */ void insertIntoList(Object *dest, int ind, const Object src) { - if(!dest || dest->type != TYPE_LIST) + if(!dest || !isListy(*dest)) return; // Merely append, when possible @@ -161,13 +162,14 @@ void insertIntoList(Object *dest, int ind, const Object src) * Replace an Object in a list at a given index with a given Object * Attempts to clean the replaced Object before adding the new one * Immediately returns if `list` is NULL or not a list type + * * @param list The list Object to replace an element of * @param i The index of the element to replace * @param src The Object to copy into the list */ void replaceListing(Object *list, int i, const Object src) { - if(!list || list->type != TYPE_LIST) + if(!list || isListy(*list)) return; Object *replace = itemAt(list, i); Object *oldForward = replace->forward; @@ -184,7 +186,7 @@ void replaceListing(Object *list, int i, const Object src) */ void nf_addToList(Object *dest, const Object src) { - if(!dest || dest->type != TYPE_LIST) + if(!dest || !isListy(*dest)) return; if(isEmpty(dest)) { @@ -233,7 +235,7 @@ static const char *errorText[] = { */ void stringList(char *dest, const Object *obj) { - if(!dest || obj->type != TYPE_LIST) + if(!dest || !isListy(*obj)) return; dest[0] = '('; @@ -282,6 +284,7 @@ char* stringNObj(char *dest, const Object *obj, const size_t len) { snprintf(dest, len, "`%s`", obj->string); break; case TYPE_LIST: + case TYPE_SLIST: stringList(dest, obj); break; case TYPE_ERROR: { @@ -342,6 +345,9 @@ void printType(const Object *obj) case TYPE_LIST: printf("TYPE_LIST"); return; + case TYPE_SLIST: + printf("TYPE_SLIST"); + return; case TYPE_FUNC: printf("TYPE_FUNC"); return; @@ -443,6 +449,7 @@ void cleanObject(Object *target) target->string = NULL; break; case TYPE_LIST: + case TYPE_SLIST: deleteList(target); break; case TYPE_LAMBDA: @@ -494,7 +501,7 @@ void deleteList(Object *dest) if(!dest) return; - if(dest->type != TYPE_LIST) { + if(!isListy(*dest)) { printf("Tried to delete something other than a list\n"); return; } @@ -515,7 +522,7 @@ void _copyList(Object *dest, const Object *src, int delete) printd("NULL\n"); return; } - if(dest->type != TYPE_LIST || src->type != TYPE_LIST) { + if(!isListy(*dest) || !isListy(*src)) { printd("NOT A LIST\n"); return; } @@ -524,7 +531,7 @@ void _copyList(Object *dest, const Object *src, int delete) deleteList(dest); FOR_POINTER_IN_LIST(src) { - if(POINTER->type == TYPE_LIST) { + if(isListy(*POINTER)) { nf_addToList(dest, *POINTER); tail(dest)->list = NULL; _copyList(tail(dest), POINTER, 0); @@ -592,6 +599,11 @@ inline Object startList(const Object start) return list; } +inline int isListy(const Object test) +{ + return test.type == TYPE_LIST || test.type == TYPE_SLIST; +} + inline int isStringy(const Object test) { return test.type == TYPE_STRING || test.type == TYPE_SYMBOL; @@ -603,6 +615,7 @@ inline int isValidType(const Object test) case TYPE_NUMBER: case TYPE_BOOL: case TYPE_LIST: + case TYPE_SLIST: case TYPE_FUNC: case TYPE_SYMBOL: case TYPE_LAMBDA: @@ -637,6 +650,7 @@ inline Object cloneList(const Object src) { Object list = listObject(); copyList(&list, &src); + list.type = src.type; return list; } @@ -649,6 +663,7 @@ inline Object cloneOther(const Object src) { inline Object cloneObject(const Object src) { switch(src.type) { + case TYPE_SLIST: case TYPE_LIST: return cloneList(src); case TYPE_LAMBDA: @@ -773,11 +788,10 @@ inline enum errorCode getErrorCode(const Object obj) #ifndef SIMPLE_ERRORS inline void errorAddContext(Object *o, const char* context) { - printf("o: %p\n", o); + //printf("o: %p\n", o); //printf("o->error: %s\n", o->error); - printf("o->error->context: %s\n", o->error->context); o->error->context = calloc(sizeof(char), RESULT_LENGTH); - printf("context: %p\n", context); + //printf("context: %p\n", context); strncpy(o->error->context, context, RESULT_LENGTH); } diff --git a/src/object.h b/src/object.h index ace6b20..0be627c 100644 --- a/src/object.h +++ b/src/object.h @@ -8,7 +8,7 @@ #define RESULT_LENGTH 128 #define FOR_POINTER_IN_LIST(_list) \ - if(_list && _list->type == TYPE_LIST) \ + if(_list && isListy(*_list)) \ for(Object *_element = _list->list; \ _element != NULL;\ _element = _element->forward) @@ -60,6 +60,7 @@ typedef enum Type { TYPE_NUMBER, TYPE_BOOL, TYPE_LIST, + TYPE_SLIST, TYPE_FUNC, TYPE_SYMBOL, TYPE_LAMBDA, @@ -132,6 +133,7 @@ void printAndClean(Object *target); void allocObject(Object **spot, const Object src); void appendList(Object *dest, const Object *src); +int isListy(const Object test); int isStringy(const Object test); int isValidType(const Object test); int isError(const Object obj, const enum errorCode err); diff --git a/src/pebblisp.c b/src/pebblisp.c index 645f9b6..6f157da 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -309,6 +309,12 @@ Object eval(const Object *obj, struct Environment *env) case TYPE_SYMBOL: return fetchFromEnvironment(obj->string, env); + case TYPE_SLIST: { + Object o = cloneObject(*obj); + o.type = TYPE_LIST; + return o; + } + case TYPE_LIST: return evalList(obj, env); @@ -630,7 +636,11 @@ Result parse(struct Slice *slices) struct Slice *token = slices; if(token && token->text) { struct Slice *rest = &slices[1]; - if(token->text[0] == '(') { + if(token->text[0] == '\'' && token->text[1] == '(') { + Result r = readSeq(&slices[2]); + r.obj.type = TYPE_SLIST; + return r; + } else if(token->text[0] == '(') { // todo check for null rest return readSeq(rest); } else { // todo error on missing close paren @@ -781,8 +791,12 @@ Object parseEval(const char *input, struct Environment *env) tok = &tok[i + 1]; i = -1; } - obj = eval(&parsed, env); - cleanObject(&parsed); + if (parsed.type == TYPE_SLIST) { + obj = parsed; + } else { + obj = eval(&parsed, env); + cleanObject(&parsed); + } } i++;