Browse Source

Add implementations for remaining functions

* Add list, eval & join functions
* Use new macro LASSERT for error checks
T. Meissner 7 months ago
parent
commit
7f8d0429d2
2 changed files with 78 additions and 24 deletions
  1. 70
    24
      chapter_10/lispy.c
  2. 8
    0
      chapter_10/lispy.h

+ 70
- 24
chapter_10/lispy.c View File

@@ -418,20 +418,14 @@ lval* builtin_op(lval* a, char* op) {
418 418
 lval* builtin_head(lval* a) {
419 419
 
420 420
     /* Check error conditions */
421
-    if (a->count != 1) {
422
-        lval_del(a);
423
-        return lval_err("Function 'head' passed too many arguments");
424
-    }
421
+    LASSERT(a, a->count == 1,
422
+            "Function 'head' passed too many arguments!");
425 423
 
426
-    if (a->cell[0]->type != LVAL_QEXPR) {
427
-        lval_del(a);
428
-        return lval_err("Function 'head' passed incorrect types!");
429
-    }
424
+    LASSERT(a, a->cell[0]->type == LVAL_QEXPR,
425
+        "Function 'head' passed incorrect type!");
430 426
 
431
-    if (a->cell[0]->count == 0) {
432
-        lval_del(a);
433
-        return lval_err("Function 'head' passed empty {}!");
434
-    }
427
+    LASSERT(a, a->cell[0]->count != 0,
428
+        "Function 'head' passed {}!");
435 429
 
436 430
     /* Otherwise take first argument */
437 431
     lval* v = lval_take(a, 0);
@@ -449,20 +443,14 @@ lval* builtin_head(lval* a) {
449 443
 lval* builtin_tail(lval* a) {
450 444
 
451 445
     /* Check error conditions */
452
-    if (a->count != 1) {
453
-        lval_del(a);
454
-        return lval_err("Function 'tail' passed too many arguments");
455
-    }
446
+    LASSERT(a, a->count == 1,
447
+            "Function 'tail' passed too many arguments!");
456 448
 
457
-    if (a->cell[0]->type != LVAL_QEXPR) {
458
-        lval_del(a);
459
-        return lval_err("Function 'tail' passed incorrect types!");
460
-    }
449
+    LASSERT(a, a->cell[0]->type == LVAL_QEXPR,
450
+        "Function 'tail' passed incorrect type!");
461 451
 
462
-    if (a->cell[0]->count == 0) {
463
-        lval_del(a);
464
-        return lval_err("Function 'tail' passed empty {}!");
465
-    }
452
+    LASSERT(a, a->cell[0]->count != 0,
453
+        "Function 'tail' passed {}!");
466 454
 
467 455
     /* Otherwise take first argument */
468 456
     lval* v = lval_take(a, 0);
@@ -475,6 +463,64 @@ lval* builtin_tail(lval* a) {
475 463
 }
476 464
 
477 465
 
466
+lval* builtin_list(lval* a) {
467
+
468
+    a->type = LVAL_QEXPR;
469
+    return a;
470
+
471
+}
472
+
473
+
474
+lval* builtin_eval(lval* a) {
475
+
476
+    /* Check error conditions */
477
+    LASSERT(a, a->count == 1,
478
+            "Function 'eval' passed too many arguments!");
479
+
480
+    LASSERT(a, a->cell[0]->type == LVAL_QEXPR,
481
+        "Function 'eval' passed incorrect type!");
482
+
483
+    lval* x = lval_take(a, 0);
484
+    x->type = LVAL_SEXPR;
485
+    return lval_eval(x);
486
+
487
+}
488
+
489
+
490
+lval* builtin_join(lval* a) {
491
+
492
+    /* Check error conditions */
493
+    for (size_t i = 0; i < a->count; i++) {
494
+        LASSERT(a, a->cell[i]->type == LVAL_QEXPR,
495
+        "Function 'join' passed incorrect type!");
496
+    }
497
+
498
+    lval* x = lval_pop(a, 0);
499
+
500
+    while (a->count) {
501
+        x = lval_join(x, lval_pop(a, 0));
502
+    }
503
+
504
+    lval_del(a);
505
+    return x;
506
+
507
+}
508
+
509
+
510
+lval* lval_join(lval* x, lval* y) {
511
+
512
+    /* For each cell in y add it to x */
513
+    while (y->count) {
514
+        x = lval_add(x, lval_pop(y, 0));
515
+    }
516
+
517
+    /* Delete the empty y and return x */
518
+    lval_del(y);
519
+    return x;
520
+
521
+}
522
+
523
+
478 524
 long min(long x, long y) {
479 525
     if (x <= y) {
480 526
         return x;

+ 8
- 0
chapter_10/lispy.h View File

@@ -1,3 +1,7 @@
1
+#define LASSERT(args, cond, err)  \
2
+    if (!(cond)) { lval_del(args); return lval_err(err); }
3
+
4
+
1 5
 static char* lispy_version = "Lispy version 0.0.0.0.6";
2 6
 
3 7
 
@@ -69,3 +73,7 @@ long max(long x, long y);
69 73
 lval* builtin_op(lval* a, char* op);
70 74
 lval* builtin_head(lval* a);
71 75
 lval* builtin_tail(lval* a);
76
+lval* builtin_list(lval* a);
77
+lval* builtin_eval(lval* a);
78
+lval* builtin_join(lval* a);
79
+lval* lval_join(lval* x, lval* y);