about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-07-03 16:16:03 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-07-03 16:16:03 -0700
commitd986404ff03bca8d87062c0011829b262448876a (patch)
tree0921bfb733ff2e6c1de6baa5a63b0ced98565d05
parent810d9a26f55deade47060642e1b71a1069d1dce7 (diff)
downloadmu-d986404ff03bca8d87062c0011829b262448876a.tar.gz
new primitive: cons?
-rw-r--r--shell/primitives.mu43
1 files changed, 42 insertions, 1 deletions
diff --git a/shell/primitives.mu b/shell/primitives.mu
index a2902f64..c78b44e0 100644
--- a/shell/primitives.mu
+++ b/shell/primitives.mu
@@ -26,6 +26,7 @@ fn initialize-primitives _self: (addr global-table) {
   append-primitive self, "car"
   append-primitive self, "cdr"
   append-primitive self, "cons"
+  append-primitive self, "cons?"
   # for screens
   append-primitive self, "print"
   append-primitive self, "clear"
@@ -74,7 +75,7 @@ fn render-primitives screen: (addr screen), xmin: int, xmax: int, ymax: int {
   draw-text-wrapping-right-then-down-from-cursor screen, "lists", right-min, y, xmax, ymax, 7/fg=grey, 0xdc/bg=green-bg
   y <- increment
   set-cursor-position screen, right-min, y
-  draw-text-wrapping-right-then-down-from-cursor screen, "cons car cdr no", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
+  draw-text-wrapping-right-then-down-from-cursor screen, "cons car cdr no cons?", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
   y <- increment
   set-cursor-position screen, right-min, y
   draw-text-wrapping-right-then-down-from-cursor screen, "numbers", right-min, y, xmax, ymax, 7/fg=grey, 0xdc/bg=green-bg
@@ -293,6 +294,13 @@ fn apply-primitive _f: (addr cell), args-ah: (addr handle cell), out: (addr hand
     return
   }
   {
+    var cons-check?/eax: boolean <- string-equal? f-name, "cons?"
+    compare cons-check?, 0/false
+    break-if-=
+    apply-cons-check args-ah, out, trace
+    return
+  }
+  {
     var structurally-equal?/eax: boolean <- string-equal? f-name, "="
     compare structurally-equal?, 0/false
     break-if-=
@@ -1070,6 +1078,39 @@ fn apply-cons _args-ah: (addr handle cell), out: (addr handle cell), trace: (add
   new-pair out, *first-ah, *second-ah
 }
 
+fn apply-cons-check _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+  trace-text trace, "eval", "apply cons?"
+  var args-ah/eax: (addr handle cell) <- copy _args-ah
+  var _args/eax: (addr cell) <- lookup *args-ah
+  var args/esi: (addr cell) <- copy _args
+  {
+    var args-type/ecx: (addr int) <- get args, type
+    compare *args-type, 0/pair
+    break-if-=
+    error trace, "args to cons? are not a list"
+    return
+  }
+  var empty-args?/eax: boolean <- nil? args
+  compare empty-args?, 0/false
+  {
+    break-if-=
+    error trace, "cons? needs 1 arg but got 0"
+    return
+  }
+  # args->left
+  var first-ah/edx: (addr handle cell) <- get args, left
+  var first/eax: (addr cell) <- lookup *first-ah
+  var first-type/ecx: (addr int) <- get first, type
+  compare *first-type, 0/pair
+  {
+    break-if-=
+    nil out
+    return
+  }
+  new-integer out, 1
+}
+
+
 fn apply-structurally-equal _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
   trace-text trace, "eval", "apply '='"
   var args-ah/eax: (addr handle cell) <- copy _args-ah