Start using switches to warn on unhandled types

This commit is contained in:
= 2020-05-23 18:01:15 +01:00
parent edf57a3050
commit f0a8f6ca43
3 changed files with 142 additions and 80 deletions

View File

@ -2,16 +2,16 @@ files = pebblisp.c tokens.c object.c env.c
exe = pebblisp exe = pebblisp
all: all:
gcc -g -O0 -o $(exe) -D STANDALONE $(files) && ./tests.sh gcc -g -O0 -Wall -o $(exe) -D STANDALONE $(files) && ./tests.sh
notest: notest:
gcc -g -O0 -o $(exe) -D STANDALONE $(files) gcc -g -O0 -Wall -o $(exe) -D STANDALONE $(files)
val: val:
gcc -g -O0 -o $(exe) -D STANDALONE $(files) && ./tests.sh -val gcc -g -O0 -Wall -o $(exe) -D STANDALONE $(files) && ./tests.sh -val
debug: debug:
gcc -g -O0 -o $(exe) -D STANDALONE -D DEBUG $(files) gcc -g -O0 -Wall -o $(exe) -D STANDALONE -D DEBUG $(files)
run: run:
./$(exe) ./$(exe)

View File

@ -95,14 +95,15 @@ inline int isEmpty(const Object *obj)
case TYPE_LAMBDA: case TYPE_LAMBDA:
return obj->lambda == NULL; return obj->lambda == NULL;
case TYPE_SYMBOL: case TYPE_SYMBOL:
return obj->string == NULL; case TYPE_STRING:
return obj->string == NULL || obj->string[0] == '\0';
case TYPE_FUNC: case TYPE_FUNC:
return obj->func == NULL; return obj->func == NULL;
case TYPE_ERROR: case TYPE_ERROR:
return obj->err == 0; return obj->err == 0;
default:
return 0;
} }
return 0;
} }
/** /**
@ -189,6 +190,26 @@ void nf_addToList(Object *dest, const Object src)
allocObject(&tail(dest)->forward, src); allocObject(&tail(dest)->forward, src);
} }
static const char *errorText[] = {
"MISMATCHED_PARENS",
"BAD_LIST_OF_SYMBOL_STRINGS",
"TYPE_LIST_NOT_CAUGHT",
"NULL_ENV",
"EMPTY_ENV",
"BUILT_IN_NOT_FOUND",
"NULL_PARSE",
"NULL_LAMBDA_LIST",
"NULL_MAP_ARGS",
"LAMBDA_ARGS_NOT_LIST",
"DID_NOT_FIND_SYMBOL",
"BAD_TYPE",
"UNEXPECTED_FORM",
"LISTS_NOT_SAME_SIZE",
"SYMBOLS_CANT_START_WITH_DIGITS",
"UNSUPPORTED_NUMBER_TYPE",
"NOT_A_SYMBOL"
};
/** /**
* Prints out the error of a given error Object * Prints out the error of a given error Object
* Doesn't print anything if `obj` is NULL or not an error type * Doesn't print anything if `obj` is NULL or not an error type
@ -247,22 +268,33 @@ char* stringObj(char *dest, const Object *obj)
if(!dest || !obj) if(!dest || !obj)
return NULL; return NULL;
const Type t = obj->type; switch(obj->type) {
case TYPE_NUMBER:
if(t == TYPE_NUMBER) { snprintf(dest, RESULT_LENGTH, "%d", obj->number);
snprintf(dest, RESULT_LENGTH, "%d", obj->number); break;
} else if(t == TYPE_BOOL) { case TYPE_BOOL:
snprintf(dest, RESULT_LENGTH, "%s", obj->number ? "T" : "F"); snprintf(dest, RESULT_LENGTH, "%s", obj->number ? "T" : "F");
} else if(t == TYPE_STRING || t == TYPE_SYMBOL) { break;
snprintf(dest, RESULT_LENGTH, "%s", obj->string); case TYPE_STRING:
} else if(t == TYPE_LIST) { snprintf(dest, RESULT_LENGTH, "%s", obj->string);
stringList(dest, obj); break;
} else if(t == TYPE_ERROR) { case TYPE_SYMBOL:
snprintf(dest, RESULT_LENGTH, "E%d", obj->err); snprintf(dest, RESULT_LENGTH, "`%s`", obj->string);
} else { break;
snprintf(dest, RESULT_LENGTH, "X%d", obj->number); case TYPE_LIST:
stringList(dest, obj);
break;
case TYPE_ERROR:
snprintf(dest, RESULT_LENGTH, "E%d", obj->err);
break;
case TYPE_FUNC:
case TYPE_LAMBDA:
snprintf(dest, RESULT_LENGTH, "X%d", obj->number);
} }
if(!isValidType(*obj))
snprintf(dest, RESULT_LENGTH, "BAD_TYPE(%d) X%d", obj->type, obj->number);
return dest; return dest;
} }
@ -281,27 +313,39 @@ void debugObj(const Object *obj)
void _printList(const Object *list, int newline); void _printList(const Object *list, int newline);
void _printObj(const Object *obj, int newline) void _printObj(const Object *obj, int newline)
{ {
if(obj->type == TYPE_NUMBER) { switch(obj->type) {
printd("TYPE_NUMBER"); case TYPE_NUMBER:
} else if(obj->type == TYPE_BOOL) { printd("TYPE_NUMBER");
printd("TYPE_BOOL"); break;
} else if(obj->type == TYPE_LIST) { case TYPE_BOOL:
printd("TYPE_LIST\n"); printd("TYPE_BOOL");
} else if(obj->type == TYPE_FUNC) { break;
printd("TYPE_FUNC"); case TYPE_LIST:
} else if(obj->type == TYPE_SYMBOL) { printd("TYPE_LIST\n");
printd("TYPE_SYMBOL"); break;
} else if(obj->type == TYPE_LAMBDA) { case TYPE_FUNC:
printd("TYPE_LAMBDA Params:\n"); printd("TYPE_FUNC");
printObj(&obj->lambda->params); break;
printd("Lambda Body: \n"); case TYPE_SYMBOL:
printObj(&obj->lambda->body); printd("TYPE_SYMBOL");
return; break;
} else if(obj->type == TYPE_ERROR) { case TYPE_STRING:
printd("TYPE_ERROR: "); printd("TYPE_STRING");
} else { break;
printd("TYPE_OTHER (as int)"); case TYPE_LAMBDA:
printd("TYPE_LAMBDA Params:\n");
printObj(&obj->lambda->params);
printd("Lambda Body: \n");
printObj(&obj->lambda->body);
return;
case TYPE_ERROR:
printd("TYPE_ERROR: ");
break;
} }
if(!isValidType(*obj))
printd("TYPE_OTHER (as int)");
char temp[100] = ""; char temp[100] = "";
stringObj(temp, obj); stringObj(temp, obj);
if(newline) if(newline)
@ -360,17 +404,27 @@ void cleanObject(Object *target)
if(target == NULL) if(target == NULL)
return; return;
const Type t = target->type; switch(target->type) {
if(t == TYPE_STRING || t == TYPE_SYMBOL) { case TYPE_STRING:
free(target->string); case TYPE_SYMBOL:
target->string = NULL; free(target->string);
} else if(t == TYPE_LIST) { target->string = NULL;
deleteList(target); break;
} else if(t == TYPE_LAMBDA) { case TYPE_LIST:
cleanObject(&target->lambda->params); deleteList(target);
cleanObject(&target->lambda->body); break;
free(target->lambda); case TYPE_LAMBDA:
cleanObject(&target->lambda->params);
cleanObject(&target->lambda->body);
free(target->lambda);
break;
case TYPE_BOOL:
case TYPE_NUMBER:
case TYPE_FUNC:
case TYPE_ERROR:
break;
} }
target->forward = NULL; target->forward = NULL;
} }
@ -493,9 +547,26 @@ inline Object startList(const Object start)
return list; return list;
} }
inline int isStringy(const Object src) inline int isStringy(const Object test)
{ {
return src.type == TYPE_STRING || src.type == TYPE_SYMBOL; return test.type == TYPE_STRING || test.type == TYPE_SYMBOL;
}
inline int isValidType(const Object test)
{
switch(test.type) {
case TYPE_NUMBER:
case TYPE_BOOL:
case TYPE_LIST:
case TYPE_FUNC:
case TYPE_SYMBOL:
case TYPE_LAMBDA:
case TYPE_STRING:
case TYPE_ERROR:
return 1;
}
return 0;
} }
/** /**
@ -525,10 +596,22 @@ inline Object cloneList(const Object src)
inline Object cloneObject(const Object src) inline Object cloneObject(const Object src)
{ {
return src.type == TYPE_LIST? cloneList(src) : switch(src.type) {
src.type == TYPE_LAMBDA? cloneLambda(src) : case TYPE_LIST:
isStringy(src)? cloneString(src) : return cloneList(src);
src; case TYPE_LAMBDA:
return cloneLambda(src);
case TYPE_STRING:
case TYPE_SYMBOL:
return cloneString(src);
case TYPE_BOOL:
case TYPE_NUMBER:
case TYPE_FUNC:
case TYPE_ERROR:
; // Fall through to plain return
}
return src;
} }
inline Object numberObject(int num) inline Object numberObject(int num)

View File

@ -39,28 +39,6 @@ enum errorCode {
NOT_A_SYMBOL NOT_A_SYMBOL
}; };
//#ifdef STANDALONE
static const char *errorText[] = {
"MISMATCHED_PARENS",
"BAD_LIST_OF_SYMBOL_STRINGS",
"TYPE_LIST_NOT_CAUGHT",
"NULL_ENV",
"EMPTY_ENV",
"BUILT_IN_NOT_FOUND",
"NULL_PARSE",
"NULL_LAMBDA_LIST",
"NULL_MAP_ARGS",
"LAMBDA_ARGS_NOT_LIST",
"DID_NOT_FIND_SYMBOL",
"BAD_TYPE",
"UNEXPECTED_FORM",
"LISTS_NOT_SAME_SIZE",
"SYMBOLS_CANT_START_WITH_DIGITS",
"UNSUPPORTED_NUMBER_TYPE",
"NOT_A_SYMBOL"
};
//#endif
#define MALLOC_FLAG 64 #define MALLOC_FLAG 64
typedef enum Type { typedef enum Type {
@ -121,7 +99,8 @@ 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 isStringy(const Object src); int isStringy(const Object test);
int isValidType(const Object test);
Object cloneList(const Object src); Object cloneList(const Object src);
Object cloneString(Object obj); Object cloneString(Object obj);