Added more error-catching
This commit is contained in:
parent
944d9287dc
commit
1da347e612
|
@ -6,3 +6,6 @@ debug:
|
||||||
|
|
||||||
phrase:
|
phrase:
|
||||||
gcc -g -O0 -o pebblisp -D STANDALONE -D DEBUG -D NO_REPL pebblisp.c tokens.c object.c
|
gcc -g -O0 -o pebblisp -D STANDALONE -D DEBUG -D NO_REPL pebblisp.c tokens.c object.c
|
||||||
|
|
||||||
|
run:
|
||||||
|
./pebblisp
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define MAX_ENV_ELM 15 // 50
|
#define MAX_ENV_ELM 15 // 50
|
||||||
|
|
||||||
enum errorCode {
|
enum errorCode {
|
||||||
|
MISMATCHED_PARENS,
|
||||||
BAD_LIST_OF_SYMBOL_STRINGS,
|
BAD_LIST_OF_SYMBOL_STRINGS,
|
||||||
TYPE_LIST_NOT_CAUGHT,
|
TYPE_LIST_NOT_CAUGHT,
|
||||||
NULL_ENV,
|
NULL_ENV,
|
||||||
|
@ -21,6 +22,7 @@ enum errorCode {
|
||||||
|
|
||||||
//#ifdef STANDALONE
|
//#ifdef STANDALONE
|
||||||
static const char *errorText[] = {
|
static const char *errorText[] = {
|
||||||
|
"MISMATCHED_PARENS",
|
||||||
"BAD_LIST_OF_SYMBOL_STRINGS",
|
"BAD_LIST_OF_SYMBOL_STRINGS",
|
||||||
"TYPE_LIST_NOT_CAUGHT",
|
"TYPE_LIST_NOT_CAUGHT",
|
||||||
"NULL_ENV",
|
"NULL_ENV",
|
||||||
|
|
|
@ -22,6 +22,8 @@ void debugSlice(struct Slice *s)
|
||||||
printd("Debug Slice\n text:'");
|
printd("Debug Slice\n text:'");
|
||||||
for(int i = 0; i < s->length; i++) {
|
for(int i = 0; i < s->length; i++) {
|
||||||
printd("%c", s->text[i]);
|
printd("%c", s->text[i]);
|
||||||
|
if(s->text[i] == '\0')
|
||||||
|
printd("NULLCHAR\n");
|
||||||
}
|
}
|
||||||
printd("'\n");
|
printd("'\n");
|
||||||
printd(" length: %d\n", s->length);
|
printd(" length: %d\n", s->length);
|
||||||
|
@ -61,7 +63,7 @@ Result parse(struct Slice *slices)
|
||||||
if(token->text[0] == '(') {
|
if(token->text[0] == '(') {
|
||||||
// todo check for null rest
|
// todo check for null rest
|
||||||
return readSeq(rest);
|
return readSeq(rest);
|
||||||
} else { // todo error on closed paren
|
} else { // todo error on missing close paren
|
||||||
return result(parseAtom(token), rest);
|
return result(parseAtom(token), rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,6 +111,7 @@ Object evalDefArgs(const Object *arg_forms, struct Environment *env)
|
||||||
const Object *first_form = &arg_forms[0];
|
const Object *first_form = &arg_forms[0];
|
||||||
const char *name = first_form->name;
|
const char *name = first_form->name;
|
||||||
|
|
||||||
|
// Immediately adding the function to the env might allow recursion?
|
||||||
Object second_eval = eval(first_form->forward, env);
|
Object second_eval = eval(first_form->forward, env);
|
||||||
|
|
||||||
addToEnv(env, name, second_eval);
|
addToEnv(env, name, second_eval);
|
||||||
|
@ -126,7 +129,7 @@ Object evalIfArgs(const Object *arg_forms, struct Environment *env)
|
||||||
Object evalLambdaArgs(const Object *arg_forms)
|
Object evalLambdaArgs(const Object *arg_forms)
|
||||||
{
|
{
|
||||||
// params // body
|
// params // body
|
||||||
return constructLambda(arg_forms, arg_forms->forward);
|
return constructLambda(arg_forms, arg_forms? arg_forms->forward : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object evalMapArgs(const Object *arg_forms, struct Environment *env)
|
Object evalMapArgs(const Object *arg_forms, struct Environment *env)
|
||||||
|
@ -137,14 +140,12 @@ Object evalMapArgs(const Object *arg_forms, struct Environment *env)
|
||||||
const Object lambda = eval(&arg_forms[0], env);
|
const Object lambda = eval(&arg_forms[0], env);
|
||||||
Object *oldList = (&arg_forms[0])->forward;
|
Object *oldList = (&arg_forms[0])->forward;
|
||||||
|
|
||||||
if(lambda.type != TYPE_LAMBDA || oldList->type != TYPE_LIST) {
|
if(lambda.type != TYPE_LAMBDA || oldList->type != TYPE_LIST)
|
||||||
return errorObject(BAD_TYPE);
|
return errorObject(BAD_TYPE);
|
||||||
}
|
|
||||||
|
|
||||||
Object list = listObject();
|
Object list = listObject();
|
||||||
|
|
||||||
int i = 0;
|
const Object *oldElement = oldList->list;
|
||||||
Object *oldElement = oldList->list;
|
|
||||||
while(oldElement != NULL) {
|
while(oldElement != NULL) {
|
||||||
// Create a new list for each element in the list,
|
// Create a new list for each element in the list,
|
||||||
// since lambda evaluation looks for a list
|
// since lambda evaluation looks for a list
|
||||||
|
@ -152,7 +153,6 @@ Object evalMapArgs(const Object *arg_forms, struct Environment *env)
|
||||||
Object listBack[1] = {*oldElement};
|
Object listBack[1] = {*oldElement};
|
||||||
listBack[0].forward = NULL;
|
listBack[0].forward = NULL;
|
||||||
tempList.list = listBack;
|
tempList.list = listBack;
|
||||||
printObj(&tempList);
|
|
||||||
|
|
||||||
struct Environment newEnv =
|
struct Environment newEnv =
|
||||||
envForLambda(&lambda.lambda->params, &tempList, env);
|
envForLambda(&lambda.lambda->params, &tempList, env);
|
||||||
|
@ -192,7 +192,6 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms,
|
||||||
const char *n = itemAt(params, i)->name;
|
const char *n = itemAt(params, i)->name;
|
||||||
addToEnv(&env, n, eval(&arg_forms[i], outer)); // May not need eval?
|
addToEnv(&env, n, eval(&arg_forms[i], outer)); // May not need eval?
|
||||||
// SHOULD BE `vs` not arg_forms???
|
// SHOULD BE `vs` not arg_forms???
|
||||||
|
|
||||||
} // Something is segfaulting, anyway
|
} // Something is segfaulting, anyway
|
||||||
// env.strings[length] = NULL;
|
// env.strings[length] = NULL;
|
||||||
|
|
||||||
|
@ -432,6 +431,8 @@ struct Environment defaultEnv() {
|
||||||
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)
|
||||||
|
return errorObject(MISMATCHED_PARENS);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
struct Slice *debug = tokens;
|
struct Slice *debug = tokens;
|
||||||
if(debug) {
|
if(debug) {
|
||||||
|
|
|
@ -63,6 +63,10 @@ struct Slice *nf_tokenize(const char *input)
|
||||||
parens++;
|
parens++;
|
||||||
} else if (input[i] == ')') {
|
} else if (input[i] == ')') {
|
||||||
parens--;
|
parens--;
|
||||||
|
if(parens < 0) {
|
||||||
|
free(slices);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isSingle(input[i])) {
|
if(isSingle(input[i])) {
|
||||||
|
|
Loading…
Reference in New Issue