Skip to content

Commit 75881c2

Browse files
committed
Adds fancy error handling features, for more verbose error handling.
1 parent ab5f452 commit 75881c2

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

Diff for: .parsing.c.swp

0 Bytes
Binary file not shown.

Diff for: parsing

120 Bytes
Binary file not shown.

Diff for: parsing.c

+48-13
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,12 @@ void add_history(char *dummy){}
3535
#include <editline/history.h>
3636
#endif
3737

38-
#define LASSERT(args, cond, err) \
39-
if(!(cond)) {lval_del(args); return lval_err(err); }
38+
#define LASSERT(args, cond, fmt, ...) \
39+
if(!(cond)) { \
40+
lval *err = lval_err(fmt, ##__VA_ARGS__); \
41+
lval_del(args); \
42+
return err; \
43+
}
4044

4145
/* Forward declerations */
4246
struct lval;
@@ -95,7 +99,7 @@ void lenv_del(lenv *e){
9599
free(e);
96100
}
97101
lval* lval_copy(lval* v);
98-
lval* lval_err(char* m);
102+
lval* lval_err(char* m, ...);
99103
lval *lenv_get(lenv *e, lval *k){
100104
/* Iterate over all the variables in the environment */
101105
for(int i=0; i<e->count; i++){
@@ -106,7 +110,7 @@ lval *lenv_get(lenv *e, lval *k){
106110
}
107111

108112
/* If symbol not found return error */
109-
return lval_err("Unbound err0r.");
113+
return lval_err("Unbound symbol '%s'.", k->sym);
110114
}
111115

112116
void lenv_put(lenv *e, lval *k, lval *v){
@@ -142,11 +146,24 @@ lval* lval_num(double x){
142146
}
143147

144148
/*Create a new error type lval*/
145-
lval* lval_err(char* m){
149+
lval* lval_err(char* fmt, ...){
146150
lval* v = malloc(sizeof(lval));
147151
v->type = LVAL_ERR;
148-
v->err = malloc(sizeof(strlen(m) + 1));
149-
strcpy(v->err, m);
152+
/* Create a va list and initialise it */
153+
va_list va;
154+
va_start(va, fmt);
155+
156+
/* Allocate 512 bytes of space first */
157+
v->err = malloc(512);
158+
159+
/* printf the error string with a maximum of 511 character */
160+
vsnprintf(v->err, 511, fmt, va);
161+
162+
/* Reallocate the number of bytes to what is actually used. Resourcefulness ting */
163+
v->err = realloc(v->err, strlen(v->err)+1);
164+
165+
/* cleanup our va_list */
166+
va_end(va);
150167

151168
return v;
152169
}
@@ -388,11 +405,26 @@ lval* lval_copy(lval* v){
388405
return x;
389406
}
390407

408+
char *ltype_name(int t){
409+
switch(t){
410+
case LVAL_FUN : return "Function";
411+
case LVAL_NUM : return "Number";
412+
case LVAL_ERR : return "Error";
413+
case LVAL_SYM : return "Symbol";
414+
case LVAL_SEXPR : return "S-Expression";
415+
case LVAL_QEXPR : return "Q-Expression";
416+
417+
default: return "Unknown";
418+
}
419+
}
420+
391421
lval *builtin_head(lenv *e, lval *a){
392422
/* Check the error condition */
393-
LASSERT(a, a->count == 1, "Function 'head' has way too many arguements. Err0r.");
394-
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Incorrect type passed to function 'head'. Err0r.");
395-
LASSERT(a, a->cell[0]->count != 0, "Function head is passed {} which is empty. Err0r.");
423+
LASSERT(a, a->count == 1, "Function 'head' has way too many arguements.", "Got %i, expected %i", a->count, 1);
424+
LASSERT(a, a->cell[0]->type == LVAL_QEXPR
425+
, "Incorrect type passed to function 'head'.", "Got %s, expected %s"
426+
, ltype_name(a->cell[0]->type), ltype_name(LVAL_QEXPR));
427+
LASSERT(a, a->cell[0]->count != 0, "Function head is passed {} which is empty.");
396428

397429
/* If no error, get the first arguements */
398430
lval *v = lval_take(a, 0);
@@ -407,8 +439,10 @@ lval *builtin_head(lenv *e, lval *a){
407439

408440
lval* builtin_tail(lenv *e, lval *a){
409441
/* Check the error condition */
410-
LASSERT(a, a->count == 1, "Function 'tail' has way too many arguements. Err0r.");
411-
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Incorrect type passed to function 'tail'. Err0r.");
442+
LASSERT(a, a->count == 1, "Function 'tail' has way too many arguements.", "Got %i, expected %i", a->count, 1);
443+
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Incorrect type passed to function 'tail'." , "Got %s, expected %s"
444+
, ltype_name(a->cell[0]->type), ltype_name(LVAL_SEXPR));
445+
412446
LASSERT(a, a->cell[0]->count != 0, "Function 'tail' is passed {} which is empty. Err0r.");
413447

414448

@@ -550,7 +584,8 @@ void lenv_add_builtin(lenv* e, char *name, lbuiltin func){
550584
}
551585

552586
lval *builtin_def(lenv *e, lval *a){
553-
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Function def passed incorrect type. Err0r.");
587+
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Function def passed incorrect type.", "Expected %s, got %s"
588+
, ltype_name(LVAL_QEXPR), ltype_name(a->cell[0]->type));
554589

555590
/* The first arguements is the symbols list */
556591
lval *syms = a->cell[0];

0 commit comments

Comments
 (0)