Add TYPE_SLIST.

Not yet stable, but allows manipulation of lists without immediate
evaluation.
This commit is contained in:
Sage Vaillancourt 2021-12-15 14:30:16 -05:00 committed by Sage Vaillancourt
parent 5261880ebb
commit 55d39431b1
3 changed files with 47 additions and 17 deletions

View File

@ -23,7 +23,7 @@
*/ */
int listLength(const Object *listObj) int listLength(const Object *listObj)
{ {
if(!listObj || listObj->type != TYPE_LIST) if(!listObj || !isListy(*listObj))
return -1; return -1;
int len = 0; 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) Object *itemAt(const Object *listObj, int n)
{ {
if(!listObj || listObj->type != TYPE_LIST) if(!listObj || !isListy(*listObj))
return NULL; return NULL;
FOR_POINTER_IN_LIST(listObj) { FOR_POINTER_IN_LIST(listObj) {
@ -67,7 +67,7 @@ Object *itemAt(const Object *listObj, int n)
*/ */
Object *tail(const Object *listObj) Object *tail(const Object *listObj)
{ {
if(!listObj || listObj->type != TYPE_LIST) if(!listObj || !isListy(*listObj))
return NULL; return NULL;
Object *tail = NULL; Object *tail = NULL;
@ -96,6 +96,7 @@ inline int isEmpty(const Object *obj)
case TYPE_BOOL: case TYPE_BOOL:
return obj->number == 0; return obj->number == 0;
case TYPE_LIST: case TYPE_LIST:
case TYPE_SLIST:
return obj->list == NULL; return obj->list == NULL;
case TYPE_LAMBDA: case TYPE_LAMBDA:
return obj->lambda == NULL; return obj->lambda == NULL;
@ -139,7 +140,7 @@ void allocObject(Object **spot, const Object src)
*/ */
void insertIntoList(Object *dest, int ind, const Object src) void insertIntoList(Object *dest, int ind, const Object src)
{ {
if(!dest || dest->type != TYPE_LIST) if(!dest || !isListy(*dest))
return; return;
// Merely append, when possible // 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 * 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 * Attempts to clean the replaced Object before adding the new one
* Immediately returns if `list` is NULL or not a list type * Immediately returns if `list` is NULL or not a list type
*
* @param list The list Object to replace an element of * @param list The list Object to replace an element of
* @param i The index of the element to replace * @param i The index of the element to replace
* @param src The Object to copy into the list * @param src The Object to copy into the list
*/ */
void replaceListing(Object *list, int i, const Object src) void replaceListing(Object *list, int i, const Object src)
{ {
if(!list || list->type != TYPE_LIST) if(!list || isListy(*list))
return; return;
Object *replace = itemAt(list, i); Object *replace = itemAt(list, i);
Object *oldForward = replace->forward; 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) void nf_addToList(Object *dest, const Object src)
{ {
if(!dest || dest->type != TYPE_LIST) if(!dest || !isListy(*dest))
return; return;
if(isEmpty(dest)) { if(isEmpty(dest)) {
@ -233,7 +235,7 @@ static const char *errorText[] = {
*/ */
void stringList(char *dest, const Object *obj) void stringList(char *dest, const Object *obj)
{ {
if(!dest || obj->type != TYPE_LIST) if(!dest || !isListy(*obj))
return; return;
dest[0] = '('; dest[0] = '(';
@ -282,6 +284,7 @@ char* stringNObj(char *dest, const Object *obj, const size_t len) {
snprintf(dest, len, "`%s`", obj->string); snprintf(dest, len, "`%s`", obj->string);
break; break;
case TYPE_LIST: case TYPE_LIST:
case TYPE_SLIST:
stringList(dest, obj); stringList(dest, obj);
break; break;
case TYPE_ERROR: { case TYPE_ERROR: {
@ -342,6 +345,9 @@ void printType(const Object *obj)
case TYPE_LIST: case TYPE_LIST:
printf("TYPE_LIST"); printf("TYPE_LIST");
return; return;
case TYPE_SLIST:
printf("TYPE_SLIST");
return;
case TYPE_FUNC: case TYPE_FUNC:
printf("TYPE_FUNC"); printf("TYPE_FUNC");
return; return;
@ -443,6 +449,7 @@ void cleanObject(Object *target)
target->string = NULL; target->string = NULL;
break; break;
case TYPE_LIST: case TYPE_LIST:
case TYPE_SLIST:
deleteList(target); deleteList(target);
break; break;
case TYPE_LAMBDA: case TYPE_LAMBDA:
@ -494,7 +501,7 @@ void deleteList(Object *dest)
if(!dest) if(!dest)
return; return;
if(dest->type != TYPE_LIST) { if(!isListy(*dest)) {
printf("Tried to delete something other than a list\n"); printf("Tried to delete something other than a list\n");
return; return;
} }
@ -515,7 +522,7 @@ void _copyList(Object *dest, const Object *src, int delete)
printd("NULL\n"); printd("NULL\n");
return; return;
} }
if(dest->type != TYPE_LIST || src->type != TYPE_LIST) { if(!isListy(*dest) || !isListy(*src)) {
printd("NOT A LIST\n"); printd("NOT A LIST\n");
return; return;
} }
@ -524,7 +531,7 @@ void _copyList(Object *dest, const Object *src, int delete)
deleteList(dest); deleteList(dest);
FOR_POINTER_IN_LIST(src) { FOR_POINTER_IN_LIST(src) {
if(POINTER->type == TYPE_LIST) { if(isListy(*POINTER)) {
nf_addToList(dest, *POINTER); nf_addToList(dest, *POINTER);
tail(dest)->list = NULL; tail(dest)->list = NULL;
_copyList(tail(dest), POINTER, 0); _copyList(tail(dest), POINTER, 0);
@ -592,6 +599,11 @@ inline Object startList(const Object start)
return list; return list;
} }
inline int isListy(const Object test)
{
return test.type == TYPE_LIST || test.type == TYPE_SLIST;
}
inline int isStringy(const Object test) inline int isStringy(const Object test)
{ {
return test.type == TYPE_STRING || test.type == TYPE_SYMBOL; return test.type == TYPE_STRING || test.type == TYPE_SYMBOL;
@ -603,6 +615,7 @@ inline int isValidType(const Object test)
case TYPE_NUMBER: case TYPE_NUMBER:
case TYPE_BOOL: case TYPE_BOOL:
case TYPE_LIST: case TYPE_LIST:
case TYPE_SLIST:
case TYPE_FUNC: case TYPE_FUNC:
case TYPE_SYMBOL: case TYPE_SYMBOL:
case TYPE_LAMBDA: case TYPE_LAMBDA:
@ -637,6 +650,7 @@ inline Object cloneList(const Object src)
{ {
Object list = listObject(); Object list = listObject();
copyList(&list, &src); copyList(&list, &src);
list.type = src.type;
return list; return list;
} }
@ -649,6 +663,7 @@ inline Object cloneOther(const Object src) {
inline Object cloneObject(const Object src) inline Object cloneObject(const Object src)
{ {
switch(src.type) { switch(src.type) {
case TYPE_SLIST:
case TYPE_LIST: case TYPE_LIST:
return cloneList(src); return cloneList(src);
case TYPE_LAMBDA: case TYPE_LAMBDA:
@ -773,11 +788,10 @@ inline enum errorCode getErrorCode(const Object obj)
#ifndef SIMPLE_ERRORS #ifndef SIMPLE_ERRORS
inline void errorAddContext(Object *o, const char* context) 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: %s\n", o->error);
printf("o->error->context: %s\n", o->error->context);
o->error->context = calloc(sizeof(char), RESULT_LENGTH); 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); strncpy(o->error->context, context, RESULT_LENGTH);
} }

View File

@ -8,7 +8,7 @@
#define RESULT_LENGTH 128 #define RESULT_LENGTH 128
#define FOR_POINTER_IN_LIST(_list) \ #define FOR_POINTER_IN_LIST(_list) \
if(_list && _list->type == TYPE_LIST) \ if(_list && isListy(*_list)) \
for(Object *_element = _list->list; \ for(Object *_element = _list->list; \
_element != NULL;\ _element != NULL;\
_element = _element->forward) _element = _element->forward)
@ -60,6 +60,7 @@ typedef enum Type {
TYPE_NUMBER, TYPE_NUMBER,
TYPE_BOOL, TYPE_BOOL,
TYPE_LIST, TYPE_LIST,
TYPE_SLIST,
TYPE_FUNC, TYPE_FUNC,
TYPE_SYMBOL, TYPE_SYMBOL,
TYPE_LAMBDA, TYPE_LAMBDA,
@ -132,6 +133,7 @@ void printAndClean(Object *target);
void allocObject(Object **spot, const Object src); void allocObject(Object **spot, const Object src);
void appendList(Object *dest, const Object *src); void appendList(Object *dest, const Object *src);
int isListy(const Object test);
int isStringy(const Object test); int isStringy(const Object test);
int isValidType(const Object test); int isValidType(const Object test);
int isError(const Object obj, const enum errorCode err); int isError(const Object obj, const enum errorCode err);

View File

@ -309,6 +309,12 @@ Object eval(const Object *obj, struct Environment *env)
case TYPE_SYMBOL: case TYPE_SYMBOL:
return fetchFromEnvironment(obj->string, env); return fetchFromEnvironment(obj->string, env);
case TYPE_SLIST: {
Object o = cloneObject(*obj);
o.type = TYPE_LIST;
return o;
}
case TYPE_LIST: case TYPE_LIST:
return evalList(obj, env); return evalList(obj, env);
@ -630,7 +636,11 @@ Result parse(struct Slice *slices)
struct Slice *token = slices; struct Slice *token = slices;
if(token && token->text) { if(token && token->text) {
struct Slice *rest = &slices[1]; 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 // todo check for null rest
return readSeq(rest); return readSeq(rest);
} else { // todo error on missing close paren } else { // todo error on missing close paren
@ -781,9 +791,13 @@ Object parseEval(const char *input, struct Environment *env)
tok = &tok[i + 1]; tok = &tok[i + 1];
i = -1; i = -1;
} }
if (parsed.type == TYPE_SLIST) {
obj = parsed;
} else {
obj = eval(&parsed, env); obj = eval(&parsed, env);
cleanObject(&parsed); cleanObject(&parsed);
} }
}
i++; i++;
} }