nydp 0.4.3 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/lisp/core-010-precompile.nydp +5 -6
  3. data/lib/lisp/core-012-utils.nydp +2 -1
  4. data/lib/lisp/core-015-documentation.nydp +17 -11
  5. data/lib/lisp/core-020-utils.nydp +5 -5
  6. data/lib/lisp/core-030-syntax.nydp +29 -9
  7. data/lib/lisp/core-035-flow-control.nydp +15 -6
  8. data/lib/lisp/core-037-list-utils.nydp +22 -0
  9. data/lib/lisp/core-039-module.nydp +24 -0
  10. data/lib/lisp/core-040-utils.nydp +11 -12
  11. data/lib/lisp/core-041-string-utils.nydp +24 -0
  12. data/lib/lisp/core-042-date-utils.nydp +16 -0
  13. data/lib/lisp/core-043-list-utils.nydp +72 -50
  14. data/lib/lisp/core-080-pretty-print.nydp +50 -17
  15. data/lib/lisp/core-090-hook.nydp +13 -1
  16. data/lib/lisp/core-100-utils.nydp +82 -2
  17. data/lib/lisp/core-110-hash-utils.nydp +38 -0
  18. data/lib/lisp/core-120-settings.nydp +11 -2
  19. data/lib/lisp/core-900-benchmarking.nydp +17 -17
  20. data/lib/lisp/tests/accum-examples.nydp +28 -1
  21. data/lib/lisp/tests/at-syntax-examples.nydp +17 -0
  22. data/lib/lisp/tests/best-examples.nydp +9 -0
  23. data/lib/lisp/tests/builtin-tests.nydp +10 -0
  24. data/lib/lisp/tests/case-examples.nydp +14 -0
  25. data/lib/lisp/tests/date-examples.nydp +54 -1
  26. data/lib/lisp/tests/detect-examples.nydp +12 -0
  27. data/lib/lisp/tests/dp-examples.nydp +24 -0
  28. data/lib/lisp/tests/empty-examples.nydp +1 -1
  29. data/lib/lisp/tests/error-tests.nydp +4 -4
  30. data/lib/lisp/tests/hash-examples.nydp +17 -0
  31. data/lib/lisp/tests/list-grep-examples.nydp +40 -0
  32. data/lib/lisp/tests/list-tests.nydp +39 -0
  33. data/lib/lisp/tests/module-examples.nydp +10 -0
  34. data/lib/lisp/tests/parser-tests.nydp +16 -0
  35. data/lib/lisp/tests/pretty-print-tests.nydp +8 -2
  36. data/lib/lisp/tests/settings-examples.nydp +1 -1
  37. data/lib/lisp/tests/string-tests.nydp +48 -0
  38. data/lib/lisp/tests/syntax-tests.nydp +5 -1
  39. data/lib/nydp.rb +6 -3
  40. data/lib/nydp/assignment.rb +10 -3
  41. data/lib/nydp/builtin.rb +1 -1
  42. data/lib/nydp/builtin/abs.rb +8 -0
  43. data/lib/nydp/builtin/date.rb +9 -0
  44. data/lib/nydp/builtin/error.rb +1 -1
  45. data/lib/nydp/builtin/hash.rb +11 -1
  46. data/lib/nydp/builtin/ruby_wrap.rb +69 -0
  47. data/lib/nydp/builtin/string_pad_left.rb +7 -0
  48. data/lib/nydp/builtin/string_pad_right.rb +7 -0
  49. data/lib/nydp/builtin/type_of.rb +9 -6
  50. data/lib/nydp/closure.rb +0 -3
  51. data/lib/nydp/cond.rb +23 -1
  52. data/lib/nydp/context_symbol.rb +14 -6
  53. data/lib/nydp/core.rb +33 -29
  54. data/lib/nydp/core_ext.rb +5 -4
  55. data/lib/nydp/date.rb +17 -17
  56. data/lib/nydp/function_invocation.rb +33 -25
  57. data/lib/nydp/helper.rb +12 -2
  58. data/lib/nydp/interpreted_function.rb +68 -40
  59. data/lib/nydp/literal.rb +1 -1
  60. data/lib/nydp/pair.rb +13 -2
  61. data/lib/nydp/parser.rb +3 -0
  62. data/lib/nydp/symbol_lookup.rb +7 -7
  63. data/lib/nydp/version.rb +1 -1
  64. data/nydp.gemspec +2 -4
  65. data/spec/date_spec.rb +79 -0
  66. data/spec/parser_spec.rb +11 -0
  67. metadata +15 -36
  68. data/lib/nydp/builtin/car.rb +0 -7
  69. data/lib/nydp/builtin/cdr.rb +0 -7
  70. data/lib/nydp/builtin/cons.rb +0 -9
