Some type-check functions. Consistent 'if' styling

This commit is contained in:
Sage Vaillancourt 2021-07-04 23:48:26 -04:00
parent 6a2e12ebfe
commit 0c9c876d00
3 changed files with 56 additions and 20 deletions

View File

@ -718,6 +718,21 @@ inline int isError(const Object obj, const enum errorCode err)
return obj.type == TYPE_ERROR && obj.err == err; return obj.type == TYPE_ERROR && obj.err == err;
} }
inline int bothAre(const enum Type type, const Object *obj1, const Object *obj2)
{
return (obj1->type == type) && (obj2->type == type);
}
inline int eitherIs(const enum Type type, const Object *o1, const Object *o2)
{
return (o1->type == type) || (o2->type == type);
}
inline int areSameType(const Object *obj1, const Object *obj2)
{
return obj1->type == obj2->type;
}
inline Object otherObject() inline Object otherObject()
{ {
Object o = newObject(TYPE_OTHER); Object o = newObject(TYPE_OTHER);

View File

@ -115,6 +115,9 @@ void appendList(Object *dest, const Object *src);
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);
int bothAre(const enum Type type, const Object *obj1, const Object *obj2);
int eitherIs(const enum Type type, const Object *obj1, const Object *obj2);
int areSameType(const Object *obj1, const Object *obj2);
Object cloneList(const Object src); Object cloneList(const Object src);
Object cloneString(Object obj); Object cloneString(Object obj);

View File

@ -25,7 +25,7 @@ Object evalDefArgs(const Object *symbol, const Object *value, struct Environment
const char *name = symbol->string; const char *name = symbol->string;
// Handles multi-definitions // Handles multi-definitions
if(symbol->type == TYPE_LIST && value->type == TYPE_LIST if(bothAre(TYPE_LIST, symbol, value)
&& listLength(symbol) == listLength(value)) { && listLength(symbol) == listLength(value)) {
FOR_POINTERS_IN_LISTS(symbol, value) { FOR_POINTERS_IN_LISTS(symbol, value) {
Object finalValue = eval(P2, env); Object finalValue = eval(P2, env);
@ -60,15 +60,17 @@ Object evalLambdaArgs(const Object *argForms)
Object evalMapArgs(const Object *argForms, struct Environment *env) Object evalMapArgs(const Object *argForms, struct Environment *env)
{ {
if(!argForms) if(!argForms) {
return errorObject(NULL_MAP_ARGS); return errorObject(NULL_MAP_ARGS);
}
Object lambda = eval(argForms, env); Object lambda = eval(argForms, env);
const Object *inputList = argForms->forward; const Object *inputList = argForms->forward;
Object outputList = listObject(); Object outputList = listObject();
if(lambda.type != TYPE_LAMBDA) if(lambda.type != TYPE_LAMBDA) {
return errorObject(BAD_TYPE); return errorObject(BAD_TYPE);
}
FOR_POINTER_IN_LIST(inputList) { FOR_POINTER_IN_LIST(inputList) {
// Create a new list for each element, // Create a new list for each element,
@ -232,12 +234,14 @@ Object evalList(const Object *obj, struct Environment *env)
{ {
const int evalLength = listLength(obj); const int evalLength = listLength(obj);
if(evalLength == 0) if(evalLength == 0) {
return cloneObject(*obj); return cloneObject(*obj);
}
if(evalLength == 1) { if(evalLength == 1) {
if(listLength(obj->list) == 0) if(listLength(obj->list) == 0) {
return cloneObject(*obj); return cloneObject(*obj);
}
return startList(cloneObject(eval(obj->list, env))); return startList(cloneObject(eval(obj->list, env)));
} }
@ -328,9 +332,10 @@ Object catObjects(const Object obj1, const Object obj2, struct Environment *env)
Object listEquality(const Object *list1, const Object *list2) Object listEquality(const Object *list1, const Object *list2)
{ {
FOR_POINTERS_IN_LISTS(list1, list2) { FOR_POINTERS_IN_LISTS(list1, list2) {
if(P1->type != P2->type || P1->number != P2->number) if(P1->type != P2->type || P1->number != P2->number) {
return boolObject(0); return boolObject(0);
} }
}
return boolObject(1); return boolObject(1);
} }
@ -342,8 +347,9 @@ Object _basicOp(const Object *obj1, const Object *obj2, const char op,
switch(op){ switch(op){
case '+': case '+':
if(obj1->type == TYPE_STRING || obj2->type == TYPE_STRING) if(eitherIs(TYPE_STRING, obj1, obj2)) {
return catObjects(*obj1, *obj2, env); return catObjects(*obj1, *obj2, env);
}
return numberObject(n1 + n2); return numberObject(n1 + n2);
case '-': case '-':
return numberObject(n1 - n2); return numberObject(n1 - n2);
@ -355,11 +361,13 @@ Object _basicOp(const Object *obj1, const Object *obj2, const char op,
return numberObject(n1 % n2); return numberObject(n1 % n2);
case '=': case '=':
if(obj1->type == TYPE_STRING && obj2->type == TYPE_STRING) if(bothAre(TYPE_STRING, obj1, obj2)) {
return boolObject(!strcmp(obj1->string, obj2->string)); return boolObject(!strcmp(obj1->string, obj2->string));
if(obj1->type == TYPE_LIST && obj2->type == TYPE_LIST) }
if(bothAre(TYPE_LIST, obj1, obj2)) {
return listEquality(obj1, obj2); return listEquality(obj1, obj2);
return boolObject(n1 == n2 && obj1->type == obj2->type); }
return boolObject(n1 == n2 && areSameType(obj1, obj2));
case '>': case '>':
return boolObject(n1 > n2); return boolObject(n1 > n2);
case '<': case '<':
@ -372,8 +380,9 @@ Object _basicOp(const Object *obj1, const Object *obj2, const char op,
Object basicOp(const Object *obj1, const Object *obj2, const char op, Object basicOp(const Object *obj1, const Object *obj2, const char op,
struct Environment *env) struct Environment *env)
{ {
if(isError(*obj2, ONLY_ONE_ARGUMENT)) if(isError(*obj2, ONLY_ONE_ARGUMENT)) {
return *obj2; return *obj2;
}
int lists = (obj1->type == TYPE_LIST) + (obj2->type == TYPE_LIST); int lists = (obj1->type == TYPE_LIST) + (obj2->type == TYPE_LIST);
if(lists == 0) { if(lists == 0) {
@ -461,8 +470,9 @@ Object rest(Object list, Object ignore, struct Environment *env)
Object ret = listObject(); Object ret = listObject();
Object *l = &list; Object *l = &list;
FOR_POINTER_IN_LIST(l) { FOR_POINTER_IN_LIST(l) {
if(POINTER == l->list) if(POINTER == l->list) {
continue; continue;
}
nf_addToList(&ret, cloneObject(*POINTER)); nf_addToList(&ret, cloneObject(*POINTER));
} }
return ret; return ret;
@ -477,9 +487,10 @@ Object reverse(Object _list, Object ignore, struct Environment *ignore2)
FOR_POINTER_IN_LIST(list) { FOR_POINTER_IN_LIST(list) {
Object *oldTail = tail; Object *oldTail = tail;
allocObject(&tail, cloneObject(*POINTER)); allocObject(&tail, cloneObject(*POINTER));
if(oldTail) if(oldTail) {
tail->forward = oldTail; tail->forward = oldTail;
} }
}
rev.list = tail; rev.list = tail;
return rev; return rev;
@ -553,8 +564,9 @@ Object takeInput(Object i1, Object i2, struct Environment *i3)
void copySlice(char * dest, struct Slice *src) void copySlice(char * dest, struct Slice *src)
{ {
if(!dest || !src) if(!dest || !src) {
return; return;
}
strncpy(dest, src->text, src->length); strncpy(dest, src->text, src->length);
dest[(int)src->length] = '\0'; dest[(int)src->length] = '\0';
} }
@ -568,9 +580,10 @@ void debugSlice(struct Slice *s)
printf("Debug Slice\n text:'"); printf("Debug Slice\n text:'");
for(int i = 0; i < s->length; i++) { for(int i = 0; i < s->length; i++) {
printf("%c", s->text[i]); printf("%c", s->text[i]);
if(s->text[i] == '\0') if(s->text[i] == '\0') {
printf("NULLCHAR\n"); printf("NULLCHAR\n");
} }
}
printf("'\n"); printf("'\n");
printf(" length: %d\n", s->length); printf(" length: %d\n", s->length);
} }
@ -601,8 +614,9 @@ Result readSeq(struct Slice *tokens)
return (Result){res, rest}; return (Result){res, rest};
} }
Result r = parse(tokens); Result r = parse(tokens);
if(r.obj.type == TYPE_ERROR) if(r.obj.type == TYPE_ERROR) {
return r; return r;
}
nf_addToList(&res, cloneObject(r.obj)); nf_addToList(&res, cloneObject(r.obj));
tokens = r.slices; tokens = r.slices;
cleanObject(&r.obj); cleanObject(&r.obj);
@ -681,10 +695,12 @@ Object parseAtom(struct Slice *s)
Object parseEval(const char *input, struct Environment *env) Object parseEval(const char *input, struct Environment *env)
{ {
struct Slice *tokens = nf_tokenize(input); struct Slice *tokens = nf_tokenize(input);
if(!tokens) if(!tokens) {
return errorObject(MISMATCHED_PARENS); return errorObject(MISMATCHED_PARENS);
if(!tokens->text) }
if(!tokens->text) {
return symFromSlice(" ", 1); return symFromSlice(" ", 1);
}
#ifdef DEBUG #ifdef DEBUG
struct Slice *debug = tokens; struct Slice *debug = tokens;
@ -713,8 +729,9 @@ Object parseEval(const char *input, struct Environment *env)
if(parens == 0) { if(parens == 0) {
cleanObject(&obj); cleanObject(&obj);
Object parsed = parse(tok).obj; Object parsed = parse(tok).obj;
if(parsed.type == TYPE_ERROR) if(parsed.type == TYPE_ERROR) {
return parsed; return parsed;
}
if(tok[i].text[0] == ')') { if(tok[i].text[0] == ')') {
tok = &tok[i + 1]; tok = &tok[i + 1];
i = -1; i = -1;
@ -753,9 +770,10 @@ int readFile(const char *filename, struct Environment *env) {
} else { } else {
int j = 0; int j = 0;
for(j = i; j < LINE_MAX; j++) { for(j = i; j < LINE_MAX; j++) {
if(line[j] == ';' || line[j] == '\0') if(line[j] == ';' || line[j] == '\0') {
break; break;
} }
}
strncat(page, line, j); strncat(page, line, j);
strcat(page, " "); strcat(page, " ");
break; break;