Browse Source

Implement some bonus marks

* Add functions cons, len & init
T. Meissner 6 months ago
parent
commit
69221adb3f
2 changed files with 71 additions and 1 deletions
  1. 66
    0
      chapter_10/lispy.c
  2. 5
    1
      chapter_10/lispy.h

+ 66
- 0
chapter_10/lispy.c View File

@@ -346,6 +346,9 @@ lval* builtin(lval* a, char* func) {
346 346
     if (strcmp("tail", func) == 0) {return builtin_tail(a);}
347 347
     if (strcmp("join", func) == 0) {return builtin_join(a);}
348 348
     if (strcmp("eval", func) == 0) {return builtin_eval(a);}
349
+    if (strcmp("cons", func) == 0) {return builtin_cons(a);}
350
+    if (strcmp("len", func) == 0)  {return builtin_len(a);}
351
+    if (strcmp("init", func) == 0) {return builtin_init(a);}
349 352
 
350 353
     /* Check for operators */
351 354
     if (strstr("+-*/%^", func) ||
@@ -542,6 +545,69 @@ lval* lval_join(lval* x, lval* y) {
542 545
 }
543 546
 
544 547
 
548
+lval* builtin_cons(lval* a) {
549
+
550
+    /* Check error conditions */
551
+    LASSERT(a, a->count == 2 ,
552
+            "Function 'cons' takes exactly 2 arguments!");
553
+
554
+    LASSERT(a, a->cell[1]->type == LVAL_QEXPR,
555
+            "Function 'cons' passed incorrect type!");
556
+
557
+    lval* v = lval_qexpr();
558
+    v = lval_add(v, lval_pop(a, 0));
559
+
560
+    lval* y = lval_pop(a, 0);
561
+
562
+    while (y->count) {
563
+        v = lval_add(v, lval_pop(y, 0));
564
+    }
565
+
566
+    lval_del(a);
567
+    lval_del(y);
568
+    return v;
569
+
570
+}
571
+
572
+
573
+lval* builtin_len(lval* a) {
574
+
575
+    /* Check error conditions */
576
+    LASSERT(a, a->count == 1,
577
+            "Function 'len' passed too many arguments!");
578
+
579
+    LASSERT(a, a->cell[0]->type == LVAL_QEXPR,
580
+        "Function 'len' passed incorrect type!");
581
+
582
+    lval* v = lval_num(a->cell[0]->count);
583
+    return v;
584
+
585
+}
586
+
587
+
588
+lval* builtin_init(lval* a) {
589
+
590
+    /* Check error conditions */
591
+    LASSERT(a, a->count == 1,
592
+            "Function 'init' passed too many arguments!");
593
+
594
+    LASSERT(a, a->cell[0]->type == LVAL_QEXPR,
595
+        "Function 'init' passed incorrect type!");
596
+
597
+    LASSERT(a, a->cell[0]->count != 0,
598
+        "Function 'init' passed {}!");
599
+
600
+    /* Otherwise take first argument */
601
+    lval* v = lval_take(a, 0);
602
+
603
+    /* Delete last element and return */
604
+    lval_del(lval_pop(v, v->count-1));
605
+
606
+    return v;
607
+
608
+}
609
+
610
+
545 611
 long min(long x, long y) {
546 612
     if (x <= y) {
547 613
         return x;

+ 5
- 1
chapter_10/lispy.h View File

@@ -10,7 +10,8 @@ static char* parser =
10 10
 "                                                         \
11 11
     number   : /-?[0-9]+([.][0-9]*|[0-9]*)/ ;             \
12 12
     symbol : \"list\" | \"head\" | \"tail\" | \"join\" |  \
13
-             \"eval\" | '+' | '-' | '*' | '/' | '%' |     \
13
+             \"eval\" | \"len\" | \"init\" | \"cons\" |   \
14
+             '+' | '-' | '*' | '/' | '%' |                \
14 15
              '^' | \"min\" | \"max\" ;                    \
15 16
     sexpr    : '(' <expr>* ')' ;                          \
16 17
     qexpr    : '{' <expr>* '}' ;                          \
@@ -78,3 +79,6 @@ lval* builtin_list(lval* a);
78 79
 lval* builtin_eval(lval* a);
79 80
 lval* builtin_join(lval* a);
80 81
 lval* lval_join(lval* x, lval* y);
82
+lval* builtin_cons(lval* a);
83
+lval* builtin_len(lval* a);
84
+lval* builtin_init(lval* a);