From 7f8d0429d2f39b0dfb241ca63403df0452ddc385 Mon Sep 17 00:00:00 2001 From: tmeissner Date: Fri, 10 May 2019 00:19:25 +0200 Subject: [PATCH] Add implementations for remaining functions * Add list, eval & join functions * Use new macro LASSERT for error checks --- chapter_10/lispy.c | 94 ++++++++++++++++++++++++++++++++++------------ chapter_10/lispy.h | 8 ++++ 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/chapter_10/lispy.c b/chapter_10/lispy.c index 1246401..bafa75d 100644 --- a/chapter_10/lispy.c +++ b/chapter_10/lispy.c @@ -418,20 +418,14 @@ lval* builtin_op(lval* a, char* op) { lval* builtin_head(lval* a) { /* Check error conditions */ - if (a->count != 1) { - lval_del(a); - return lval_err("Function 'head' passed too many arguments"); - } + LASSERT(a, a->count == 1, + "Function 'head' passed too many arguments!"); - if (a->cell[0]->type != LVAL_QEXPR) { - lval_del(a); - return lval_err("Function 'head' passed incorrect types!"); - } + LASSERT(a, a->cell[0]->type == LVAL_QEXPR, + "Function 'head' passed incorrect type!"); - if (a->cell[0]->count == 0) { - lval_del(a); - return lval_err("Function 'head' passed empty {}!"); - } + LASSERT(a, a->cell[0]->count != 0, + "Function 'head' passed {}!"); /* Otherwise take first argument */ lval* v = lval_take(a, 0); @@ -449,20 +443,14 @@ lval* builtin_head(lval* a) { lval* builtin_tail(lval* a) { /* Check error conditions */ - if (a->count != 1) { - lval_del(a); - return lval_err("Function 'tail' passed too many arguments"); - } + LASSERT(a, a->count == 1, + "Function 'tail' passed too many arguments!"); - if (a->cell[0]->type != LVAL_QEXPR) { - lval_del(a); - return lval_err("Function 'tail' passed incorrect types!"); - } + LASSERT(a, a->cell[0]->type == LVAL_QEXPR, + "Function 'tail' passed incorrect type!"); - if (a->cell[0]->count == 0) { - lval_del(a); - return lval_err("Function 'tail' passed empty {}!"); - } + LASSERT(a, a->cell[0]->count != 0, + "Function 'tail' passed {}!"); /* Otherwise take first argument */ lval* v = lval_take(a, 0); @@ -475,6 +463,64 @@ lval* builtin_tail(lval* a) { } +lval* builtin_list(lval* a) { + + a->type = LVAL_QEXPR; + return a; + +} + + +lval* builtin_eval(lval* a) { + + /* Check error conditions */ + LASSERT(a, a->count == 1, + "Function 'eval' passed too many arguments!"); + + LASSERT(a, a->cell[0]->type == LVAL_QEXPR, + "Function 'eval' passed incorrect type!"); + + lval* x = lval_take(a, 0); + x->type = LVAL_SEXPR; + return lval_eval(x); + +} + + +lval* builtin_join(lval* a) { + + /* Check error conditions */ + for (size_t i = 0; i < a->count; i++) { + LASSERT(a, a->cell[i]->type == LVAL_QEXPR, + "Function 'join' passed incorrect type!"); + } + + lval* x = lval_pop(a, 0); + + while (a->count) { + x = lval_join(x, lval_pop(a, 0)); + } + + lval_del(a); + return x; + +} + + +lval* lval_join(lval* x, lval* y) { + + /* For each cell in y add it to x */ + while (y->count) { + x = lval_add(x, lval_pop(y, 0)); + } + + /* Delete the empty y and return x */ + lval_del(y); + return x; + +} + + long min(long x, long y) { if (x <= y) { return x; diff --git a/chapter_10/lispy.h b/chapter_10/lispy.h index bba67f5..3074aba 100644 --- a/chapter_10/lispy.h +++ b/chapter_10/lispy.h @@ -1,3 +1,7 @@ +#define LASSERT(args, cond, err) \ + if (!(cond)) { lval_del(args); return lval_err(err); } + + static char* lispy_version = "Lispy version 0.0.0.0.6"; @@ -69,3 +73,7 @@ long max(long x, long y); lval* builtin_op(lval* a, char* op); lval* builtin_head(lval* a); lval* builtin_tail(lval* a); +lval* builtin_list(lval* a); +lval* builtin_eval(lval* a); +lval* builtin_join(lval* a); +lval* lval_join(lval* x, lval* y);