nydp 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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