Add detailed error reporting, remove panics
diff --git a/src/lisp/lisp.c b/src/lisp/lisp.c
index 6ed3fb9..64ab9ae 100644
--- a/src/lisp/lisp.c
+++ b/src/lisp/lisp.c
@@ -1,4 +1,5 @@
#include "lisp.h"
+#include "error.h"
#include "plat/plat.h"
#include <ctype.h>
@@ -15,28 +16,6 @@
unsigned char max_pool = 0, current_pool = 0;
-__attribute__((noreturn)) void err(const char *msg)
-{
- fprintf(stderr, "ERROR: %s\n", msg);
- exit(1);
-}
-
-__attribute__((noreturn)) void err_at(value_t form, const char *msg, ...)
-{
- int line = cons_line(form);
- char *file = cons_file(form);
-
- fprintf(stderr, "\033[31merror at\033[0m %s:%d\n", file, line);
-
- va_list list;
- va_start(list, msg);
- vfprintf(stderr, msg, list);
- va_end(list);
- fprintf(stderr, "\n");
-
- exit(1);
-}
-
value_t intval(int i)
{
i <<= 2;
@@ -116,12 +95,14 @@
return isalpha(c) || isallowedchar(c) || isdigit(c);
}
-bool readsym(struct istream *is, value_t *val)
+struct error readsym(struct istream *is, value_t *val)
{
+ E_INIT();
+
skipws(is);
if (!issymstart(is->peek(is)))
- return false;
+ THROWSAFE(EEXPECTED);
int size = 8;
struct alloc *a = malloc_aligned(size + sizeof(struct alloc));
@@ -150,17 +131,20 @@
*val |= SYMBOL_TAG;
add_this_alloc(a, SYMBOL_TAG);
- return true;
+
+ OKAY();
}
}
}
-bool readstr(struct istream *is, value_t *val)
+struct error readstr(struct istream *is, value_t *val)
{
+ E_INIT();
+
skipws(is);
if (is->peek(is) != '"')
- return false;
+ THROWSAFE(EEXPECTED);
bool escape = false;
int size = 8;
@@ -209,7 +193,8 @@
*val |= STRING_TAG;
add_this_alloc(a, STRING_TAG);
- return true;
+
+ OKAY();
}
}
}
@@ -265,12 +250,15 @@
}
}
-bool readlist(struct istream *is, value_t *val)
+struct error readlist(struct istream *is, value_t *val)
{
+ E_INIT();
+ NEARIS(is);
+
skipws(is);
if (is->peek(is) != '(')
- return false;
+ THROWSAFE(EEXPECTED);
is->get(is);
@@ -280,23 +268,24 @@
if (is->peek(is) != ')')
{
- is->showpos(is, stderr);
- err("Unterminated list");
- return false;
+ NEARIS(is);
+ THROW(EEXPECTED, "Unterminated list");
}
is->get(is);
- return true;
+ OKAY();
}
-bool readint(struct istream *is, value_t *val)
+struct error readint(struct istream *is, value_t *val)
{
+ E_INIT();
+
skipws(is);
int number = 0;
if (!isdigit(is->peek(is)))
- return false;
+ THROWSAFE(EEXPECTED);
while (isdigit(is->peek(is)))
{
@@ -305,11 +294,13 @@
}
*val = intval(number);
- return true;
+ OKAY();
}
-bool readquote(struct istream *is, value_t *val)
+struct error readquote(struct istream *is, value_t *val)
{
+ E_INIT();
+
skipws(is);
char c = is->peek(is);
@@ -332,15 +323,9 @@
// Read the next form and wrap it in the appropriate function
value_t wrapped;
- bool has_next = read1(is, &wrapped);
+ NEARIS(is);
- if (!has_next)
- {
- fprintf(stderr, "Expected a form after reader macro char %c\n", c);
- is->showpos(is, stderr);
- err("Invalid reader macro");
- return false;
- }
+ TRY_ELSE(read1(is, &wrapped), EEXPECTED, "Expected a form after reader macro char %c", c);
value_t symbol = nil;
@@ -362,39 +347,33 @@
symbol = symval("function");
break;
default:
- is->showpos(is, stderr);
- err("Something went wrong parsing a reader macro");
+ NEARIS(is);
+ THROW(EINVALID, "Invalid reader macro char %c", c);
}
*val = cons(symbol, cons(wrapped, nil));
- return true;
+ OKAY();
}
else
{
- return false;
+ THROWSAFE(EEXPECTED);
}
}
-bool read1(struct istream *is, value_t *val)
+struct error read1(struct istream *is, value_t *val)
{
- // This could all be one big short-circuiting || but that is ugly.
- if (readquote(is, val))
- return true;
+ E_INIT();
- if (readsym(is, val))
- return true;
+ NEARIS(is);
- if (readstr(is, val))
- return true;
+ OKAY_IF(readquote(is, val));
+ OKAY_IF(readsym(is, val));
+ OKAY_IF(readstr(is, val));
+ OKAY_IF(readint(is, val));
+ OKAY_IF(readlist(is, val));
- if (readint(is, val))
- return true;
-
- if (readlist(is, val))
- return true;
-
- return false;
+ THROWSAFE(EEXPECTED);
}
void set_cons_info(value_t cons, int line, char *name)
@@ -415,7 +394,7 @@
value_t read_val;
- while (read1(is, &read_val))
+ while (IS_OKAY(read1(is, &read_val)))
{
int line;
char *file;
@@ -703,6 +682,7 @@
}
else
{
- err("Don't know how to deep copy this, sorry... please report this bug :)");
+ fprintf(stderr, "Don't know how to deep copy this, sorry... please report this bug :)");
+ return nil;
}
}