-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbind.robin
72 lines (55 loc) · 1.93 KB
/
bind.robin
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
;'<<SPEC'
-> Tests for functionality "Evaluate Robin Expression (with literal and bind)"
`bind` binds a single identifier to the result of evaluating a single
expression, and makes that binding available in another expression which
it evaluates.
| (bind x (literal hello)
| (prepend x (prepend x ())))
= (hello hello)
| (bind dup (fexpr (args env)
| (prepend (head args) (prepend (head args) ())))
| (dup g))
= (g g)
| (bind dup (fexpr (args env)
| (bind x (eval env (head args))
| (prepend x (prepend x ()))))
| (dup (literal g)))
= (g g)
| (bind dup (fexpr (args env)
| (bind x (eval env (head args))
| (prepend x (prepend x ()))))
| (dup (dup (literal g))))
= ((g g) (g g))
`bind` can bind a recursive fexpr to a name.
| (bind elem?-r
| (fexpr (args env)
| (bind self (eval env (head args))
| (bind target (eval env (head (tail args)))
| (bind items (eval env (head (tail (tail args))))
| (if (equal? items ()) #f
| (if (equal? (head items) target) #t
| (self self target (tail items))))))))
| (elem?-r elem?-r (literal c) (literal (a b c d e f))))
= #t
`bind` expects exactly three arguments, or else an abort value will be produced.
| (bind smoosh (fun (x y) (list y x)))
? abort
| (bind smoosh)
? abort
| (bind)
? abort
The identifier in a binding must be a symbol.
| (bind 3 1 3)
? abort
`bind` is basically equivalent to Scheme's `let`, but only one
binding may be given.
'<<SPEC'
(define bind (fexpr (args env)
(if
(symbol? (head args))
(eval
(prepend
(prepend (head args) (prepend (eval env (head (tail args)))
())) env)
(head (tail (tail args))))
(abort ((literal expected-symbol) (head args))))))