rouge-lang 0.0.1 → 0.0.2
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.
- data/lib/boot.rg +26 -8
- data/lib/rouge/context.rb +4 -2
- data/lib/rouge/reader.rb +4 -4
- data/lib/rouge/version.rb +1 -1
- data/misc/TODO +0 -1
- data/spec/core_spec.rg +3 -0
- data/spec/reader_spec.rb +241 -241
- metadata +1 -1
data/lib/boot.rg
CHANGED
@@ -108,7 +108,9 @@
|
|
108
108
|
(reduce .+ args)))
|
109
109
|
|
110
110
|
(defn - [a & args]
|
111
|
-
(
|
111
|
+
(if (= () args)
|
112
|
+
(.-@ a)
|
113
|
+
(reduce .- (concat (list a) args))))
|
112
114
|
|
113
115
|
(defn * [& args]
|
114
116
|
(if (empty? args)
|
@@ -373,24 +375,40 @@
|
|
373
375
|
{:passed @*tests-passed*
|
374
376
|
:failed @*tests-failed*})))
|
375
377
|
|
378
|
+
(defn check-code [check]
|
379
|
+
(if (and (seq? check)
|
380
|
+
(= (first check) '=)
|
381
|
+
(= (count check) 3))
|
382
|
+
(let [[_ l r] check]
|
383
|
+
`(let [l# ~l
|
384
|
+
r# ~r]
|
385
|
+
(if (= l# r#)
|
386
|
+
{:result true}
|
387
|
+
{:result false, :error `(~'~'= ~r# ~'~r)})))
|
388
|
+
{:error nil, :result check}))
|
389
|
+
|
390
|
+
(defn format-actual [check]
|
391
|
+
(if (and (seq? check)
|
392
|
+
(= (first check) 'not)
|
393
|
+
(= (count check) 2))
|
394
|
+
(second check)
|
395
|
+
`(not ~check)))
|
396
|
+
|
376
397
|
(defmacro is [check]
|
377
398
|
`(let [result# (try
|
378
|
-
|
399
|
+
~(check-code check)
|
379
400
|
(catch Exception e#
|
380
401
|
{:error e#, :result false}))]
|
381
|
-
(if (not (
|
402
|
+
(if (not (:result result#))
|
382
403
|
(do
|
383
404
|
(swap! *tests-failed* conj (conj *test-level* (pr-str '~check)))
|
384
405
|
(puts "FAIL in ???")
|
385
406
|
(puts "expected: " ~(pr-str check))
|
386
407
|
(let [actual#
|
387
|
-
(let [error# (
|
408
|
+
(let [error# (:error result#)]
|
388
409
|
(if error#
|
389
410
|
error#
|
390
|
-
(
|
391
|
-
(= 'not (first '~check)))
|
392
|
-
(second '~check)
|
393
|
-
`(not ~'~check))))]
|
411
|
+
(format-actual '~check)))]
|
394
412
|
(puts " actual: " (pr-str actual#))))
|
395
413
|
(do
|
396
414
|
(swap! *tests-passed* inc)
|
data/lib/rouge/context.rb
CHANGED
@@ -197,8 +197,10 @@ class Rouge::Context
|
|
197
197
|
default
|
198
198
|
end
|
199
199
|
else
|
200
|
-
raise
|
201
|
-
|
200
|
+
raise(
|
201
|
+
ArgumentError,
|
202
|
+
"Wrong number of args (#{num_args}) passed to " \
|
203
|
+
"ruby/Symbol #{fun.inspect}")
|
202
204
|
end
|
203
205
|
when Hash
|
204
206
|
if num_args == 1 || num_args == 2
|
data/lib/rouge/reader.rb
CHANGED
@@ -164,7 +164,7 @@ class Rouge::Reader
|
|
164
164
|
def syntaxquotation
|
165
165
|
consume
|
166
166
|
@gensyms.unshift(@@gensym_counter += 1)
|
167
|
-
r = dequote
|
167
|
+
r = dequote(lex)
|
168
168
|
@gensyms.shift
|
169
169
|
r
|
170
170
|
end
|
@@ -181,7 +181,7 @@ class Rouge::Reader
|
|
181
181
|
|
182
182
|
def dequote form
|
183
183
|
case form
|
184
|
-
when Rouge::Seq::
|
184
|
+
when Rouge::Seq::ISeq, Array
|
185
185
|
rest = []
|
186
186
|
group = []
|
187
187
|
form.each do |f|
|
@@ -233,7 +233,7 @@ class Rouge::Reader
|
|
233
233
|
begin
|
234
234
|
var = @ns[form.name]
|
235
235
|
Rouge::Seq::Cons[Rouge::Symbol[:quote],
|
236
|
-
Rouge::Symbol[var.name]]
|
236
|
+
Rouge::Symbol[:"#{var.ns}/#{var.name}"]]
|
237
237
|
rescue Rouge::Namespace::VarNotFoundError
|
238
238
|
Rouge::Seq::Cons[Rouge::Symbol[:quote],
|
239
239
|
Rouge::Symbol[:"#{@ns.name}/#{form.name}"]]
|
@@ -427,7 +427,7 @@ class Rouge::Reader
|
|
427
427
|
)\z
|
428
428
|
/ox
|
429
429
|
|
430
|
-
SYMBOL = /^(\.\[\])|([a-zA-Z0-9\-_!&\?\*\/\.\+\|=%$<>#]+)/
|
430
|
+
SYMBOL = /^(\.\[\])|(\.?[-+]@)|([a-zA-Z0-9\-_!&\?\*\/\.\+\|=%$<>#]+)/
|
431
431
|
end
|
432
432
|
|
433
433
|
# vim: set sw=2 et cc=80:
|
data/lib/rouge/version.rb
CHANGED
data/misc/TODO
CHANGED
data/spec/core_spec.rg
CHANGED
data/spec/reader_spec.rb
CHANGED
@@ -39,379 +39,379 @@ describe Rouge::Reader do
|
|
39
39
|
it { @ns.read("-0333").should eq(-219) }
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
context "bad numbers" do
|
43
|
+
it { expect { @ns.read("1.2.3")
|
44
|
+
}.to raise_exception Rouge::Reader::UnexpectedCharacterError }
|
45
|
+
|
46
|
+
it { expect { @ns.read("12..")
|
47
|
+
}.to raise_exception Rouge::Reader::UnexpectedCharacterError }
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
|
-
|
49
|
-
@ns.read("loki").should eq Rouge::Symbol[:loki]
|
50
|
-
@ns.read("wah?").should eq Rouge::Symbol[:wah?]
|
51
|
-
@ns.read("!ruby!").should eq Rouge::Symbol[:"!ruby!"]
|
52
|
-
@ns.read("nil").should eq Rouge::Symbol[:nil]
|
53
|
-
@ns.read("nil").should eq nil
|
54
|
-
@ns.read("true").should eq Rouge::Symbol[:true]
|
55
|
-
@ns.read("true").should eq true
|
56
|
-
@ns.read("false").should eq Rouge::Symbol[:false]
|
57
|
-
@ns.read("false").should eq false
|
58
|
-
@ns.read("&").should eq Rouge::Symbol[:&]
|
59
|
-
@ns.read("*").should eq Rouge::Symbol[:*]
|
60
|
-
@ns.read("-").should eq Rouge::Symbol[:-]
|
61
|
-
@ns.read("+").should eq Rouge::Symbol[:+]
|
62
|
-
@ns.read("/").should eq Rouge::Symbol[:/]
|
63
|
-
@ns.read("|").should eq Rouge::Symbol[:|]
|
64
|
-
@ns.read("$").should eq Rouge::Symbol[:"$"]
|
65
|
-
@ns.read(".").should eq Rouge::Symbol[:"."]
|
66
|
-
@ns.read(".[]").should eq Rouge::Symbol[:".[]"]
|
67
|
-
@ns.read("=").should eq Rouge::Symbol[:"="]
|
68
|
-
@ns.read("%").should eq Rouge::Symbol[:"%"]
|
69
|
-
@ns.read(">").should eq Rouge::Symbol[:">"]
|
70
|
-
@ns.read("<").should eq Rouge::Symbol[:"<"]
|
71
|
-
@ns.read("%50").should eq Rouge::Symbol[:"%50"]
|
72
|
-
@ns.read("xyz#").should eq Rouge::Symbol[:"xyz#"]
|
51
|
+
describe "symbols" do
|
52
|
+
it { @ns.read("loki").should eq Rouge::Symbol[:loki] }
|
53
|
+
it { @ns.read("wah?").should eq Rouge::Symbol[:wah?] }
|
54
|
+
it { @ns.read("!ruby!").should eq Rouge::Symbol[:"!ruby!"] }
|
55
|
+
it { @ns.read("nil").should eq Rouge::Symbol[:nil] }
|
56
|
+
it { @ns.read("nil").should eq nil }
|
57
|
+
it { @ns.read("true").should eq Rouge::Symbol[:true] }
|
58
|
+
it { @ns.read("true").should eq true }
|
59
|
+
it { @ns.read("false").should eq Rouge::Symbol[:false] }
|
60
|
+
it { @ns.read("false").should eq false }
|
61
|
+
it { @ns.read("&").should eq Rouge::Symbol[:&] }
|
62
|
+
it { @ns.read("*").should eq Rouge::Symbol[:*] }
|
63
|
+
it { @ns.read("-").should eq Rouge::Symbol[:-] }
|
64
|
+
it { @ns.read("+").should eq Rouge::Symbol[:+] }
|
65
|
+
it { @ns.read("/").should eq Rouge::Symbol[:/] }
|
66
|
+
it { @ns.read("|").should eq Rouge::Symbol[:|] }
|
67
|
+
it { @ns.read("$").should eq Rouge::Symbol[:"$"] }
|
68
|
+
it { @ns.read(".").should eq Rouge::Symbol[:"."] }
|
69
|
+
it { @ns.read(".[]").should eq Rouge::Symbol[:".[]"] }
|
70
|
+
it { @ns.read("=").should eq Rouge::Symbol[:"="] }
|
71
|
+
it { @ns.read("%").should eq Rouge::Symbol[:"%"] }
|
72
|
+
it { @ns.read(">").should eq Rouge::Symbol[:">"] }
|
73
|
+
it { @ns.read("<").should eq Rouge::Symbol[:"<"] }
|
74
|
+
it { @ns.read("%50").should eq Rouge::Symbol[:"%50"] }
|
75
|
+
it { @ns.read("xyz#").should eq Rouge::Symbol[:"xyz#"] }
|
76
|
+
it { @ns.read("-@").should eq Rouge::Symbol[:-@] }
|
77
|
+
it { @ns.read(".-@").should eq Rouge::Symbol[:".-@"] }
|
78
|
+
it { @ns.read("+@").should eq Rouge::Symbol[:+@] }
|
79
|
+
it { @ns.read(".+@").should eq Rouge::Symbol[:".+@"] }
|
73
80
|
end
|
74
81
|
|
75
82
|
describe "keywords" do
|
76
|
-
|
77
|
-
@ns.read(":loki").should eq :loki
|
78
|
-
@ns.read(":/").should eq :/
|
79
|
-
@ns.read(":wah?").should eq :wah?
|
80
|
-
@ns.read(":nil").should eq :nil
|
81
|
-
@ns.read(":true").should eq :true
|
82
|
-
@ns.read(":false").should eq :false
|
83
|
+
context "plain keywords" do
|
84
|
+
it { @ns.read(":loki").should eq :loki }
|
85
|
+
it { @ns.read(":/").should eq :/ }
|
86
|
+
it { @ns.read(":wah?").should eq :wah? }
|
87
|
+
it { @ns.read(":nil").should eq :nil }
|
88
|
+
it { @ns.read(":true").should eq :true }
|
89
|
+
it { @ns.read(":false").should eq :false }
|
83
90
|
end
|
84
91
|
|
85
|
-
|
86
|
-
@ns.read(":\"!ruby!\"").should eq :"!ruby!"
|
92
|
+
context "string-symbols" do
|
93
|
+
it { @ns.read(":\"!ruby!\"").should eq :"!ruby!" }
|
87
94
|
end
|
88
95
|
end
|
89
96
|
|
90
97
|
describe "strings" do
|
91
|
-
|
92
|
-
@ns.read("\"akashi yo\"").should eq "akashi yo"
|
93
|
-
@ns.read("\"akashi \n woah!\"").should eq "akashi \n woah!"
|
98
|
+
context "plain strings" do
|
99
|
+
it { @ns.read("\"akashi yo\"").should eq "akashi yo" }
|
100
|
+
it { @ns.read("\"akashi \n woah!\"").should eq "akashi \n woah!" }
|
94
101
|
end
|
95
102
|
|
96
|
-
|
97
|
-
@ns.read("\"here \\\" goes\"").should eq "here \" goes"
|
98
|
-
@ns.read("\"here \\\\ goes\"").should eq "here \\ goes"
|
99
|
-
@ns.read("\"\\a\\b\\e\\f\\n\\r\"").should eq "\a\b\e\f\n\r"
|
100
|
-
@ns.read("\"\\s\\t\\v\"").should eq "\s\t\v"
|
103
|
+
context "escape sequences" do
|
104
|
+
it { @ns.read("\"here \\\" goes\"").should eq "here \" goes" }
|
105
|
+
it { @ns.read("\"here \\\\ goes\"").should eq "here \\ goes" }
|
106
|
+
it { @ns.read("\"\\a\\b\\e\\f\\n\\r\"").should eq "\a\b\e\f\n\r" }
|
107
|
+
it { @ns.read("\"\\s\\t\\v\"").should eq "\s\t\v" }
|
101
108
|
end
|
102
109
|
|
103
|
-
|
104
|
-
@ns.read("\"bah\"").should be_frozen
|
110
|
+
context "read as frozen" do
|
111
|
+
it { @ns.read("\"bah\"").should be_frozen }
|
105
112
|
end
|
106
113
|
end
|
107
114
|
|
108
115
|
describe "lists" do
|
109
|
-
|
110
|
-
@ns.read("()").should eq Rouge::Seq::Cons[]
|
116
|
+
context "empty list" do
|
117
|
+
it { @ns.read("()").should eq Rouge::Seq::Cons[] }
|
111
118
|
end
|
112
119
|
|
113
|
-
|
114
|
-
@ns.read("(tiffany)").
|
115
|
-
|
116
|
-
|
120
|
+
context "one-element lists" do
|
121
|
+
it { @ns.read("(tiffany)").
|
122
|
+
should eq Rouge::Seq::Cons[Rouge::Symbol[:tiffany]] }
|
123
|
+
it { @ns.read("(:raaaaash)").
|
124
|
+
should eq Rouge::Seq::Cons[:raaaaash] }
|
117
125
|
end
|
118
126
|
|
119
|
-
|
120
|
-
@ns.read("(1 2 3)").should eq Rouge::Seq::Cons[1, 2, 3]
|
121
|
-
@ns.read("(true () [] \"no\")").
|
122
|
-
|
127
|
+
context "multiple-element lists" do
|
128
|
+
it { @ns.read("(1 2 3)").should eq Rouge::Seq::Cons[1, 2, 3] }
|
129
|
+
it { @ns.read("(true () [] \"no\")").
|
130
|
+
should eq Rouge::Seq::Cons[Rouge::Symbol[:true],
|
131
|
+
Rouge::Seq::Cons[],
|
132
|
+
[],
|
133
|
+
"no"] }
|
123
134
|
end
|
124
135
|
|
125
|
-
|
126
|
-
@ns.read("(((3) (())) 9 ((8) (8)))").
|
127
|
-
|
128
|
-
|
129
|
-
|
136
|
+
context "nested lists" do
|
137
|
+
it { @ns.read("(((3) (())) 9 ((8) (8)))").
|
138
|
+
should eq Rouge::Seq::Cons[Rouge::Seq::Cons[Rouge::Seq::Cons[3],
|
139
|
+
Rouge::Seq::Cons[Rouge::Seq::Cons[]]], 9,
|
140
|
+
Rouge::Seq::Cons[Rouge::Seq::Cons[8], Rouge::Seq::Cons[8]]] }
|
130
141
|
end
|
131
142
|
|
132
|
-
|
133
|
-
@ns.read("()").should be_frozen
|
134
|
-
@ns.read("(1)").should be_frozen
|
135
|
-
@ns.read("(1 2)").should be_frozen
|
143
|
+
context "read as frozen" do
|
144
|
+
it { @ns.read("()").should be_frozen }
|
145
|
+
it { @ns.read("(1)").should be_frozen }
|
146
|
+
it { @ns.read("(1 2)").should be_frozen }
|
136
147
|
end
|
137
148
|
end
|
138
149
|
|
139
150
|
describe "vectors" do
|
140
|
-
|
141
|
-
@ns.read("[]").should eq []
|
151
|
+
context "the empty vector" do
|
152
|
+
it { @ns.read("[]").should eq [] }
|
142
153
|
end
|
143
154
|
|
144
|
-
|
145
|
-
@ns.read("[tiffany]").should eq [Rouge::Symbol[:tiffany]]
|
146
|
-
@ns.read("[:raaaaash]").should eq [:raaaaash]
|
155
|
+
context "one-element vectors" do
|
156
|
+
it { @ns.read("[tiffany]").should eq [Rouge::Symbol[:tiffany]] }
|
157
|
+
it { @ns.read("[:raaaaash]").should eq [:raaaaash] }
|
147
158
|
end
|
148
159
|
|
149
|
-
|
150
|
-
@ns.read("[1 2 3]").should eq [1, 2, 3]
|
151
|
-
@ns.read("[true () [] \"no\"]").
|
152
|
-
|
160
|
+
context "multiple-element vectors" do
|
161
|
+
it { @ns.read("[1 2 3]").should eq [1, 2, 3] }
|
162
|
+
it { @ns.read("[true () [] \"no\"]").
|
163
|
+
should eq [Rouge::Symbol[:true], Rouge::Seq::Cons[], [], "no"] }
|
153
164
|
end
|
154
165
|
|
155
|
-
|
156
|
-
@ns.read("[[[3] [[]]] 9 [[8] [8]]]").
|
157
|
-
|
166
|
+
context "nested vectors" do
|
167
|
+
it { @ns.read("[[[3] [[]]] 9 [[8] [8]]]").
|
168
|
+
should eq [[[3], [[]]], 9, [[8], [8]]] }
|
158
169
|
end
|
159
170
|
|
160
|
-
|
161
|
-
@ns.read("[]").should be_frozen
|
162
|
-
@ns.read("[1]").should be_frozen
|
163
|
-
@ns.read("[1 2]").should be_frozen
|
171
|
+
context "read as frozen" do
|
172
|
+
it { @ns.read("[]").should be_frozen }
|
173
|
+
it { @ns.read("[1]").should be_frozen }
|
174
|
+
it { @ns.read("[1 2]").should be_frozen }
|
164
175
|
end
|
165
176
|
end
|
166
177
|
|
167
178
|
describe "quotations" do
|
168
|
-
it
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
Rouge::Seq::Cons[Rouge::Seq::Cons[Rouge::Symbol[:quote],
|
178
|
-
Rouge::Symbol[:x]]]]]
|
179
|
-
end
|
179
|
+
it { @ns.read("'x").
|
180
|
+
should eq Rouge::Seq::Cons[Rouge::Symbol[:quote],
|
181
|
+
Rouge::Symbol[:x]] }
|
182
|
+
|
183
|
+
it { @ns.read("''('x)").
|
184
|
+
should eq Rouge::Seq::Cons[Rouge::Symbol[:quote],
|
185
|
+
Rouge::Seq::Cons[Rouge::Symbol[:quote],
|
186
|
+
Rouge::Seq::Cons[Rouge::Seq::Cons[Rouge::Symbol[:quote],
|
187
|
+
Rouge::Symbol[:x]]]]] }
|
180
188
|
end
|
181
189
|
|
182
190
|
describe "vars" do
|
183
|
-
it
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
Rouge::Seq::Cons[Rouge::Symbol[:var],
|
192
|
-
Rouge::Seq::Cons[Rouge::Seq::Cons[Rouge::Symbol[:var],
|
193
|
-
Rouge::Symbol[:x]]]]]
|
194
|
-
end
|
191
|
+
it { @ns.read("#'x").
|
192
|
+
should eq Rouge::Seq::Cons[Rouge::Symbol[:var], Rouge::Symbol[:x]] }
|
193
|
+
|
194
|
+
it { @ns.read("#'#'(#'x)").
|
195
|
+
should eq Rouge::Seq::Cons[Rouge::Symbol[:var],
|
196
|
+
Rouge::Seq::Cons[Rouge::Symbol[:var],
|
197
|
+
Rouge::Seq::Cons[Rouge::Seq::Cons[Rouge::Symbol[:var],
|
198
|
+
Rouge::Symbol[:x]]]]] }
|
195
199
|
end
|
196
200
|
|
197
201
|
describe "maps" do
|
198
|
-
|
199
|
-
@ns.read("{}").should eq({})
|
202
|
+
context "the empty map" do
|
203
|
+
it { @ns.read("{}").should eq({}) }
|
200
204
|
end
|
201
205
|
|
202
|
-
|
203
|
-
@ns.read("{a 1}").to_s.should eq({Rouge::Symbol[:a] => 1}.to_s)
|
204
|
-
@ns.read("{\"quux\" [lambast]}").
|
205
|
-
|
206
|
+
context "one-element maps" do
|
207
|
+
it { @ns.read("{a 1}").to_s.should eq({Rouge::Symbol[:a] => 1}.to_s) }
|
208
|
+
it { @ns.read("{\"quux\" [lambast]}").
|
209
|
+
should eq({"quux" => [Rouge::Symbol[:lambast]]}) }
|
206
210
|
end
|
207
211
|
|
208
|
-
|
209
|
-
@ns.read("{:a 1 :b 2}").should eq({:a => 1, :b => 2})
|
210
|
-
@ns.read("{:f :f, :y :y\n:z :z}").
|
211
|
-
|
212
|
+
context "multiple-element maps" do
|
213
|
+
it { @ns.read("{:a 1 :b 2}").should eq({:a => 1, :b => 2}) }
|
214
|
+
it { @ns.read("{:f :f, :y :y\n:z :z}").
|
215
|
+
should eq({:f => :f, :y => :y, :z => :z}) }
|
212
216
|
end
|
213
217
|
|
214
|
-
|
215
|
-
@ns.read("{:a {:z 9} :b {:q q}}").should eq(
|
216
|
-
|
217
|
-
@ns.read("{{9 7} 5}").should eq({{9 => 7} => 5})
|
218
|
+
context "nested maps" do
|
219
|
+
it { @ns.read("{:a {:z 9} :b {:q q}}").should eq(
|
220
|
+
{:a => {:z => 9}, :b => {:q => Rouge::Symbol[:q]}}) }
|
221
|
+
it { @ns.read("{{9 7} 5}").should eq({{9 => 7} => 5}) }
|
218
222
|
end
|
219
223
|
|
220
|
-
|
221
|
-
@ns.read("{}").should be_frozen
|
222
|
-
@ns.read("{:a 1}").should be_frozen
|
224
|
+
context "read as frozen" do
|
225
|
+
it { @ns.read("{}").should be_frozen }
|
226
|
+
it { @ns.read("{:a 1}").should be_frozen }
|
223
227
|
end
|
224
228
|
end
|
225
229
|
|
226
230
|
describe "whitespace behaviour" do
|
227
|
-
it
|
228
|
-
|
229
|
-
@ns.read(":hello \n\n\t\t ").should eq :hello
|
230
|
-
}.should_not raise_exception
|
231
|
-
end
|
231
|
+
it { expect { @ns.read(":hello \n\n\t\t ").should eq :hello
|
232
|
+
}.to_not raise_exception }
|
232
233
|
|
233
|
-
it
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
end
|
234
|
+
it { expect { @ns.read("[1 ]").should eq [1]
|
235
|
+
}.to_not raise_exception }
|
236
|
+
|
237
|
+
it { expect { @ns.read(" [ 2 ] ").should eq [2]
|
238
|
+
}.to_not raise_exception }
|
239
239
|
end
|
240
240
|
|
241
241
|
describe "empty reads" do
|
242
|
-
it
|
243
|
-
|
244
|
-
@ns.read("")
|
245
|
-
}.should raise_exception(Rouge::Reader::EndOfDataError)
|
242
|
+
it { expect { @ns.read("")
|
243
|
+
}.to raise_exception(Rouge::Reader::EndOfDataError) }
|
246
244
|
|
247
|
-
|
248
|
-
|
249
|
-
}.should raise_exception(Rouge::Reader::EndOfDataError)
|
250
|
-
end
|
245
|
+
it { expect { @ns.read(" \n ")
|
246
|
+
}.to raise_exception(Rouge::Reader::EndOfDataError) }
|
251
247
|
end
|
252
248
|
|
253
249
|
describe "comments" do
|
254
|
-
it "should
|
255
|
-
|
256
|
-
@ns.read("[42 ;what!\n15]").should eq [42, 15]
|
250
|
+
it { @ns.read("42 ;what!").should eq 42 }
|
251
|
+
it { @ns.read("[42 ;what!\n15]").should eq [42, 15] }
|
257
252
|
|
258
|
-
|
259
|
-
|
260
|
-
}.should raise_exception(Rouge::Reader::EndOfDataError)
|
253
|
+
it { expect { @ns.read(";what!")
|
254
|
+
}.to raise_exception(Rouge::Reader::EndOfDataError) }
|
261
255
|
|
262
|
-
|
263
|
-
end
|
256
|
+
it { @ns.read(";what!\nhmm").should eq Rouge::Symbol[:hmm] }
|
264
257
|
end
|
265
258
|
|
266
259
|
describe "syntax-quoting" do
|
267
260
|
describe "non-cons lists" do
|
268
|
-
|
269
|
-
@ns.read('`3').should eq @ns.read("'3")
|
270
|
-
@ns.read('`"my my my"').should eq @ns.read(%{'"my my my"})
|
261
|
+
context "quoting non-cons lists" do
|
262
|
+
it { @ns.read('`3').should eq @ns.read("'3") }
|
263
|
+
it { @ns.read('`"my my my"').should eq @ns.read(%{'"my my my"}) }
|
271
264
|
end
|
272
265
|
|
273
|
-
|
274
|
-
@ns.read('`~3').should eq @ns.read("3")
|
275
|
-
@ns.read('``~3').should eq @ns.read("'3")
|
276
|
-
@ns.read('``~~3').should eq @ns.read("3")
|
266
|
+
context "dequoting within non-cons lists" do
|
267
|
+
it { @ns.read('`~3').should eq @ns.read("3") }
|
268
|
+
it { @ns.read('``~3').should eq @ns.read("'3") }
|
269
|
+
it { @ns.read('``~~3').should eq @ns.read("3") }
|
277
270
|
end
|
278
271
|
|
279
|
-
|
280
|
-
@ns.read('`a').should eq @ns.read("'user.spec/a")
|
272
|
+
context "qualifying symbols" do
|
273
|
+
it { @ns.read('`a').should eq @ns.read("'user.spec/a") }
|
281
274
|
end
|
282
275
|
|
283
|
-
|
284
|
-
@ns.read('`.a').should eq @ns.read("'.a")
|
285
|
-
@ns.read('`&').should eq @ns.read("'&")
|
286
|
-
@ns.read('`|').should eq @ns.read("'|")
|
276
|
+
context "not qualifying special symbols" do
|
277
|
+
it { @ns.read('`.a').should eq @ns.read("'.a") }
|
278
|
+
it { @ns.read('`&').should eq @ns.read("'&") }
|
279
|
+
it { @ns.read('`|').should eq @ns.read("'|") }
|
287
280
|
end
|
288
281
|
end
|
289
282
|
|
290
283
|
describe "cons-lists" do
|
291
|
-
|
292
|
-
@ns.read('`(1 2)').should eq @ns.read("(list '1 '2)")
|
293
|
-
@ns.read('`(a b)').
|
294
|
-
|
284
|
+
context "quoting cons lists" do
|
285
|
+
it { @ns.read('`(1 2)').should eq @ns.read("(list '1 '2)") }
|
286
|
+
it { @ns.read('`(a b)').
|
287
|
+
should eq @ns.read("(list 'user.spec/a 'user.spec/b)") }
|
295
288
|
end
|
296
289
|
|
297
|
-
|
298
|
-
@ns.read('`(a ~b)').should eq @ns.read("(list 'user.spec/a b)")
|
299
|
-
|
300
|
-
|
301
|
-
|
290
|
+
context "dequoting within cons lists" do
|
291
|
+
it { @ns.read('`(a ~b)').should eq @ns.read("(list 'user.spec/a b)") }
|
292
|
+
|
293
|
+
it { @ns.read('`(a ~(b `(c ~d)))').
|
294
|
+
should eq @ns.read("(list 'user.spec/a (b " \
|
295
|
+
"(list 'user.spec/c d)))") }
|
296
|
+
|
297
|
+
# Should the below include 'rouge.builtin/quote as it does?
|
298
|
+
# Or should that be 'quote? Clojure reads it so.
|
299
|
+
it { @ns.read('`(a `(b ~c))').
|
302
300
|
should eq @ns.read("(list 'user.spec/a (list 'user.spec/list " \
|
303
|
-
"(list 'quote 'user.spec/b)
|
304
|
-
|
301
|
+
"(list 'rouge.builtin/quote 'user.spec/b) " \
|
302
|
+
"'user.spec/c))") }
|
303
|
+
|
304
|
+
it { @ns.read('`~`(x)').should eq @ns.read("(list 'user.spec/x)") }
|
305
305
|
end
|
306
306
|
|
307
|
-
|
308
|
-
@ns.read('`{a ~b}').to_s.
|
307
|
+
context "dequoting within maps" do
|
308
|
+
it { @ns.read('`{a ~b}').to_s.
|
309
|
+
should eq @ns.read("{'user.spec/a b}").to_s }
|
309
310
|
end
|
310
311
|
|
311
|
-
|
312
|
-
@ns.read('`(a ~@b c)').
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
312
|
+
context "splicing within seqs and vectors" do
|
313
|
+
it { @ns.read('`(a ~@b c)').
|
314
|
+
should eq @ns.read("(seq (concat (list 'user.spec/a) b " \
|
315
|
+
"(list 'user.spec/c)))") }
|
316
|
+
|
317
|
+
it { @ns.read('`(~@(a b) ~c)').
|
318
|
+
should eq @ns.read("(seq (concat (a b) (list c)))") }
|
319
|
+
|
320
|
+
it do
|
321
|
+
@ns.read('`[a ~@b c]').should eq @ns.read(<<-ROUGE)
|
318
322
|
(apply vector (concat (list 'user.spec/a) b (list 'user.spec/c)))
|
319
|
-
|
320
|
-
|
321
|
-
|
323
|
+
ROUGE
|
324
|
+
end
|
325
|
+
|
326
|
+
it { @ns.read('`[~@(a b) ~c]').
|
327
|
+
should eq @ns.read("(apply vector (concat (a b) (list c)))") }
|
322
328
|
end
|
323
329
|
end
|
324
330
|
|
325
331
|
describe "gensyms" do
|
326
|
-
|
327
|
-
a1
|
328
|
-
a2
|
329
|
-
a1.to_s.should_not eq a2.to_s
|
332
|
+
context "reading as unique in each invocation" do
|
333
|
+
let(:a1) { @ns.read('`a#') }
|
334
|
+
let(:a2) { @ns.read('`a#') }
|
335
|
+
it { a1.to_s.should_not eq a2.to_s }
|
330
336
|
end
|
331
337
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
338
|
+
context "reading identically within each invocation" do
|
339
|
+
let(:r) do
|
340
|
+
@ns.read('`(a# a# `(a# a#))').
|
341
|
+
map {|e| e.respond_to?(:to_a) ? e.to_a : e}.to_a.flatten.
|
342
|
+
flat_map {|e| e.respond_to?(:to_a) ? e.to_a : e}.
|
343
|
+
flat_map {|e| e.respond_to?(:to_a) ? e.to_a : e}.
|
344
|
+
find_all {|e|
|
345
|
+
e.is_a?(Rouge::Symbol) and e.name.to_s =~ /^a/
|
346
|
+
}
|
347
|
+
end
|
348
|
+
|
349
|
+
it { r.should have(4).items }
|
350
|
+
it { r[0].should eq r[1] }
|
351
|
+
it { r[2].should eq r[3] }
|
352
|
+
it { r[0].should_not eq r[2] }
|
345
353
|
end
|
346
354
|
end
|
347
355
|
end
|
348
356
|
|
349
357
|
describe "anonymous functions" do
|
350
|
-
it
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
@ns.read('#(%2 %)').should eq @ns.read('(fn [%1 %2] (%2 %1))')
|
357
|
-
end
|
358
|
+
it { @ns.read('#(1)').should eq @ns.read('(fn [] (1))') }
|
359
|
+
it { @ns.read('#(do 1)').should eq @ns.read('(fn [] (do 1))') }
|
360
|
+
it { @ns.read('#(%)').should eq @ns.read('(fn [%1] (%1))') }
|
361
|
+
it { @ns.read('#(%2)').should eq @ns.read('(fn [%1 %2] (%2))') }
|
362
|
+
it { @ns.read('#(%5)').should eq @ns.read('(fn [%1 %2 %3 %4 %5] (%5))') }
|
363
|
+
it { @ns.read('#(%2 %)').should eq @ns.read('(fn [%1 %2] (%2 %1))') }
|
358
364
|
end
|
359
365
|
|
360
366
|
describe "metadata" do
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
367
|
+
context "reading" do
|
368
|
+
subject { @ns.read('^{:x 1} y') }
|
369
|
+
it { should eq Rouge::Symbol[:y] }
|
370
|
+
its(:meta) { should eq({:x => 1}) }
|
365
371
|
end
|
366
372
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
373
|
+
context "stacking" do
|
374
|
+
subject { @ns.read('^{:y 2} ^{:y 3 :z 2} y') }
|
375
|
+
it { should eq Rouge::Symbol[:y] }
|
376
|
+
its(:meta) { should include({:y => 2, :z => 2}) }
|
371
377
|
end
|
372
378
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
379
|
+
context "assigning tags" do
|
380
|
+
subject { @ns.read('^"xyz" y') }
|
381
|
+
it { should eq Rouge::Symbol[:y] }
|
382
|
+
its(:meta) { should include({:tag => "xyz"}) }
|
377
383
|
end
|
378
384
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
385
|
+
context "assigning symbol markers" do
|
386
|
+
subject { @ns.read('^:blargh y') }
|
387
|
+
it { should eq Rouge::Symbol[:y] }
|
388
|
+
its(:meta) { should include({:blargh => true}) }
|
383
389
|
end
|
384
390
|
end
|
385
391
|
|
386
392
|
describe "deref" do
|
387
|
-
it
|
388
|
-
@ns.read('@(boo)').should eq @ns.read('(rouge.core/deref (boo))')
|
389
|
-
end
|
393
|
+
it { @ns.read('@(boo)').should eq @ns.read('(rouge.core/deref (boo))') }
|
390
394
|
end
|
391
395
|
|
392
396
|
describe "multiple reading" do
|
393
|
-
|
394
|
-
|
397
|
+
let(:r) { Rouge::Reader.new(@ns, "a b c") }
|
398
|
+
|
399
|
+
it do
|
395
400
|
r.lex.should eq Rouge::Symbol[:a]
|
396
401
|
r.lex.should eq Rouge::Symbol[:b]
|
397
402
|
r.lex.should eq Rouge::Symbol[:c]
|
398
403
|
|
399
|
-
|
400
|
-
|
401
|
-
}.should raise_exception(Rouge::Reader::EndOfDataError)
|
404
|
+
expect { r.lex
|
405
|
+
}.to raise_exception(Rouge::Reader::EndOfDataError)
|
402
406
|
end
|
403
407
|
end
|
404
408
|
|
405
409
|
describe "the ns property" do
|
406
|
-
it "should
|
407
|
-
Rouge::Reader.new(@ns, "").ns.should be @ns
|
408
|
-
end
|
410
|
+
it { Rouge::Reader.new(@ns, "").ns.should be @ns }
|
409
411
|
end
|
410
412
|
|
411
413
|
describe "the comment dispatch" do
|
412
|
-
it
|
413
|
-
@ns.read('#_(xyz abc) :f').should eq :f
|
414
|
-
end
|
414
|
+
it { @ns.read('#_(xyz abc) :f').should eq :f }
|
415
415
|
end
|
416
416
|
|
417
417
|
describe "regexp" do
|