rouge-lang 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|