@@ -35,8 +35,12 @@ void add_history(char *dummy){}
35
35
#include <editline/history.h>
36
36
#endif
37
37
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
+ }
40
44
41
45
/* Forward declerations */
42
46
struct lval ;
@@ -95,7 +99,7 @@ void lenv_del(lenv *e){
95
99
free (e );
96
100
}
97
101
lval * lval_copy (lval * v );
98
- lval * lval_err (char * m );
102
+ lval * lval_err (char * m , ... );
99
103
lval * lenv_get (lenv * e , lval * k ){
100
104
/* Iterate over all the variables in the environment */
101
105
for (int i = 0 ; i < e -> count ; i ++ ){
@@ -106,7 +110,7 @@ lval *lenv_get(lenv *e, lval *k){
106
110
}
107
111
108
112
/* If symbol not found return error */
109
- return lval_err ("Unbound err0r." );
113
+ return lval_err ("Unbound symbol '%s'." , k -> sym );
110
114
}
111
115
112
116
void lenv_put (lenv * e , lval * k , lval * v ){
@@ -142,11 +146,24 @@ lval* lval_num(double x){
142
146
}
143
147
144
148
/*Create a new error type lval*/
145
- lval * lval_err (char * m ){
149
+ lval * lval_err (char * fmt , ... ){
146
150
lval * v = malloc (sizeof (lval ));
147
151
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 );
150
167
151
168
return v ;
152
169
}
@@ -388,11 +405,26 @@ lval* lval_copy(lval* v){
388
405
return x ;
389
406
}
390
407
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
+
391
421
lval * builtin_head (lenv * e , lval * a ){
392
422
/* 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." );
396
428
397
429
/* If no error, get the first arguements */
398
430
lval * v = lval_take (a , 0 );
@@ -407,8 +439,10 @@ lval *builtin_head(lenv *e, lval *a){
407
439
408
440
lval * builtin_tail (lenv * e , lval * a ){
409
441
/* 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
+
412
446
LASSERT (a , a -> cell [0 ]-> count != 0 , "Function 'tail' is passed {} which is empty. Err0r." );
413
447
414
448
@@ -550,7 +584,8 @@ void lenv_add_builtin(lenv* e, char *name, lbuiltin func){
550
584
}
551
585
552
586
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 ));
554
589
555
590
/* The first arguements is the symbols list */
556
591
lval * syms = a -> cell [0 ];
0 commit comments