nydp 0.4.2 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +44 -0
- data/lib/lisp/core-010-precompile.nydp +13 -16
- data/lib/lisp/core-012-utils.nydp +3 -2
- data/lib/lisp/core-015-documentation.nydp +54 -23
- data/lib/lisp/core-017-builtin-dox.nydp +14 -12
- data/lib/lisp/core-020-utils.nydp +5 -5
- data/lib/lisp/core-030-syntax.nydp +166 -72
- data/lib/lisp/core-035-flow-control.nydp +38 -11
- data/lib/lisp/core-037-list-utils.nydp +12 -0
- data/lib/lisp/core-039-module.nydp +24 -0
- data/lib/lisp/core-040-utils.nydp +32 -12
- data/lib/lisp/core-041-string-utils.nydp +25 -1
- data/lib/lisp/core-042-date-utils.nydp +21 -1
- data/lib/lisp/core-043-list-utils.nydp +96 -64
- data/lib/lisp/core-070-prefix-list.nydp +1 -1
- data/lib/lisp/core-080-pretty-print.nydp +57 -17
- data/lib/lisp/core-090-hook.nydp +35 -1
- data/lib/lisp/core-100-utils.nydp +82 -2
- data/lib/lisp/core-110-hash-utils.nydp +56 -2
- data/lib/lisp/core-120-settings.nydp +16 -5
- data/lib/lisp/core-130-validations.nydp +51 -0
- data/lib/lisp/core-900-benchmarking.nydp +78 -20
- data/lib/lisp/tests/accum-examples.nydp +28 -1
- data/lib/lisp/tests/aif-examples.nydp +8 -3
- data/lib/lisp/tests/andify-examples.nydp +7 -0
- data/lib/lisp/tests/at-syntax-examples.nydp +17 -0
- data/lib/lisp/tests/best-examples.nydp +9 -0
- data/lib/lisp/tests/builtin-tests.nydp +19 -0
- data/lib/lisp/tests/case-examples.nydp +14 -0
- data/lib/lisp/tests/date-examples.nydp +54 -1
- data/lib/lisp/tests/destructuring-examples.nydp +46 -14
- data/lib/lisp/tests/detect-examples.nydp +12 -0
- data/lib/lisp/tests/dp-examples.nydp +24 -0
- data/lib/lisp/tests/each-tests.nydp +5 -0
- data/lib/lisp/tests/empty-examples.nydp +1 -1
- data/lib/lisp/tests/error-tests.nydp +4 -4
- data/lib/lisp/tests/explain-mac-examples.nydp +1 -1
- data/lib/lisp/tests/filter-forms-examples.nydp +15 -0
- data/lib/lisp/tests/hash-examples.nydp +25 -1
- data/lib/lisp/tests/list-grep-examples.nydp +40 -0
- data/lib/lisp/tests/list-tests.nydp +58 -1
- data/lib/lisp/tests/map-hash-examples.nydp +11 -0
- data/lib/lisp/tests/module-examples.nydp +10 -0
- data/lib/lisp/tests/multi-assign-examples.nydp +6 -0
- data/lib/lisp/tests/parser-tests.nydp +25 -0
- data/lib/lisp/tests/pretty-print-tests.nydp +17 -14
- data/lib/lisp/tests/set-difference-examples.nydp +8 -0
- data/lib/lisp/tests/settings-examples.nydp +17 -1
- data/lib/lisp/tests/string-tests.nydp +70 -1
- data/lib/lisp/tests/syntax-tests.nydp +5 -1
- data/lib/lisp/tests/to-integer-examples.nydp +16 -0
- data/lib/lisp/tests/validation-examples.nydp +15 -0
- data/lib/nydp.rb +10 -3
- data/lib/nydp/assignment.rb +10 -3
- data/lib/nydp/builtin.rb +1 -1
- data/lib/nydp/builtin/abs.rb +8 -0
- data/lib/nydp/builtin/date.rb +15 -1
- data/lib/nydp/builtin/error.rb +1 -1
- data/lib/nydp/builtin/hash.rb +24 -1
- data/lib/nydp/builtin/inspect.rb +1 -1
- data/lib/nydp/builtin/plus.rb +10 -2
- data/lib/nydp/builtin/random_string.rb +2 -2
- data/lib/nydp/builtin/{car.rb → regexp.rb} +2 -2
- data/lib/nydp/builtin/ruby_wrap.rb +72 -0
- data/lib/nydp/builtin/string_match.rb +2 -2
- data/lib/nydp/builtin/string_pad_left.rb +7 -0
- data/lib/nydp/builtin/string_pad_right.rb +7 -0
- data/lib/nydp/builtin/string_replace.rb +3 -3
- data/lib/nydp/builtin/string_split.rb +4 -3
- data/lib/nydp/builtin/to_integer.rb +23 -0
- data/lib/nydp/builtin/to_string.rb +2 -9
- data/lib/nydp/builtin/type_of.rb +9 -6
- data/lib/nydp/closure.rb +0 -3
- data/lib/nydp/cond.rb +23 -1
- data/lib/nydp/context_symbol.rb +14 -6
- data/lib/nydp/core.rb +36 -28
- data/lib/nydp/core_ext.rb +21 -5
- data/lib/nydp/date.rb +26 -18
- data/lib/nydp/function_invocation.rb +34 -26
- data/lib/nydp/helper.rb +35 -3
- data/lib/nydp/interpreted_function.rb +68 -40
- data/lib/nydp/literal.rb +1 -1
- data/lib/nydp/pair.rb +22 -5
- data/lib/nydp/parser.rb +11 -7
- data/lib/nydp/string_atom.rb +3 -4
- data/lib/nydp/symbol_lookup.rb +7 -7
- data/lib/nydp/tokeniser.rb +2 -2
- data/lib/nydp/truth.rb +10 -10
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +7 -0
- data/nydp.gemspec +2 -4
- data/spec/date_spec.rb +93 -0
- data/spec/embedded_spec.rb +12 -12
- data/spec/foreign_hash_spec.rb +14 -2
- data/spec/hash_non_hash_behaviour_spec.rb +7 -7
- data/spec/hash_spec.rb +24 -2
- data/spec/nydp_spec.rb +14 -2
- data/spec/pair_spec.rb +3 -1
- data/spec/parser_spec.rb +31 -20
- data/spec/rand_spec.rb +3 -3
- data/spec/spec_helper.rb +10 -1
- metadata +24 -37
- data/lib/nydp/builtin/cdr.rb +0 -7
- data/lib/nydp/builtin/cons.rb +0 -9
data/spec/date_spec.rb
CHANGED
@@ -138,6 +138,40 @@ describe Nydp::Date do
|
|
138
138
|
expect(nd._nydp_get(:"end-of-month").to_s). to eq "2015-06-30"
|
139
139
|
end
|
140
140
|
|
141
|
+
it "calculates end-of-month all year around" do
|
142
|
+
expect(Nydp.r2n(Date.parse("2015-01-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-01-31"
|
143
|
+
expect(Nydp.r2n(Date.parse("2015-02-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-02-28"
|
144
|
+
expect(Nydp.r2n(Date.parse("2016-02-08"))._nydp_get(:"end-of-month").to_s).to eq "2016-02-29"
|
145
|
+
expect(Nydp.r2n(Date.parse("2015-03-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-03-31"
|
146
|
+
expect(Nydp.r2n(Date.parse("2015-04-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-04-30"
|
147
|
+
expect(Nydp.r2n(Date.parse("2015-05-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-05-31"
|
148
|
+
expect(Nydp.r2n(Date.parse("2015-06-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-06-30"
|
149
|
+
expect(Nydp.r2n(Date.parse("2015-07-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-07-31"
|
150
|
+
expect(Nydp.r2n(Date.parse("2015-08-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-08-31"
|
151
|
+
expect(Nydp.r2n(Date.parse("2015-09-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-09-30"
|
152
|
+
expect(Nydp.r2n(Date.parse("2015-10-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-10-31"
|
153
|
+
expect(Nydp.r2n(Date.parse("2015-11-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-11-30"
|
154
|
+
expect(Nydp.r2n(Date.parse("2015-12-08"))._nydp_get(:"end-of-month").to_s).to eq "2015-12-31"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "manages leap years" do
|
158
|
+
rd = Date.parse "2020-02-08"
|
159
|
+
nd = Nydp.r2n rd
|
160
|
+
|
161
|
+
expect(nd._nydp_get(:"last-month").to_s). to eq "2020-01-08"
|
162
|
+
expect(nd._nydp_get(:"next-month").to_s). to eq "2020-03-08"
|
163
|
+
expect(nd._nydp_get(:"beginning-of-month").to_s). to eq "2020-02-01"
|
164
|
+
expect(nd._nydp_get(:"end-of-month").to_s). to eq "2020-02-29"
|
165
|
+
|
166
|
+
rd = Date.parse "2020-02-28"
|
167
|
+
nd = Nydp.r2n rd
|
168
|
+
expect(nd._nydp_get(:"tomorrow").to_s). to eq "2020-02-29"
|
169
|
+
|
170
|
+
rd = Date.parse "2020-03-01"
|
171
|
+
nd = Nydp.r2n rd
|
172
|
+
expect(nd._nydp_get(:"yesterday").to_s). to eq "2020-02-29"
|
173
|
+
end
|
174
|
+
|
141
175
|
it "returns relative dates by week" do
|
142
176
|
rd = Date.parse "2015-03-12"
|
143
177
|
nd = Nydp.r2n rd
|
@@ -147,4 +181,63 @@ describe Nydp::Date do
|
|
147
181
|
expect(nd._nydp_get(:"beginning-of-week").to_s). to eq "2015-03-09"
|
148
182
|
expect(nd._nydp_get(:"end-of-week").to_s). to eq "2015-03-15"
|
149
183
|
end
|
184
|
+
|
185
|
+
it "returns age relative to today" do
|
186
|
+
rd = Date.parse "2014-03-12"
|
187
|
+
nd = Nydp.r2n rd
|
188
|
+
allow(::Date).to receive_messages(today: Date.parse("2016-06-21"))
|
189
|
+
expect(nd._nydp_get(:age)).to eq({ years: 2, months: 3 })
|
190
|
+
end
|
191
|
+
|
192
|
+
it "returns a negative age relative to today for a date in the future" do
|
193
|
+
rd = Date.parse "2094-11-18"
|
194
|
+
nd = Nydp.r2n rd
|
195
|
+
allow(::Date).to receive_messages(today: Date.parse("2016-06-21"))
|
196
|
+
expect(nd._nydp_get(:age)).to eq({ years: -78, months: -5 })
|
197
|
+
end
|
198
|
+
|
199
|
+
describe "#change" do
|
200
|
+
let(:nd) { Nydp::Date.new(Date.parse("1965-06-08")) }
|
201
|
+
|
202
|
+
it "advances by weeks" do
|
203
|
+
expect((nd.change 1, :week).to_s).to eq "1965-06-15"
|
204
|
+
expect((nd.change -1, :week).to_s).to eq "1965-06-01"
|
205
|
+
expect((nd.change -2, :week).to_s).to eq "1965-05-25"
|
206
|
+
expect((nd.change 2, :week).to_s).to eq "1965-06-22"
|
207
|
+
end
|
208
|
+
|
209
|
+
it "advances by days" do
|
210
|
+
expect((nd.change 1, :day).to_s).to eq "1965-06-09"
|
211
|
+
expect((nd.change -1, :day).to_s).to eq "1965-06-07"
|
212
|
+
expect((nd.change -2, :day).to_s).to eq "1965-06-06"
|
213
|
+
expect((nd.change 2, :day).to_s).to eq "1965-06-10"
|
214
|
+
end
|
215
|
+
|
216
|
+
it "advances by months" do
|
217
|
+
expect((nd.change 1, :month).to_s).to eq "1965-07-08"
|
218
|
+
expect((nd.change -1, :month).to_s).to eq "1965-05-08"
|
219
|
+
expect((nd.change -2, :month).to_s).to eq "1965-04-08"
|
220
|
+
expect((nd.change 2, :month).to_s).to eq "1965-08-08"
|
221
|
+
end
|
222
|
+
|
223
|
+
it "advances by years" do
|
224
|
+
expect((nd.change 1, :year).to_s).to eq "1966-06-08"
|
225
|
+
expect((nd.change -1, :year).to_s).to eq "1964-06-08"
|
226
|
+
expect((nd.change -2, :year).to_s).to eq "1963-06-08"
|
227
|
+
expect((nd.change 2, :year).to_s).to eq "1967-06-08"
|
228
|
+
end
|
229
|
+
|
230
|
+
it "handles leap years and small months" do
|
231
|
+
d = Nydp::Date.new(Date.parse("2019-12-31"))
|
232
|
+
|
233
|
+
expect(d.change( 2, :month).to_s).to eq "2020-02-29"
|
234
|
+
expect(d.change(12, :month).to_s).to eq "2020-12-31"
|
235
|
+
expect(d.change(14, :month).to_s).to eq "2021-02-28"
|
236
|
+
expect(d.change( 6, :month).to_s).to eq "2020-06-30"
|
237
|
+
expect(d.change( 7, :month).to_s).to eq "2020-07-31"
|
238
|
+
|
239
|
+
d = Nydp::Date.new(Date.parse("2020-02-29"))
|
240
|
+
expect(d.change(12, :month).to_s).to eq "2021-02-28"
|
241
|
+
end
|
242
|
+
end
|
150
243
|
end
|
data/spec/embedded_spec.rb
CHANGED
@@ -27,29 +27,29 @@ describe Nydp::Parser do
|
|
27
27
|
it "should parse empty string" do
|
28
28
|
expected = pair_list([sym('string-pieces'), Nydp::StringFragmentCloseToken.new('','')])
|
29
29
|
actual = parse_string ""
|
30
|
-
expect(actual).to eq
|
30
|
+
expect(actual).to eq ''
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should parse external text" do
|
34
34
|
actual = parse_string "a fluffy bunny!"
|
35
|
-
expect(actual) .to eq
|
35
|
+
expect(actual) .to eq "a fluffy bunny!"
|
36
36
|
expect(actual.inspect).to eq '"a fluffy bunny!"'
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should parse a string delimited by eof" do
|
40
40
|
expected = pair_list([sym('string-pieces'), Nydp::StringFragmentCloseToken.new('a fluffy bunny!','a fluffy bunny!')])
|
41
41
|
actual = parse_string "a fluffy bunny!"
|
42
|
-
expect(actual) .to eq
|
42
|
+
expect(actual) .to eq "a fluffy bunny!"
|
43
43
|
expect(actual.inspect).to eq '"a fluffy bunny!"'
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should parse a string with embedded code, delimited by eof" do
|
47
47
|
x1 = sym('string-pieces')
|
48
48
|
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
49
|
-
x2 =
|
49
|
+
x2 = x2.string
|
50
50
|
x3 = sym('expr')
|
51
51
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
52
|
-
x4 =
|
52
|
+
x4 = x4.string
|
53
53
|
|
54
54
|
expected = pair_list([x1,x2,x3,x4])
|
55
55
|
actual = parse_string "a fluffy bunny! ~expr a purple cow!"
|
@@ -59,15 +59,15 @@ describe Nydp::Parser do
|
|
59
59
|
it "should parse a string with embedded code containing a nested string, delimited by eof" do
|
60
60
|
n1 = sym(:foo)
|
61
61
|
n2 = sym(:bar)
|
62
|
-
n3 =
|
62
|
+
n3 = 'an embedded bunny :)'
|
63
63
|
n4 = sym(:zop)
|
64
64
|
|
65
65
|
x1 = sym('string-pieces')
|
66
66
|
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
67
|
-
x2 =
|
67
|
+
x2 = x2.string
|
68
68
|
x3 = pair_list [n1, n2, n3, n4]
|
69
69
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
70
|
-
x4 =
|
70
|
+
x4 = x4.string
|
71
71
|
|
72
72
|
expected = pair_list([x1,x2,x3,x4])
|
73
73
|
actual = parse_string 'a fluffy bunny! ~(foo bar "an embedded bunny :)" zop) a purple cow!'
|
@@ -80,10 +80,10 @@ describe Nydp::Parser do
|
|
80
80
|
|
81
81
|
s1 = sym('string-pieces')
|
82
82
|
s2 = Nydp::StringFragmentToken.new('a rather ','a rather ~')
|
83
|
-
s2 =
|
83
|
+
s2 = s2.string
|
84
84
|
s3 = pair_list [e1, e2]
|
85
85
|
s4 = Nydp::StringFragmentCloseToken.new(' bunny :)',' bunny :)"')
|
86
|
-
s4 =
|
86
|
+
s4 = s4.string
|
87
87
|
|
88
88
|
n1 = sym(:foo)
|
89
89
|
n2 = sym(:bar)
|
@@ -92,10 +92,10 @@ describe Nydp::Parser do
|
|
92
92
|
|
93
93
|
x1 = sym('string-pieces')
|
94
94
|
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
95
|
-
x2 =
|
95
|
+
x2 = x2.string
|
96
96
|
x3 = pair_list [n1, n2, n3, n4]
|
97
97
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
98
|
-
x4 =
|
98
|
+
x4 = x4.string
|
99
99
|
|
100
100
|
expected = pair_list([x1,x2,x3,x4])
|
101
101
|
actual = parse_string "a fluffy bunny! ~(foo bar \"a rather ~(describe bunny) bunny :)\" zop) a purple cow!"
|
data/spec/foreign_hash_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe Nydp::Hash do
|
|
9
9
|
describe "hash set" do
|
10
10
|
it "returns a new Nydp hash" do
|
11
11
|
k = Nydp::Symbol.mk "keysym", ns
|
12
|
-
v =
|
12
|
+
v = "foobar"
|
13
13
|
args = pair_list [ahash, k, v]
|
14
14
|
Nydp::Builtin::HashSet.instance.invoke vm, args
|
15
15
|
|
@@ -29,7 +29,7 @@ describe Nydp::Hash do
|
|
29
29
|
|
30
30
|
Nydp::Builtin::HashGet.instance.invoke vm, pair_list(args)
|
31
31
|
|
32
|
-
expect(vm.args.pop).to eq
|
32
|
+
expect(vm.args.pop).to eq "avalue"
|
33
33
|
end
|
34
34
|
|
35
35
|
it "converts ruby nil to nydp value" do
|
@@ -84,5 +84,17 @@ describe Nydp::Hash do
|
|
84
84
|
expect(vm.args.pop).to eq pair_list [sym("k0"), sym("k1")]
|
85
85
|
end
|
86
86
|
end
|
87
|
+
|
88
|
+
describe "hash-slice" do
|
89
|
+
it "returns a new hash containing only the given keys from the old hash" do
|
90
|
+
ahash[:k0] = 42
|
91
|
+
ahash[:k1] = 84
|
92
|
+
args = [ahash, pair_list([sym("k0"), sym("k1")])]
|
93
|
+
|
94
|
+
Nydp::Builtin::HashSlice.instance.invoke vm, pair_list(args)
|
95
|
+
|
96
|
+
expect(vm.args.pop).to eq({ k0: 42, k1: 84 })
|
97
|
+
end
|
98
|
+
end
|
87
99
|
end
|
88
100
|
end
|
@@ -20,15 +20,15 @@ describe Nydp::Hash do
|
|
20
20
|
args = [ ahash, k ]
|
21
21
|
|
22
22
|
Nydp::Builtin::HashGet.instance.invoke vm, pair_list(args)
|
23
|
-
expect(vm.args.pop).to eq
|
23
|
+
expect(vm.args.pop).to eq "hello there"
|
24
24
|
end
|
25
25
|
|
26
26
|
it "converts string keys to method names" do
|
27
|
-
k =
|
27
|
+
k = "b"
|
28
28
|
args = [ ahash, k ]
|
29
29
|
|
30
30
|
Nydp::Builtin::HashGet.instance.invoke vm, pair_list(args)
|
31
|
-
expect(vm.args.pop).to eq
|
31
|
+
expect(vm.args.pop).to eq "hello there"
|
32
32
|
end
|
33
33
|
|
34
34
|
it "returns nil for unavailable methods" do
|
@@ -42,7 +42,7 @@ describe Nydp::Hash do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
describe "unfriendly non-hash" do
|
45
|
-
let(:ahash) {
|
45
|
+
let(:ahash) { "this here ain't no hash, hombre" }
|
46
46
|
|
47
47
|
def cleanup_err_msg txt
|
48
48
|
txt.gsub(/at \/.*:in `builtin_invoke'/, '<error info>')
|
@@ -51,7 +51,7 @@ describe Nydp::Hash do
|
|
51
51
|
describe "hash set" do
|
52
52
|
it "does nothing, returns its value" do
|
53
53
|
k = Nydp::Symbol.mk "keysym", ns
|
54
|
-
v =
|
54
|
+
v = "foobar"
|
55
55
|
args = pair_list [ahash, k, v]
|
56
56
|
|
57
57
|
begin
|
@@ -66,7 +66,7 @@ with args
|
|
66
66
|
keysym
|
67
67
|
\"foobar\""
|
68
68
|
|
69
|
-
expect(cleanup_err_msg error.cause.message).to eq "_nydp_get : not settable: keysym on
|
69
|
+
expect(cleanup_err_msg error.cause.message).to eq "_nydp_get : not settable: keysym on String"
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -86,7 +86,7 @@ with args
|
|
86
86
|
\"this here ain't no hash, hombre\"
|
87
87
|
keysym"
|
88
88
|
|
89
|
-
expect(cleanup_err_msg error.cause.message).to eq "_nydp_get : not gettable: keysym on
|
89
|
+
expect(cleanup_err_msg error.cause.message).to eq "_nydp_get : not gettable: keysym on String"
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
data/spec/hash_spec.rb
CHANGED
@@ -16,7 +16,7 @@ describe Nydp::Hash do
|
|
16
16
|
|
17
17
|
it "converts ruby string key to nydp string key" do
|
18
18
|
hash = Nydp::Hash.new
|
19
|
-
hash[
|
19
|
+
hash["boo"] = 42
|
20
20
|
|
21
21
|
rhash = hash.to_ruby
|
22
22
|
expect(rhash["boo"]).to eq 42
|
@@ -123,7 +123,7 @@ describe Nydp::Hash do
|
|
123
123
|
describe "hash set" do
|
124
124
|
it "does nothing, returns its value" do
|
125
125
|
k = Nydp::Symbol.mk "keysym", ns
|
126
|
-
v =
|
126
|
+
v = "foobar"
|
127
127
|
args = pair_list [ahash, k, v]
|
128
128
|
Nydp::Builtin::HashSet.instance.invoke vm, args
|
129
129
|
|
@@ -143,4 +143,26 @@ describe Nydp::Hash do
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
end
|
146
|
+
|
147
|
+
describe "hash-slice" do
|
148
|
+
it "returns a new hash containing only the given keys from the old hash" do
|
149
|
+
hash = Nydp::Hash.new
|
150
|
+
sfoo = sym "foo"
|
151
|
+
sbar = sym "bar"
|
152
|
+
syak = sym "yak"
|
153
|
+
szeb = sym "zeb"
|
154
|
+
|
155
|
+
h = Nydp::Hash.new
|
156
|
+
|
157
|
+
h[sfoo] = 16
|
158
|
+
h[sbar] = 42
|
159
|
+
h[szeb] = 99
|
160
|
+
|
161
|
+
args = [h, pair_list([sbar, syak, szeb])]
|
162
|
+
|
163
|
+
Nydp::Builtin::HashSlice.instance.invoke vm, pair_list(args)
|
164
|
+
|
165
|
+
expect(vm.args.pop).to eq({ sbar => 42, szeb => 99 })
|
166
|
+
end
|
167
|
+
end
|
146
168
|
end
|
data/spec/nydp_spec.rb
CHANGED
@@ -22,7 +22,7 @@ describe Nydp do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should add strings" do
|
25
|
-
expect(run '(+ "hello" " " "world")').to eq
|
25
|
+
expect(run '(+ "hello" " " "world")').to eq "hello world"
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should add Pairs" do
|
@@ -46,7 +46,7 @@ describe Nydp do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should convert items to strings" do
|
49
|
-
expect(run "(to-string 3.1415)").to eq
|
49
|
+
expect(run "(to-string 3.1415)").to eq "3.1415"
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should compare integers" do
|
@@ -112,4 +112,16 @@ describe Nydp do
|
|
112
112
|
expect(run code).to eq 17
|
113
113
|
end
|
114
114
|
end
|
115
|
+
|
116
|
+
describe "proc from ruby object" do
|
117
|
+
it "invokes a proc like a builtin function" do
|
118
|
+
Nydp::Symbol.mk(:tt, ns).assign(TestThing.new(42, 720, 9699690))
|
119
|
+
|
120
|
+
one_thing = run "((hash-get tt 'one_thing) 24)"
|
121
|
+
expect(one_thing).to eq(42 + 24)
|
122
|
+
|
123
|
+
two_things = run "((hash-get tt 'two_things) 60 2)"
|
124
|
+
expect(two_things).to eq(60 + (2 * 720))
|
125
|
+
end
|
126
|
+
end
|
115
127
|
end
|
data/spec/pair_spec.rb
CHANGED
@@ -18,7 +18,9 @@ describe Nydp::Pair do
|
|
18
18
|
|
19
19
|
describe :== do
|
20
20
|
it "should be true for two empty lists" do
|
21
|
-
expect(Nydp::Pair.new(NIL, NIL)).to eq Nydp::Pair.new(NIL, NIL)
|
21
|
+
expect(Nydp::Pair.new(Nydp::NIL, Nydp::NIL)).to eq Nydp::Pair.new(Nydp::NIL, Nydp::NIL)
|
22
|
+
|
23
|
+
expect(Nydp::Pair.new(nil, nil)).to eq Nydp::Pair.new(nil, nil)
|
22
24
|
end
|
23
25
|
|
24
26
|
it "there is no empty list, only NIL" do
|
data/spec/parser_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Nydp::Parser do
|
4
|
+
let(:empty) { Nydp::Symbol.mk :"", ns }
|
4
5
|
let(:aa) { Nydp::Symbol.mk :aa, ns }
|
5
6
|
let(:a) { Nydp::Symbol.mk :a, ns }
|
6
7
|
let(:b) { Nydp::Symbol.mk :b, ns }
|
@@ -9,6 +10,7 @@ describe Nydp::Parser do
|
|
9
10
|
let(:zz) { Nydp::Symbol.mk :zz, ns }
|
10
11
|
let(:foo) { Nydp::Symbol.mk :foo, ns }
|
11
12
|
let(:bar) { Nydp::Symbol.mk :bar, ns }
|
13
|
+
let(:foobar) { Nydp::Symbol.mk :foobar, ns }
|
12
14
|
let(:zab) { Nydp::Symbol.mk :zab, ns }
|
13
15
|
let(:quote) { Nydp::Symbol.mk :quote, ns }
|
14
16
|
let(:quasiquote) { Nydp::Symbol.mk :quasiquote, ns }
|
@@ -19,6 +21,7 @@ describe Nydp::Parser do
|
|
19
21
|
let(:dotsyn) { Nydp::Symbol.mk :"dot-syntax", ns }
|
20
22
|
let(:cocosyn) { Nydp::Symbol.mk :"colon-colon-syntax", ns }
|
21
23
|
let(:colosyn) { Nydp::Symbol.mk :"colon-syntax", ns }
|
24
|
+
let(:atsyn) { Nydp::Symbol.mk :"at-syntax", ns }
|
22
25
|
let(:string_pieces) { Nydp::Symbol.mk :"string-pieces", ns }
|
23
26
|
|
24
27
|
it "should return a stream of tokens" do
|
@@ -72,7 +75,7 @@ describe Nydp::Parser do
|
|
72
75
|
s2 = Nydp::StringFragmentCloseToken.new "hello there", '"hello there"'
|
73
76
|
|
74
77
|
x1 = 1
|
75
|
-
x2 =
|
78
|
+
x2 = "hello there"
|
76
79
|
x3 = 3
|
77
80
|
|
78
81
|
expected = pair_list [x1, x2, x3]
|
@@ -82,7 +85,7 @@ describe Nydp::Parser do
|
|
82
85
|
|
83
86
|
it "should parse a string" do
|
84
87
|
x1 = sym 'join'
|
85
|
-
x2 =
|
88
|
+
x2 = " - "
|
86
89
|
x3 = 1
|
87
90
|
x4 = 2
|
88
91
|
x5 = 3
|
@@ -96,7 +99,7 @@ describe Nydp::Parser do
|
|
96
99
|
s2 = Nydp::StringFragmentCloseToken.new "hello (1 2 3) there", '"hello (1 2 3) there"'
|
97
100
|
|
98
101
|
x1 = 1
|
99
|
-
x2 =
|
102
|
+
x2 = "hello (1 2 3) there"
|
100
103
|
x3 = 3
|
101
104
|
|
102
105
|
expected = pair_list [x1, x2, x3]
|
@@ -108,7 +111,7 @@ describe Nydp::Parser do
|
|
108
111
|
s2 = Nydp::StringFragmentCloseToken.new "hello there \"jimmy\"", '"hello there \"jimmy\""'
|
109
112
|
|
110
113
|
x1 = 1
|
111
|
-
x2 =
|
114
|
+
x2 = "hello there \"jimmy\""
|
112
115
|
x3 = 3
|
113
116
|
|
114
117
|
expected = pair_list [x1, x2, x3]
|
@@ -117,7 +120,7 @@ describe Nydp::Parser do
|
|
117
120
|
end
|
118
121
|
|
119
122
|
it "should handle escaped tabs and newlines inside a string" do
|
120
|
-
expected =
|
123
|
+
expected = "hello\tworld\nnice day"
|
121
124
|
parsed = parse "\"hello\\tworld\\nnice day\""
|
122
125
|
expect(parsed).to eq expected
|
123
126
|
end
|
@@ -138,8 +141,8 @@ describe Nydp::Parser do
|
|
138
141
|
parsed = parse("foo.2:3:4")
|
139
142
|
expect(parsed.inspect).to eq "(colon-syntax (dot-syntax foo 2) 3 4)"
|
140
143
|
|
141
|
-
expect(parsed.map &:class).to eq [Nydp::Symbol, Nydp::Pair,
|
142
|
-
expect(parsed.cdr.car.map &:class).to eq [Nydp::Symbol, Nydp::Symbol,
|
144
|
+
expect(parsed.map &:class).to eq [Nydp::Symbol, Nydp::Pair, Integer, Integer]
|
145
|
+
expect(parsed.cdr.car.map &:class).to eq [Nydp::Symbol, Nydp::Symbol, Integer]
|
143
146
|
end
|
144
147
|
|
145
148
|
it "should handle prefix and postfix syntax also" do
|
@@ -156,6 +159,14 @@ describe Nydp::Parser do
|
|
156
159
|
expect(parse "foo::bar").to eq pair_list([cocosyn, foo, bar])
|
157
160
|
end
|
158
161
|
|
162
|
+
it "should parse an at symbol" do
|
163
|
+
expect(parse "foo@bar").to eq pair_list([atsyn, foo, bar])
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should parse a prefix-at symbol" do
|
167
|
+
expect(parse "@foobar").to eq pair_list([atsyn, empty, foobar])
|
168
|
+
end
|
169
|
+
|
159
170
|
it "should parse a colon-symbol within a colon-colon within a dotted symbol" do
|
160
171
|
expected = parse "(colon-colon-syntax (colon-syntax (dot-syntax aa foo) foo) (colon-syntax bar (dot-syntax bar zz)))"
|
161
172
|
expect(parse "aa.foo:foo::bar:bar.zz").to eq expected
|
@@ -204,7 +215,7 @@ describe Nydp::Parser do
|
|
204
215
|
end
|
205
216
|
|
206
217
|
it "retains otherwise unidentified list prefixes" do
|
207
|
-
expect(parse "%wong(bar)").to eq pair_list([prefix_list,
|
218
|
+
expect(parse "%wong(bar)").to eq pair_list([prefix_list, "%wong", pair_list([bar])])
|
208
219
|
end
|
209
220
|
|
210
221
|
it "should do some complicated unquote stuff with lists" do
|
@@ -246,24 +257,24 @@ describe Nydp::Parser do
|
|
246
257
|
end
|
247
258
|
|
248
259
|
it "parses a simple string" do
|
249
|
-
expect(parse '"foo"').to eq
|
260
|
+
expect(parse '"foo"').to eq "foo"
|
250
261
|
end
|
251
262
|
|
252
263
|
it "parses a string with a simple interpolation" do
|
253
|
-
str =
|
254
|
-
empty =
|
255
|
-
expect(parse '"foo ~foo"').to eq pair_list([string_pieces, str, foo
|
264
|
+
str = "foo "
|
265
|
+
empty = ""
|
266
|
+
expect(parse '"foo ~foo"').to eq pair_list([string_pieces, str, foo])
|
256
267
|
end
|
257
268
|
|
258
269
|
it "parses a string with a more complex interpolation" do
|
259
|
-
strf =
|
260
|
-
strb =
|
270
|
+
strf = "foo "
|
271
|
+
strb = " bar"
|
261
272
|
expect(parse '"foo ~(foo bar) bar"').to eq pair_list([string_pieces, strf, pair_list([foo, bar]), strb])
|
262
273
|
end
|
263
274
|
|
264
275
|
it "parses a string with an interpolation containing a nested interpolation" do
|
265
|
-
strf =
|
266
|
-
strb =
|
276
|
+
strf = "foo "
|
277
|
+
strb = " bar"
|
267
278
|
|
268
279
|
nested = pair_list [string_pieces, strf, foo, strb]
|
269
280
|
expr = pair_list [foo, nested, bar]
|
@@ -272,8 +283,8 @@ describe Nydp::Parser do
|
|
272
283
|
end
|
273
284
|
|
274
285
|
it "parses a string with only an interpolation" do
|
275
|
-
empty =
|
276
|
-
expect(parse '"~foo"').to eq
|
286
|
+
empty = ""
|
287
|
+
expect(parse '"~foo"').to eq foo
|
277
288
|
end
|
278
289
|
|
279
290
|
it "should even parse comments" do
|
@@ -281,7 +292,7 @@ describe Nydp::Parser do
|
|
281
292
|
; here's a comment
|
282
293
|
(zab))
|
283
294
|
"
|
284
|
-
c1 = pair_list([comment,
|
295
|
+
c1 = pair_list([comment, "here's a comment"])
|
285
296
|
fbar = pair_list([bar])
|
286
297
|
fzab = pair_list([Nydp::Symbol.mk(:zab, ns)])
|
287
298
|
fdef = Nydp::Symbol.mk(:def, ns)
|
@@ -311,7 +322,7 @@ NYDP
|
|
311
322
|
expect(args[1]).to eq sym("args")
|
312
323
|
expect(args[2]).to be_nil
|
313
324
|
expect(parsed[2].cdr.cdr).to eq sym("body")
|
314
|
-
expect(parsed[3].to_a).to eq [sym("comment"),
|
325
|
+
expect(parsed[3].to_a).to eq [sym("comment"), "define a new function in the global namespace"]
|
315
326
|
expect(parsed[4].to_a).to eq [sym("chapter"), sym("nydp-core")]
|
316
327
|
end
|
317
328
|
end
|