nydp 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.zeiger.yml +28 -0
- data/lib/lisp/core-000.nydp +1 -1
- data/lib/lisp/core-015-documentation.nydp +6 -9
- data/lib/lisp/core-017-builtin-dox.nydp +33 -0
- data/lib/lisp/core-025-warnings.nydp +15 -0
- data/lib/lisp/core-030-syntax.nydp +38 -2
- data/lib/lisp/core-035-flow-control.nydp +2 -2
- data/lib/lisp/core-037-list-utils.nydp +7 -5
- data/lib/lisp/core-040-utils.nydp +15 -4
- data/lib/lisp/core-043-list-utils.nydp +1 -0
- data/lib/lisp/core-045-dox-utils.nydp +6 -0
- data/lib/lisp/core-050-test-runner.nydp +9 -9
- data/lib/lisp/core-070-prefix-list.nydp +2 -2
- data/lib/lisp/core-090-hook.nydp +24 -0
- data/lib/lisp/core-100-utils.nydp +38 -10
- data/lib/lisp/tests/ampersand-syntax-examples.nydp +26 -0
- data/lib/lisp/tests/boot-tests.nydp +1 -1
- data/lib/lisp/tests/collect-tests.nydp +4 -0
- data/lib/lisp/tests/destructuring-examples.nydp +18 -1
- data/lib/lisp/tests/fill-bucket-examples.nydp +46 -2
- data/lib/lisp/tests/floor-examples.nydp +58 -0
- data/lib/lisp/tests/k-examples.nydp +5 -0
- data/lib/lisp/tests/power-examples.nydp +16 -0
- data/lib/lisp/tests/string-tests.nydp +8 -0
- data/lib/lisp/tests/syntax-tests.nydp +6 -0
- data/lib/lisp/tests/zip-examples.nydp +16 -0
- data/lib/nydp.rb +6 -2
- data/lib/nydp/assignment.rb +1 -2
- data/lib/nydp/builtin/ensuring.rb +1 -2
- data/lib/nydp/builtin/greater_than.rb +2 -2
- data/lib/nydp/builtin/handle_error.rb +1 -2
- data/lib/nydp/builtin/less_than.rb +2 -2
- data/lib/nydp/builtin/math_ceiling.rb +7 -0
- data/lib/nydp/builtin/math_floor.rb +7 -0
- data/lib/nydp/builtin/math_power.rb +7 -0
- data/lib/nydp/builtin/math_round.rb +7 -0
- data/lib/nydp/builtin/parse.rb +2 -2
- data/lib/nydp/builtin/parse_in_string.rb +3 -3
- data/lib/nydp/builtin/pre_compile.rb +0 -1
- data/lib/nydp/compiler.rb +1 -1
- data/lib/nydp/cond.rb +3 -6
- data/lib/nydp/context_symbol.rb +40 -32
- data/lib/nydp/core.rb +8 -2
- data/lib/nydp/function_invocation.rb +3 -5
- data/lib/nydp/image_store.rb +21 -0
- data/lib/nydp/interpreted_function.rb +8 -12
- data/lib/nydp/lexical_context_builder.rb +19 -35
- data/lib/nydp/pair.rb +2 -1
- data/lib/nydp/parser.rb +4 -0
- data/lib/nydp/plugin.rb +15 -8
- data/lib/nydp/runner.rb +3 -3
- data/lib/nydp/symbol.rb +3 -1
- data/lib/nydp/symbol_lookup.rb +2 -2
- data/lib/nydp/truth.rb +2 -2
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +47 -27
- data/spec/date_spec.rb +2 -2
- data/spec/embedded_spec.rb +16 -16
- data/spec/error_spec.rb +1 -1
- data/spec/nydp_spec.rb +13 -4
- data/spec/parser_spec.rb +63 -16
- data/spec/spec_helper.rb +1 -2
- data/spec/string_atom_spec.rb +2 -2
- data/spec/symbol_spec.rb +2 -2
- data/spec/tokeniser_spec.rb +101 -0
- metadata +16 -2
data/lib/nydp/truth.rb
CHANGED
@@ -17,8 +17,8 @@ module Nydp
|
|
17
17
|
def car ; self ; end
|
18
18
|
def cdr ; self ; end
|
19
19
|
def size ; 0 ; end
|
20
|
-
def is? other ;
|
21
|
-
def isnt? other ;
|
20
|
+
def is? other ; self == other ; end
|
21
|
+
def isnt? other ; self != other ; end
|
22
22
|
def to_s ; "" ; end
|
23
23
|
def + other ; other ; end
|
24
24
|
def copy ; self ; end
|
data/lib/nydp/version.rb
CHANGED
data/lib/nydp/vm.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Nydp
|
2
2
|
class VM
|
3
|
+
NIL = Nydp::NIL
|
3
4
|
include Helper
|
4
|
-
attr_accessor :instructions, :args, :contexts, :current_context, :locals, :unhandled_error, :last_error, :ns
|
5
|
+
attr_accessor :instructions, :args, :contexts, :current_context, :locals, :unhandled_error, :last_error, :ns, :thisi
|
5
6
|
|
6
7
|
module Finally ; end
|
7
8
|
module HandleError ; end
|
@@ -14,36 +15,56 @@ module Nydp
|
|
14
15
|
@ns = ns
|
15
16
|
end
|
16
17
|
|
17
|
-
def r2n obj
|
18
|
-
|
18
|
+
def r2n obj ; super obj, @ns ; end
|
19
|
+
|
20
|
+
def push_instructions ii, ctx
|
21
|
+
if @current_instructions && NIL != @current_instructions
|
22
|
+
@instructions.push @current_instructions
|
23
|
+
@contexts.push @current_context
|
24
|
+
end
|
25
|
+
|
26
|
+
@current_instructions = ii
|
27
|
+
@current_context = ctx
|
28
|
+
end
|
29
|
+
|
30
|
+
def push_ctx_instructions ii
|
31
|
+
if @current_instructions && NIL != @current_instructions
|
32
|
+
@instructions.push @current_instructions
|
33
|
+
@contexts.push @current_context
|
34
|
+
end
|
35
|
+
|
36
|
+
@current_instructions = ii
|
19
37
|
end
|
20
38
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
39
|
+
def thread_with_expr expr
|
40
|
+
@current_instructions = expr
|
41
|
+
thread
|
42
|
+
end
|
43
|
+
|
44
|
+
def thread
|
45
|
+
while @current_instructions
|
24
46
|
begin
|
25
|
-
|
26
|
-
|
27
|
-
|
47
|
+
if NIL == @current_instructions
|
48
|
+
@current_instructions = @instructions.pop
|
49
|
+
@current_context = @contexts.pop
|
28
50
|
else
|
29
|
-
|
30
|
-
|
51
|
+
now = @current_instructions.car
|
52
|
+
@current_instructions = @current_instructions.cdr
|
53
|
+
now.execute(self)
|
31
54
|
end
|
32
|
-
|
55
|
+
|
33
56
|
rescue StandardError => e
|
34
57
|
handle_error e
|
35
58
|
end
|
36
59
|
end
|
37
|
-
raise_unhandled_error
|
38
|
-
args.pop
|
39
|
-
end
|
40
60
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
self.unhandled_error = nil
|
61
|
+
if @unhandled_error
|
62
|
+
e = @unhandled_error
|
63
|
+
@unhandled_error = nil
|
45
64
|
raise e
|
46
65
|
end
|
66
|
+
|
67
|
+
args.pop
|
47
68
|
end
|
48
69
|
|
49
70
|
def handle_error ex
|
@@ -52,19 +73,18 @@ module Nydp
|
|
52
73
|
protecti = []
|
53
74
|
protectc = []
|
54
75
|
|
55
|
-
while (instructions.length > 0) && !(instructions.last.car.is_a? HandleError)
|
56
|
-
if instructions.last.car.is_a? Finally
|
57
|
-
protecti << instructions.last
|
58
|
-
protectc << contexts.last
|
76
|
+
while (@instructions.length > 0) && !(@instructions.last.car.is_a? HandleError)
|
77
|
+
if @instructions.last.car.is_a? Finally
|
78
|
+
protecti << @instructions.last
|
79
|
+
protectc << @contexts.last
|
59
80
|
end
|
60
81
|
|
61
|
-
instructions.pop
|
62
|
-
contexts.pop
|
82
|
+
@instructions.pop
|
83
|
+
@contexts.pop
|
63
84
|
end
|
64
85
|
|
65
86
|
while protecti.length > 0
|
66
|
-
|
67
|
-
contexts.push protectc.pop
|
87
|
+
push_instructions protecti.pop, protectc.pop
|
68
88
|
end
|
69
89
|
end
|
70
90
|
|
data/spec/date_spec.rb
CHANGED
@@ -60,7 +60,7 @@ describe Nydp::Date do
|
|
60
60
|
|
61
61
|
f.invoke vm, pair_list([d1, d0])
|
62
62
|
|
63
|
-
expect(vm.args.pop).to eq
|
63
|
+
expect(vm.args.pop).to eq d0
|
64
64
|
end
|
65
65
|
|
66
66
|
it "compares with nil" do
|
@@ -86,7 +86,7 @@ describe Nydp::Date do
|
|
86
86
|
|
87
87
|
f.invoke vm, pair_list([d0, d1])
|
88
88
|
|
89
|
-
expect(vm.args.pop).to eq
|
89
|
+
expect(vm.args.pop).to eq d1
|
90
90
|
end
|
91
91
|
|
92
92
|
it "works with builtin less-than when false" do
|
data/spec/embedded_spec.rb
CHANGED
@@ -19,40 +19,40 @@ describe Nydp::Parser do
|
|
19
19
|
let(:cocosyn) { Nydp::Symbol.mk :"colon-colon-syntax", ns }
|
20
20
|
let(:colosyn) { Nydp::Symbol.mk :"colon-syntax", ns }
|
21
21
|
|
22
|
-
def parse_string txt
|
22
|
+
def parse_string txt
|
23
23
|
reader = Nydp::StringReader.new txt
|
24
|
-
Nydp
|
24
|
+
Nydp.new_parser(ns).embedded(Nydp.new_tokeniser(reader))
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should parse empty string" do
|
28
|
-
expected = pair_list([sym('string-pieces'), Nydp::StringFragmentCloseToken.new('','
|
29
|
-
actual = parse_string "
|
28
|
+
expected = pair_list([sym('string-pieces'), Nydp::StringFragmentCloseToken.new('','')])
|
29
|
+
actual = parse_string ""
|
30
30
|
expect(actual).to eq Nydp::StringAtom.new ''
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should parse external text" do
|
34
|
-
actual = parse_string "a fluffy bunny!"
|
35
|
-
expect(actual) .to eq Nydp::StringAtom.new "a fluffy bunny"
|
36
|
-
expect(actual.inspect).to eq '"a fluffy bunny"'
|
34
|
+
actual = parse_string "a fluffy bunny!"
|
35
|
+
expect(actual) .to eq Nydp::StringAtom.new "a fluffy bunny!"
|
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
|
-
actual = parse_string "a fluffy bunny!"
|
41
|
+
actual = parse_string "a fluffy bunny!"
|
42
42
|
expect(actual) .to eq Nydp::StringAtom.new "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
|
-
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','
|
48
|
+
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
49
49
|
x2 = Nydp::StringAtom.new(x2.string, x2)
|
50
50
|
x3 = sym('expr')
|
51
51
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
52
52
|
x4 = Nydp::StringAtom.new(x4.string, x4)
|
53
53
|
|
54
54
|
expected = pair_list([x1,x2,x3,x4])
|
55
|
-
actual = parse_string "a fluffy bunny! ~expr a purple cow!"
|
55
|
+
actual = parse_string "a fluffy bunny! ~expr a purple cow!"
|
56
56
|
expect(actual).to eq expected
|
57
57
|
end
|
58
58
|
|
@@ -63,14 +63,14 @@ describe Nydp::Parser do
|
|
63
63
|
n4 = sym(:zop)
|
64
64
|
|
65
65
|
x1 = sym('string-pieces')
|
66
|
-
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','
|
66
|
+
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
67
67
|
x2 = Nydp::StringAtom.new(x2.string, x2)
|
68
68
|
x3 = pair_list [n1, n2, n3, n4]
|
69
69
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
70
70
|
x4 = Nydp::StringAtom.new(x4.string, x4)
|
71
71
|
|
72
72
|
expected = pair_list([x1,x2,x3,x4])
|
73
|
-
actual = parse_string
|
73
|
+
actual = parse_string 'a fluffy bunny! ~(foo bar "an embedded bunny :)" zop) a purple cow!'
|
74
74
|
expect(actual).to eq expected
|
75
75
|
end
|
76
76
|
|
@@ -79,7 +79,7 @@ describe Nydp::Parser do
|
|
79
79
|
e2 = sym(:bunny)
|
80
80
|
|
81
81
|
s1 = sym('string-pieces')
|
82
|
-
s2 = Nydp::StringFragmentToken.new('a rather ','
|
82
|
+
s2 = Nydp::StringFragmentToken.new('a rather ','a rather ~')
|
83
83
|
s2 = Nydp::StringAtom.new(s2.string, s2)
|
84
84
|
s3 = pair_list [e1, e2]
|
85
85
|
s4 = Nydp::StringFragmentCloseToken.new(' bunny :)',' bunny :)"')
|
@@ -91,19 +91,19 @@ describe Nydp::Parser do
|
|
91
91
|
n4 = sym(:zop)
|
92
92
|
|
93
93
|
x1 = sym('string-pieces')
|
94
|
-
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','
|
94
|
+
x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','a fluffy bunny! ~')
|
95
95
|
x2 = Nydp::StringAtom.new(x2.string, x2)
|
96
96
|
x3 = pair_list [n1, n2, n3, n4]
|
97
97
|
x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
|
98
98
|
x4 = Nydp::StringAtom.new(x4.string, x4)
|
99
99
|
|
100
100
|
expected = pair_list([x1,x2,x3,x4])
|
101
|
-
actual = parse_string "a fluffy bunny! ~(foo bar \"a rather ~(describe bunny) bunny :)\" zop) a purple cow!"
|
101
|
+
actual = parse_string "a fluffy bunny! ~(foo bar \"a rather ~(describe bunny) bunny :)\" zop) a purple cow!"
|
102
102
|
expect(actual).to eq expected
|
103
103
|
end
|
104
104
|
|
105
105
|
it "parses a string that looks like html with little bits of embedded code in it" do
|
106
|
-
parsed = parse_string "<div id='item_~{id}'><label>~{data-label-1}</label> ~{data-content-1}</div>"
|
106
|
+
parsed = parse_string "<div id='item_~{id}'><label>~{data-label-1}</label> ~{data-content-1}</div>"
|
107
107
|
expect(parsed.inspect).to eq '(string-pieces "<div id=\'item_" (brace-list id) "\'><label>" (brace-list data-label-1) "</label> " (brace-list data-content-1) "</div>")'
|
108
108
|
end
|
109
109
|
end
|
data/spec/error_spec.rb
CHANGED
@@ -21,7 +21,7 @@ describe Nydp::VM do
|
|
21
21
|
expect(error).to be_a Nydp::Error
|
22
22
|
expect(error.message).to eq "failed to eval dflkjdgjeirgjeoi"
|
23
23
|
|
24
|
-
expect(error.cause).to be_a Nydp::
|
24
|
+
expect(error.cause).to be_a Nydp::Symbol::Unbound
|
25
25
|
expect(error.cause.message).to eq "unbound symbol: dflkjdgjeirgjeoi"
|
26
26
|
|
27
27
|
expect(vm.unhandled_error).to eq nil
|
data/spec/nydp_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Nydp do
|
4
|
-
let(:parser) { Nydp
|
4
|
+
let(:parser) { Nydp.new_parser(ns) }
|
5
5
|
let(:vm) { Nydp::VM.new(ns) }
|
6
6
|
|
7
7
|
def run txt
|
@@ -9,6 +9,10 @@ describe Nydp do
|
|
9
9
|
Nydp.eval_src ns, txt
|
10
10
|
end
|
11
11
|
|
12
|
+
it "invokes a zero-arg function" do
|
13
|
+
expect(run('(to-string)').to_s).to eq ""
|
14
|
+
end
|
15
|
+
|
12
16
|
it "should make a symbol from a string" do
|
13
17
|
expect(run '(sym "the-family")').to eq sym(:"the-family")
|
14
18
|
end
|
@@ -47,8 +51,8 @@ describe Nydp do
|
|
47
51
|
|
48
52
|
it "should compare integers" do
|
49
53
|
expect(run "(> 13 17)").to eq Nydp::NIL
|
50
|
-
expect(run "(> 29 23)").to eq
|
51
|
-
expect(run "(< 13 17)").to eq
|
54
|
+
expect(run "(> 29 23)").to eq 23
|
55
|
+
expect(run "(< 13 17)").to eq 17
|
52
56
|
expect(run "(< 29 23)").to eq Nydp::NIL
|
53
57
|
end
|
54
58
|
|
@@ -80,7 +84,12 @@ describe Nydp do
|
|
80
84
|
end
|
81
85
|
|
82
86
|
it "should recurse without consuming extra memory" do
|
83
|
-
program = "(assign f1 (fn (x acc)
|
87
|
+
program = "(assign f1 (fn (x acc)
|
88
|
+
(cond (< x 1)
|
89
|
+
(vm-info)
|
90
|
+
(f1 (- x 1)
|
91
|
+
(+ x acc)))))
|
92
|
+
(f1 1000 0)"
|
84
93
|
expected = parse "((contexts . 0) (instructions . 0) (args . 0))"
|
85
94
|
expect(run program).to eq expected
|
86
95
|
end
|
data/spec/parser_spec.rb
CHANGED
@@ -19,25 +19,14 @@ describe Nydp::Parser do
|
|
19
19
|
let(:dotsyn) { Nydp::Symbol.mk :"dot-syntax", ns }
|
20
20
|
let(:cocosyn) { Nydp::Symbol.mk :"colon-colon-syntax", ns }
|
21
21
|
let(:colosyn) { Nydp::Symbol.mk :"colon-syntax", ns }
|
22
|
+
let(:string_pieces) { Nydp::Symbol.mk :"string-pieces", ns }
|
22
23
|
|
23
24
|
it "should return a stream of tokens" do
|
24
25
|
reader = Nydp::StringReader.new ""
|
25
|
-
t = Nydp
|
26
|
+
t = Nydp.new_tokeniser reader
|
26
27
|
expect(t.next_token).to eq nil
|
27
28
|
end
|
28
29
|
|
29
|
-
it "should return another stream of tokens" do
|
30
|
-
reader = Nydp::StringReader.new "(a b c 1 2 3)"
|
31
|
-
t = Nydp::Tokeniser.new reader
|
32
|
-
tt = []
|
33
|
-
tok = t.next_token
|
34
|
-
while tok
|
35
|
-
tt << tok
|
36
|
-
tok = t.next_token
|
37
|
-
end
|
38
|
-
expect(tt).to eq [[:left_paren, ""], [:symbol, "a"], [:symbol, "b"], [:symbol, "c"], [:number, 1.0], [:number, 2.0], [:number, 3.0], [:right_paren]]
|
39
|
-
end
|
40
|
-
|
41
30
|
it "should parse an empty expression" do
|
42
31
|
expect(parse "").to be_nil
|
43
32
|
end
|
@@ -75,8 +64,11 @@ describe Nydp::Parser do
|
|
75
64
|
expect(parse "(1 2 3 . 4)").to eq pair_list([1, 2, 3], 4)
|
76
65
|
end
|
77
66
|
|
67
|
+
it "should parse an improper list containing symbols" do
|
68
|
+
expect(parse "(foo foo . bar)").to eq pair_list([foo, foo], bar)
|
69
|
+
end
|
70
|
+
|
78
71
|
it "should parse a string" do
|
79
|
-
s1 = sym 'string-pieces'
|
80
72
|
s2 = Nydp::StringFragmentCloseToken.new "hello there", '"hello there"'
|
81
73
|
|
82
74
|
x1 = 1
|
@@ -101,7 +93,6 @@ describe Nydp::Parser do
|
|
101
93
|
end
|
102
94
|
|
103
95
|
it "should not get confused by embedded lisp in a string" do
|
104
|
-
s1 = sym 'string-pieces'
|
105
96
|
s2 = Nydp::StringFragmentCloseToken.new "hello (1 2 3) there", '"hello (1 2 3) there"'
|
106
97
|
|
107
98
|
x1 = 1
|
@@ -114,7 +105,6 @@ describe Nydp::Parser do
|
|
114
105
|
end
|
115
106
|
|
116
107
|
it "should handle escaped quotes inside a string" do
|
117
|
-
s1 = sym 'string-pieces'
|
118
108
|
s2 = Nydp::StringFragmentCloseToken.new "hello there \"jimmy\"", '"hello there \"jimmy\""'
|
119
109
|
|
120
110
|
x1 = 1
|
@@ -255,6 +245,37 @@ describe Nydp::Parser do
|
|
255
245
|
expect(parse "(a b (c) d)").to eq pair_list([a, b, pair_list([c]), d])
|
256
246
|
end
|
257
247
|
|
248
|
+
it "parses a simple string" do
|
249
|
+
expect(parse '"foo"').to eq Nydp::StringAtom.new("foo")
|
250
|
+
end
|
251
|
+
|
252
|
+
it "parses a string with a simple interpolation" do
|
253
|
+
str = Nydp::StringAtom.new("foo ")
|
254
|
+
empty = Nydp::StringAtom.new("")
|
255
|
+
expect(parse '"foo ~foo"').to eq pair_list([string_pieces, str, foo, empty])
|
256
|
+
end
|
257
|
+
|
258
|
+
it "parses a string with a more complex interpolation" do
|
259
|
+
strf = Nydp::StringAtom.new("foo ")
|
260
|
+
strb = Nydp::StringAtom.new(" bar")
|
261
|
+
expect(parse '"foo ~(foo bar) bar"').to eq pair_list([string_pieces, strf, pair_list([foo, bar]), strb])
|
262
|
+
end
|
263
|
+
|
264
|
+
it "parses a string with an interpolation containing a nested interpolation" do
|
265
|
+
strf = Nydp::StringAtom.new("foo ")
|
266
|
+
strb = Nydp::StringAtom.new(" bar")
|
267
|
+
|
268
|
+
nested = pair_list [string_pieces, strf, foo, strb]
|
269
|
+
expr = pair_list [foo, nested, bar]
|
270
|
+
|
271
|
+
expect(parse '"foo ~(foo "foo ~foo bar" bar) bar"').to eq pair_list([string_pieces, strf, expr, strb])
|
272
|
+
end
|
273
|
+
|
274
|
+
it "parses a string with only an interpolation" do
|
275
|
+
empty = Nydp::StringAtom.new("")
|
276
|
+
expect(parse '"~foo"').to eq pair_list([string_pieces, empty, foo, empty])
|
277
|
+
end
|
278
|
+
|
258
279
|
it "should even parse comments" do
|
259
280
|
txt = "(def foo (bar)
|
260
281
|
; here's a comment
|
@@ -267,4 +288,30 @@ describe Nydp::Parser do
|
|
267
288
|
expr = pair_list([fdef, foo, fbar, c1, fzab])
|
268
289
|
expect(parse txt).to eq expr
|
269
290
|
end
|
291
|
+
|
292
|
+
it "parses an expression with whitespace before closing paren" do
|
293
|
+
txt = <<NYDP
|
294
|
+
(def plugin-end (name) (assign this-plugin nil ) (chapter-end))
|
295
|
+
NYDP
|
296
|
+
expect(parse(txt).to_a.inspect).to eq "[def, plugin-end, (name), (assign this-plugin nil), (chapter-end)]"
|
297
|
+
end
|
298
|
+
|
299
|
+
it "parses a more complete expression" do
|
300
|
+
txt = <<NYDP
|
301
|
+
(mac def (name args . body)
|
302
|
+
; define a new function in the global namespace
|
303
|
+
(chapter nydp-core)
|
304
|
+
(define-def-expr name args (filter-forms (build-def-hash (hash)) body)))
|
305
|
+
NYDP
|
306
|
+
parsed = parse(txt).to_a
|
307
|
+
expect(parsed[0]).to eq sym("mac")
|
308
|
+
expect(parsed[1]).to eq sym("def")
|
309
|
+
args = parsed[2].to_a
|
310
|
+
expect(args[0]).to eq sym("name")
|
311
|
+
expect(args[1]).to eq sym("args")
|
312
|
+
expect(args[2]).to be_nil
|
313
|
+
expect(parsed[2].cdr.cdr).to eq sym("body")
|
314
|
+
expect(parsed[3].to_a).to eq [sym("comment"), Nydp::StringAtom.new("define a new function in the global namespace")]
|
315
|
+
expect(parsed[4].to_a).to eq [sym("chapter"), sym("nydp-core")]
|
316
|
+
end
|
270
317
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,8 +7,7 @@ module SpecHelper
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def parse txt
|
10
|
-
|
11
|
-
Nydp::Parser.new(ns).expression(Nydp::Tokeniser.new reader)
|
10
|
+
Nydp.new_parser(ns).expression(Nydp.new_tokeniser Nydp::StringReader.new(txt))
|
12
11
|
end
|
13
12
|
|
14
13
|
def pair_list xs, last=Nydp::NIL
|
data/spec/string_atom_spec.rb
CHANGED
@@ -32,7 +32,7 @@ describe Nydp::StringAtom do
|
|
32
32
|
|
33
33
|
f.invoke vm, pair_list([foo, bar])
|
34
34
|
|
35
|
-
expect(vm.args.pop).to eq
|
35
|
+
expect(vm.args.pop).to eq bar
|
36
36
|
end
|
37
37
|
|
38
38
|
it "works with builtin greater-than when false" do
|
@@ -48,7 +48,7 @@ describe Nydp::StringAtom do
|
|
48
48
|
|
49
49
|
f.invoke vm, pair_list([bar, foo])
|
50
50
|
|
51
|
-
expect(vm.args.pop).to eq
|
51
|
+
expect(vm.args.pop).to eq foo
|
52
52
|
end
|
53
53
|
|
54
54
|
it "works with builtin less-than when false" do
|