about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--shell/eval.mu37
1 files changed, 34 insertions, 3 deletions
diff --git a/shell/eval.mu b/shell/eval.mu
index 9ca8d4bc..368e2836 100644
--- a/shell/eval.mu
+++ b/shell/eval.mu
@@ -9,6 +9,7 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env: (addr cell),
     compare is-nil?, 0/false
     break-if-=
     # nil is a literal
+    trace-text trace, "eval", "nil"
     copy-object _in, out
     trace-higher trace
     return
@@ -18,6 +19,7 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env: (addr cell),
   {
     break-if-!=
     # numbers are literals
+    trace-text trace, "eval", "number"
     copy-object _in, out
     trace-higher trace
     return
@@ -25,12 +27,27 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env: (addr cell),
   compare *in-type, 2/symbol
   {
     break-if-!=
+    trace-text trace, "eval", "symbol"
     lookup-symbol in-addr, out, env, trace
     trace-higher trace
     return
   }
-  # in-addr is a pair
-  # TODO: special forms
+  # in-addr is a syntax tree
+  $evaluate:anonymous-function: {
+    # trees starting with "fn" are anonymous functions and therefore literals
+    var expr/esi: (addr cell) <- copy in-addr
+    # if its first elem is not "fn", break
+    var first-ah/ecx: (addr handle cell) <- get in-addr, left
+    var first/eax: (addr cell) <- lookup *first-ah
+    var is-fn?/eax: boolean <- is-fn? first
+    compare is-fn?, 0/false
+    break-if-=
+    #
+    trace-text trace, "eval", "anonymous function"
+    copy-object _in, out
+    trace-higher trace
+    return
+  }
   trace-text trace, "eval", "function call"
   trace-text trace, "eval", "evaluating list elements"
   var evaluated-list-storage: (handle cell)
@@ -73,7 +90,7 @@ fn apply _f-ah: (addr handle cell), args-ah: (addr handle cell), out: (addr hand
     apply-primitive f, args-ah, out, env, trace
     return
   }
-  abort "unknown function"
+  error trace, "unknown function"
 }
 
 fn apply-primitive _f: (addr cell), args-ah: (addr handle cell), out: (addr handle cell), env: (addr cell), trace: (addr trace) {
@@ -453,6 +470,20 @@ fn cell-isomorphic? _a: (addr cell), _b: (addr cell), trace: (addr trace) -> _/e
   return result
 }
 
+fn is-fn? _x: (addr cell) -> _/eax: boolean {
+  var x/esi: (addr cell) <- copy _x
+  var type/eax: (addr int) <- get x, type
+  compare *type, 2/symbol
+  {
+    break-if-=
+    return 0/false
+  }
+  var contents-ah/eax: (addr handle stream byte) <- get x, text-data
+  var contents/eax: (addr stream byte) <- lookup *contents-ah
+  var result/eax: boolean <- stream-data-equal? contents, "fn"
+  return result
+}
+
 fn test-evaluate-is-well-behaved {
   var t-storage: trace
   var t/esi: (addr trace) <- address t-storage
'>1881922f ^
8ab348a8 ^


1881922f ^

8ab348a8 ^



1881922f ^

f8f6f7f9 ^
6deb64e6 ^


f8f6f7f9 ^

6deb64e6 ^








f8f6f7f9 ^
f8f6f7f9 ^
6deb64e6 ^

f8f6f7f9 ^
6deb64e6 ^





f61fbfae ^

f8f6f7f9 ^
6deb64e6 ^
b071cb85 ^

6deb64e6 ^
f61fbfae ^

f8f6f7f9 ^
f8f6f7f9 ^
b071cb85 ^

f8f6f7f9 ^
6deb64e6 ^




f8f6f7f9 ^
6deb64e6 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94