@@ -85,6 +85,16 @@
85
85
  (examples-for mod
86
86
  ("modulus for two ints" (mod 64 6) 4))
87
87
 
88
+ (examples-for abs
89
+ ("a positive integer" (abs 64) 64)
90
+ ("a negative integer" (abs -42) 42)
91
+ ("zero" (abs 0) 0)
92
+ ("negative zero" (abs -0) 0)
93
+ ("float zero" (abs 0.0) 0)
94
+ ("float negative zero" (abs -0.0) 0)
95
+ ("float negative" (abs -1.6) 1.6)
96
+ ("float positive" (abs 4.2) 4.2))
97
+
88
98
  (examples-for inspect
89
99
  ("truth" (inspect t) "t")
90
100
  ("nil" (inspect nil) "nil")
@@ -0,0 +1,14 @@
1
+ (examples-for 'case
2
+ ("expands to an if-expression"
3
+ (do (reset-uniq-counter)
4
+ (explain-mac 1
5
+ `(case eq? person.name
6
+ "conan" (greet person)
7
+ "egg" (delete person)
8
+ "bach" (play person)
9
+ else (interrogate person))))
10
+ (let caseval-1 (dot-syntax person name)
11
+ (if (eq? caseval-1 "conan") (greet person)
12
+ (eq? caseval-1 "egg") (delete person)
13
+ (eq? caseval-1 "bach") (play person)
14
+ (interrogate person)))))
@@ -18,6 +18,9 @@
18
18
  ("navigates to week end from sun" (let d (date 2015 11 1) (to-string d.end-of-week)) "2015-11-01" )
19
19
  ("navigates to week end" (let d (date 2015 11 6) (to-string d.end-of-week)) "2015-11-08" )
20
20
 
21
+ ("works with apply" (to-string (apply date '(2006 6 21))) "2006-06-21")
22
+ ("works with apply again" (to-string (apply date 2006 6 21 nil)) "2006-06-21")
23
+
21
24
  ("parses string" (let d (date "2004-03-12") (list d.year d.month d.day)) (2004 3 12))
22
25
 
23
26
  ("can act as hash key"
@@ -47,4 +50,54 @@
47
50
  ("adds days" (let d (date 2015 11 8) (to-string (+ d 1))) "2015-11-09")
48
51
  ("adds more days" (let d (date 2015 11 8) (to-string (+ d 10))) "2015-11-18")
49
52
  ("subtracts a day" (let d (date 2015 11 18) (to-string (- d 1))) "2015-11-17")
50
- ("subtracts more days" (let d (date 2015 11 18) (to-string (- d 5))) "2015-11-13"))
53
+ ("subtracts more days" (let d (date 2015 11 18) (to-string (- d 5))) "2015-11-13")
54
+
55
+ ("advances by -2 weeks" (let d (date 1965 6 8) (to-string (+ d '(-2 week)))) "1965-05-25")
56
+ ("advances by -1 week" (let d (date 1965 6 8) (to-string (+ d '(-1 week)))) "1965-06-01")
57
+ ("advances by 1 week" (let d (date 1965 6 8) (to-string (+ d '( 1 week)))) "1965-06-15")
58
+ ("advances by 2 weeks" (let d (date 1965 6 8) (to-string (+ d '( 2 week)))) "1965-06-22")
59
+
60
+ ("advances by -2 weeks" (let d (date 1965 6 8) (to-string (+ d '(-2 week)))) "1965-05-25")
61
+ ("advances by -1 week" (let d (date 1965 6 8) (to-string (+ d '(-1 week)))) "1965-06-01")
62
+ ("advances by 1 week" (let d (date 1965 6 8) (to-string (+ d '( 1 week)))) "1965-06-15")
63
+ ("advances by 2 weeks" (let d (date 1965 6 8) (to-string (+ d '( 2 week)))) "1965-06-22")
64
+
65
+ ("advances by -2 days" (let d (date 1965 6 8) (to-string (+ d '(-2 day)))) "1965-06-06")
66
+ ("advances by -1 day" (let d (date 1965 6 8) (to-string (+ d '(-1 day)))) "1965-06-07")
67
+ ("advances by 1 day" (let d (date 1965 6 8) (to-string (+ d '( 1 day)))) "1965-06-09")
68
+ ("advances by 2 days" (let d (date 1965 6 8) (to-string (+ d '( 2 day)))) "1965-06-10")
69
+
70
+ ("advances by -2 months" (let d (date 1965 6 8) (to-string (+ d '(-2 month)))) "1965-04-08")
71
+ ("advances by -1 month" (let d (date 1965 6 8) (to-string (+ d '(-1 month)))) "1965-05-08")
72
+ ("advances by 1 month" (let d (date 1965 6 8) (to-string (+ d '( 1 month)))) "1965-07-08")
73
+ ("advances by 2 months" (let d (date 1965 6 8) (to-string (+ d '( 2 month)))) "1965-08-08")
74
+
75
+ ("advances by -2 years" (let d (date 1965 6 8) (to-string (+ d '(-2 year)))) "1963-06-08")
76
+ ("advances by -1 year" (let d (date 1965 6 8) (to-string (+ d '(-1 year)))) "1964-06-08")
77
+ ("advances by 1 year" (let d (date 1965 6 8) (to-string (+ d '( 1 year)))) "1966-06-08")
78
+ ("advances by 2 years" (let d (date 1965 6 8) (to-string (+ d '( 2 year)))) "1967-06-08")
79
+
80
+ ("adapts for leap years" (let d (date 2019 12 31) (to-string (+ d '( 2 month)))) "2020-02-29")
81
+ ("jumps one year" (let d (date 2019 12 31) (to-string (+ d '( 1 year) ))) "2020-12-31")
82
+ ("jumps to 28 feb a year later" (let d (date 2019 12 31) (to-string (+ d '(14 month)))) "2021-02-28")
83
+ ("jumps to end of june" (let d (date 2019 12 31) (to-string (+ d '( 6 month)))) "2020-06-30")
84
+ ("jumps to end of july" (let d (date 2019 12 31) (to-string (+ d '( 7 month)))) "2020-07-31")
85
+ ("jumps from end feb to end feb" (let d (date 2020 02 29) (to-string (+ d '(12 month)))) "2021-02-28")
86
+
87
+ ("finds anniversary before a given date in previous year"
88
+ (to-string (anniversary/previous (date 2019 6 21) (date 1949 10 3)))
89
+ "2018-10-03")
90
+
91
+ ("finds anniversary before a given date in same year"
92
+ (to-string (anniversary/previous (date 2019 11 20) (date 1949 10 3)))
93
+ "2019-10-03")
94
+
95
+ ("finds anniversary after a given date in same year"
96
+ (to-string (anniversary/next (date 2019 6 21) (date 1949 10 3)))
97
+ "2019-10-03")
98
+
99
+
100
+ ("finds anniversary after a given date in following year"
101
+ (to-string (anniversary/next (date 2019 11 20) (date 1949 10 3)))
102
+ "2020-10-03")
103
+ )
@@ -26,6 +26,18 @@
26
26
  "zz")
27
27
  nil)
28
28
 
29
+ ("empty list"
30
+ (detect present? nil)
31
+ nil)
32
+
33
+ ("present? for list of empty things"
34
+ (detect present? (list "" nil {} ()))
35
+ nil)
36
+
37
+ ("present? for mostly empty things"
38
+ (detect present? (list "" nil 42 {} ()))
39
+ 42)
40
+
29
41
  ("nil for nil"
30
42
  (detect nil nil)
31
43
  nil)
@@ -0,0 +1,24 @@
1
+ (examples-for dp
2
+ ("returns nil for nil"
3
+ (dp)
4
+ nil)
5
+
6
+ ("returns nil when everything is empty"
7
+ (dp "" nil {} ())
8
+ nil)
9
+
10
+ ("returns the first item if not empty"
11
+ (dp 'a "" {} ())
12
+ a)
13
+
14
+ ("returns the second item if not empty"
15
+ (dp "" 'b "" {} ())
16
+ b)
17
+
18
+ ("returns the third item if not empty"
19
+ (dp "" {} 'c "" {} ())
20
+ c)
21
+
22
+ ("returns the last item if not empty"
23
+ (dp "" {} () 'd)
24
+ d))
@@ -18,7 +18,7 @@
18
18
  ("nonzero" (present? "foo-bar") t)
19
19
  ("zero" (present? "") nil)
20
20
  ("blank" (present? " ") t)
21
- ("nil is t" (present? nil) nil)
21
+ ("nil is nil" (present? nil) nil)
22
22
  ("sym is t" (present? 'abc) t)
23
23
  ("number is t" (present? 234) t)
24
24
 
@@ -20,10 +20,10 @@
20
20
  (on-err (error "bar")
21
21
  (on-err (error "toto")
22
22
  (error "primum errorum")))))
23
- "\"foo\"
24
- \"bar\"
25
- \"toto\"
26
- \"primum errorum\"")
23
+ "foo
24
+ bar
25
+ toto
26
+ primum errorum")
27
27
 
28
28
  ("handles errors but any ensuring clause gets called first"
29
29
  (with (x nil y nil)
@@ -1,3 +1,20 @@
1
+ (examples-for hash-replace-keys
2
+ ("changes strings to symbols"
3
+ (let h (hash-replace-keys λk(sym k) { "a" 1 "b" 2 "c" 3 })
4
+ (list (hash-keys h) (hash-values h)))
5
+ ((a b c) (1 2 3)))
6
+
7
+ ("appends a character to keys"
8
+ (let h (hash-replace-keys λk(string-pieces k "!") { "a" 1 "b" 2 "c" 3 })
9
+ (list (hash-keys h) (hash-values h)))
10
+ (("a!" "b!" "c!") (1 2 3))))
11
+
12
+ (examples-for hash
13
+ ("builds a hash"
14
+ (let h (hash "a" 1 'b 2 '(x y) 3)
15
+ (list (hash-keys h) (hash-values h)))
16
+ (("a" b (x y)) (1 2 3))))
17
+
1
18
  (examples-for hash-values
2
19
  ("returns the list of values of the given hash"
3
20
  (hash-values { a 1 b 2 c 'c d "hello" })
@@ -0,0 +1,40 @@
1
+ (examples-for list/grep
2
+ ("it finds strings"
3
+ (list/grep
4
+ string?
5
+ (list 'foo "bar" '(a b "c d" e) { ignores "hash elements" }))
6
+ ("bar" "c d"))
7
+
8
+ ("it finds items whose car is carryon"
9
+ (list/grep
10
+ λf(caris 'carryon f)
11
+ '(foo
12
+ (carryon 1 2 3 42)
13
+ (bar (40 41 42 (carryon 43 (carryon 42) 41)))
14
+ 42
15
+ 99))
16
+ ((carryon 1 2 3 42)
17
+ (carryon 43 (carryon 42) 41)
18
+ (carryon 42)))
19
+
20
+ ("it finds items of length 3"
21
+ (list/grep
22
+ λf(eq? 3 (len f))
23
+ '(foo
24
+ (2 3 42)
25
+ (bar (40 41 42) (43 (x y z) 41))
26
+ 42
27
+ 99))
28
+ ((2 3 42)
29
+ (bar (40 41 42) (43 (x y z) 41))
30
+ (40 41 42)
31
+ (43 (x y z) 41)
32
+ (x y z)))
33
+
34
+ ("it finds code within interpolated strings"
35
+ (list/seek-cars 'include (parse-in-string "
36
+ <div>~~(include \"empty-name.html\")</div>
37
+ <div>~~(map λn(let name n (include \"show-name.html\")) {names})'</div>
38
+ "))
39
+ ((include "empty-name.html")
40
+ (include "show-name.html"))))
@@ -205,3 +205,42 @@
205
205
  ("finds value corresponding to given key"
206
206
  (alref 'c '((a b) (c d)))
207
207
  d))
208
+
209
+ (examples-for list/fill
210
+ ("returns an overfull list unchanged"
211
+ (list/fill '(a b c) λ(just 'x) 2)
212
+ (a b c))
213
+
214
+ ("returns a full list unchanged"
215
+ (list/fill '(a b c) λ(just 'x) 3)
216
+ (a b c))
217
+
218
+ ("returns an unfull list with extra items"
219
+ (list/fill '(a b c) λ(just 'x) 4)
220
+ (a b c x))
221
+
222
+ ("returns an unfull list with extra items"
223
+ (let idx 0
224
+ (list/fill '(a b c) λ(++ idx) 10))
225
+ (a b c 1 2 3 4 5 6 7)))
226
+
227
+ (examples-for list/last
228
+ ("returns the thing if it's nil"
229
+ (list/last nil)
230
+ nil)
231
+
232
+ ("returns the thing if it's not a pair"
233
+ (list/last 42)
234
+ 42)
235
+
236
+ ("returns the cdr if it's not a pair"
237
+ (list/last '(x . y))
238
+ y)
239
+
240
+ ("returns the last item in the list"
241
+ (list/last '(x y z))
242
+ z)
243
+
244
+ ("returns nil if it's the last item in the list"
245
+ (list/last '(x y z nil))
246
+ nil))
@@ -0,0 +1,10 @@
1
+ (examples-for module
2
+ ("it overrides external namespace internally"
3
+ (with (x (fn (n) "the old outside x ~n")
4
+ y (fn (n) "the old outside y ~n"))
5
+ (module foo
6
+ (def x (n) (* 2 n))
7
+ (def y (n) (+ 2 n))
8
+ (export bar (a b) (* (x a) (y b))))
9
+ (list (foo/bar 3 5) (x 43) (y 44)))
10
+ (42 "the old outside x 43" "the old outside y 44")))
@@ -29,6 +29,22 @@
29
29
  (parse "%this.and.that")
30
30
  ((percent-syntax || (dot-syntax this and that))) )
31
31
 
32
+ ("parses a plain at-symbol"
33
+ (pre-compile (car (parse "@")))
34
+ @)
35
+
36
+ ("parses a plain at-prefix-syntax symbol"
37
+ (parse "@this")
38
+ ((at-syntax || this)))
39
+
40
+ ("parses an at-prefix-mixed-with-dot-syntax symbol"
41
+ (parse "@this.and.that")
42
+ ((dot-syntax (at-syntax || this) and that)))
43
+
44
+ ("at-prefix-mixed-with-dot-syntax expands to plain hash lookup: @this.and.that equivalent to @.this.and.that"
45
+ (pre-compile (car (parse "@this.and.that")))
46
+ (hash-get (hash-get (hash-get @ (quote this)) (quote and)) (quote that)))
47
+
32
48
  ("parses a dot-syntax symbol"
33
49
  (parse "this.that.zozo")
34
50
  ((dot-syntax this that zozo)) )
@@ -286,5 +286,11 @@ toto")
286
286
  "%x.y")
287
287
 
288
288
  ("brace list"
289
- (pp '(&x {a 1 b "two" c 'three d ,four e (sub invocation) f {sub brace list} }))
290
- "(&x { a 1 b \"two\" c 'three d ,four e (sub invocation) f { sub brace list } })"))
289
+ (pp '(let hello {a 1 b "two" c 'three d ,four e (sub invocation) f {sub brace list here} }))
290
+ "(let hello { a 1
291
+ b \"two\"
292
+ c 'three
293
+ d ,four
294
+ e (sub invocation)
295
+ f { sub brace
296
+ list here } })"))
@@ -17,7 +17,7 @@
17
17
 
18
18
  ("wraps arg in a fn expression if it is a hash"
19
19
  (settings/fn '{ a 1 b 2 })
20
- (fn (_) { a 1 b 2 }))
20
+ (k { a 1 b 2 }))
21
21
 
22
22
  ("wraps arg in a fn expression if it is a complex expression"
23
23
  (settings/fn '(let foo this that (rfnwith (complex stuff) (%td.tricky#syntax))))
@@ -1,3 +1,51 @@
1
+ (examples-for string-eval-fn
2
+ ("returns a function to eval a user-supplied string"
3
+ (let s "hello \~|u|, \~x + \~y is \~(+ x y), thank you!"
4
+ (let f (string-eval-fn s '(u x y))
5
+ (f "world" 37 5)))
6
+ "hello world, 37 + 5 is 42, thank you!"))
7
+
8
+ (examples-for string/eval-with-args
9
+ ("evals a user-supplied string"
10
+ (let s "hello \~|u|, \~x + \~y is \~(+ x y), thank heavens!"
11
+ (string/eval-with-args s '(u x y) "world" 36 6))
12
+ "hello world, 36 + 6 is 42, thank heavens!")
13
+
14
+ ("reports errors"
15
+ (on-err errors
16
+ (let s "hello \~|u|, \~x + \~y is \~(+ x y), thank heavens!"
17
+ (string/eval-with-args s '(a b c) "world" 36 6)))
18
+ ("error evaluating \"hello \~|u|, \~x + \~y is \~(+ x y), thank heavens!\"
19
+ with arg names (a b c)
20
+ and args (\"world\" 36 6)"
21
+ "unbound symbol: y")))
22
+
23
+ (examples-for string/pad-left
24
+ ("does not change a string whose length is greater than the given length"
25
+ (string/pad-left "Toronto" 3 "X")
26
+ "Toronto")
27
+
28
+ ("adds left padding to a string such that the result is the given length"
29
+ (string/pad-left "toto" 8 "X")
30
+ "XXXXtoto")
31
+
32
+ ("accepts multi-character padding"
33
+ (string/pad-left "toto" 12 "XYZ")
34
+ "XYZXYZXYtoto"))
35
+
36
+ (examples-for string/pad-right
37
+ ("does not change a string whose length is greater than the given length"
38
+ (string/pad-right "Toronto" 3 "X")
39
+ "Toronto")
40
+
41
+ ("adds right padding to a string such that the result is the given length"
42
+ (string/pad-right "toto" 8 "X")
43
+ "totoXXXX")
44
+
45
+ ("accepts multi-character padding"
46
+ (string/pad-right "toto" 12 "XYZ")
47
+ "totoXYZXYZXY"))
48
+
1
49
  (examples-for string-split
2
50
  ("splits a string using given expression"
3
51
  (string-split "a and b and c and d" " and ")
@@ -10,7 +10,11 @@
10
10
  ("dislikes no-prefix"
11
11
  (on-err (joinstr "\n" errors)
12
12
  (pre-compile '(:foo 1 2 3)))
13
- "\"Irregular ': syntax: got (|| foo) : not prefix-syntax : in :foo\""))
13
+ "expanding
14
+ (colon-syntax || foo)
15
+ with
16
+ (fn names ((orf (hash-get colon-syntax-overrides car [0#0#0]names) default-colon-syntax) [0#0#0]names))
17
+ Irregular ': syntax: got (|| foo) : not prefix-syntax : in :foo"))
14
18
 
15
19
  (examples-for prefix-list
16
20
  ("one argument"
@@ -11,6 +11,9 @@ module Nydp
11
11
  function = Symbol.mk(function_name.to_sym, ns).value
12
12
  function.invoke vm, r2n(args)
13
13
  vm.thread
14
+ rescue StandardError => e
15
+ friendly_args = args.map { |a| a.respond_to?(:_nydp_compact_inspect) ? a._nydp_compact_inspect : a }
16
+ raise Nydp::Error.new("Invoking #{function_name}\nwith args #{friendly_args.inspect}")
14
17
  end
15
18
 
16
19
  def self.reader txt ; Nydp::StringReader.new txt ; end
@@ -48,9 +51,9 @@ module Nydp
48
51
 
49
52
  def self.repl options={ }
50
53
  toplevel do
51
- silent = options.delete :silent
52
- ns = options.delete :ns
53
- launch_time = Time.now
54
+ launch_time = Time.now
55
+ silent = options.delete :silent
56
+ ns = options.delete :ns
54
57
  last_script_time = Time.now
55
58
  puts "welcome to nydp #{options.inspect}" unless silent
56
59
  reader = Nydp::ReadlineReader.new $stdin, "nydp > "
@@ -8,6 +8,8 @@ module Nydp
8
8
 
9
9
  def execute vm
10
10
  @name.assign vm.peek_arg, vm.current_context
11
+ rescue
12
+ raise "assigning #{@name.inspect}"
11
13
  end
12
14
 
13
15
  def to_s
@@ -26,9 +28,12 @@ module Nydp
26
28
  end
27
29
 
28
30
  def initialize name, value, value_src
29
- @value_src = value_src
30
- n = AssignmentInstruction.new name
31
- @instructions = cons(value, cons(n))
31
+ @name, @value, @value_src = name, value, value_src
32
+ @instructions = cons(value, cons(AssignmentInstruction.new(name)))
33
+ end
34
+
35
+ def lexical_reach n
36
+ [@name.lexical_reach(n), @value.lexical_reach(n)].max
32
37
  end
33
38
 
34
39
  def to_s
@@ -39,6 +44,8 @@ module Nydp
39
44
 
40
45
  def execute vm
41
46
  vm.push_ctx_instructions @instructions
47
+ rescue
48
+ raise "assigning #{@value.inspect} to #{@name.inspect}"
42
49
  end
43
50
  end
44
51
  end