Some type-check functions. Consistent 'if' styling
This commit is contained in:
parent
6a2e12ebfe
commit
0c9c876d00
15
src/object.c
15
src/object.c
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue