diff --git a/chapter_10/lispy.c b/chapter_10/lispy.c index 6405bb2..718e187 100644 --- a/chapter_10/lispy.c +++ b/chapter_10/lispy.c @@ -346,6 +346,9 @@ lval* builtin(lval* a, char* func) { if (strcmp("tail", func) == 0) {return builtin_tail(a);} if (strcmp("join", func) == 0) {return builtin_join(a);} if (strcmp("eval", func) == 0) {return builtin_eval(a);} + if (strcmp("cons", func) == 0) {return builtin_cons(a);} + if (strcmp("len", func) == 0) {return builtin_len(a);} + if (strcmp("init", func) == 0) {return builtin_init(a);} /* Check for operators */ if (strstr("+-*/%^", func) || @@ -542,6 +545,69 @@ lval* lval_join(lval* x, lval* y) { } +lval* builtin_cons(lval* a) { + + /* Check error conditions */ + LASSERT(a, a->count == 2 , + "Function 'cons' takes exactly 2 arguments!"); + + LASSERT(a, a->cell[1]->type == LVAL_QEXPR, + "Function 'cons' passed incorrect type!"); + + lval* v = lval_qexpr(); + v = lval_add(v, lval_pop(a, 0)); + + lval* y = lval_pop(a, 0); + + while (y->count) { + v = lval_add(v, lval_pop(y, 0)); + } + + lval_del(a); + lval_del(y); + return v; + +} + + +lval* builtin_len(lval* a) { + + /* Check error conditions */ + LASSERT(a, a->count == 1, + "Function 'len' passed too many arguments!"); + + LASSERT(a, a->cell[0]->type == LVAL_QEXPR, + "Function 'len' passed incorrect type!"); + + lval* v = lval_num(a->cell[0]->count); + return v; + +} + + +lval* builtin_init(lval* a) { + + /* Check error conditions */ + LASSERT(a, a->count == 1, + "Function 'init' passed too many arguments!"); + + LASSERT(a, a->cell[0]->type == LVAL_QEXPR, + "Function 'init' passed incorrect type!"); + + LASSERT(a, a->cell[0]->count != 0, + "Function 'init' passed {}!"); + + /* Otherwise take first argument */ + lval* v = lval_take(a, 0); + + /* Delete last element and return */ + lval_del(lval_pop(v, v->count-1)); + + return v; + +} + + long min(long x, long y) { if (x <= y) { return x; diff --git a/chapter_10/lispy.h b/chapter_10/lispy.h index 1d9f3df..1d03aaf 100644 --- a/chapter_10/lispy.h +++ b/chapter_10/lispy.h @@ -10,7 +10,8 @@ static char* parser = " \ number : /-?[0-9]+([.][0-9]*|[0-9]*)/ ; \ symbol : \"list\" | \"head\" | \"tail\" | \"join\" | \ - \"eval\" | '+' | '-' | '*' | '/' | '%' | \ + \"eval\" | \"len\" | \"init\" | \"cons\" | \ + '+' | '-' | '*' | '/' | '%' | \ '^' | \"min\" | \"max\" ; \ sexpr : '(' * ')' ; \ qexpr : '{' * '}' ; \ @@ -78,3 +79,6 @@ lval* builtin_list(lval* a); lval* builtin_eval(lval* a); lval* builtin_join(lval* a); lval* lval_join(lval* x, lval* y); +lval* builtin_cons(lval* a); +lval* builtin_len(lval* a); +lval* builtin_init(lval* a);