clj 0.0.6.1 → 0.0.7

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/ext/clj/extconf.rb CHANGED
@@ -5,7 +5,7 @@ unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3')
5
5
  end
6
6
 
7
7
  if CONFIG['CC'] =~ /gcc/
8
- $CFLAGS << ' -Wall' << ' -std=c99'
8
+ $CFLAGS << ' -Wall'
9
9
 
10
10
  if $DEBUG && !$CFLAGS.gsub!(/ -O[\dsz]?/, ' -O0 -ggdb')
11
11
  $CFLAGS << ' -O0 -ggdb'
data/ext/clj/parser.c CHANGED
@@ -32,7 +32,8 @@ typedef enum {
32
32
  NODE_VECTOR,
33
33
  NODE_INSTANT,
34
34
  NODE_SET,
35
- NODE_REGEXP
35
+ NODE_REGEXP,
36
+ NODE_SYMBOL
36
37
  } NodeType;
37
38
 
38
39
  #define CALL(what) (what(self, string, position))
@@ -50,14 +51,17 @@ typedef enum {
50
51
  #define IS_EQUAL_UP_TO(str, n) (strncmp(CURRENT_PTR, str, (n)) == 0)
51
52
  #define IS_EQUAL(str) IS_EQUAL_UP_TO(str, strlen(str))
52
53
  #define IS_IGNORED(ch) (isspace(ch) || ch == ',')
53
- #define IS_BOTH(ch) (ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == '\n' || ch == '\r' || ch == '\t')
54
- #define IS_KEYWORD(ch) (ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == '\'' || ch == '^' || ch == '@' || ch == '`' || ch == '~' || ch == '\\' || ch == ';' || ch == '\n' || ch == '\r' || ch == '\t')
54
+ #define IS_SYMBOL(ch) (isdigit(ch) || isalpha(ch) || ch == '+' || ch == '!' || ch == '-' || ch == '_' || ch == '?' || ch == '.' || ch == ':' || ch == '/')
55
+ #define IS_BOTH_SEPARATOR(ch) (ch == '\0' || ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == '\n' || ch == '\r' || ch == '\t')
56
+ #define IS_KEYWORD_SEPARATOR(ch) (ch == '\0' || ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == '\'' || ch == '^' || ch == '@' || ch == '`' || ch == '~' || ch == '\\' || ch == ';' || ch == '\n' || ch == '\r' || ch == '\t')
55
57
 
56
- static VALUE read_next (VALUE self, char* string, size_t* position);
58
+ static VALUE read_next (STATE);
57
59
 
58
60
  static inline bool is_not_eof_up_to (char* string, size_t* position, size_t n)
59
61
  {
60
- for (size_t i = 0; i < n; i++) {
62
+ size_t i;
63
+
64
+ for (i = 0; i < n; i++) {
61
65
  if (IS_EOF_AFTER(i)) {
62
66
  return false;
63
67
  }
@@ -103,7 +107,7 @@ static NodeType next_type (STATE)
103
107
  }
104
108
  }
105
109
 
106
- rb_raise(rb_eSyntaxError, "unknown type");
110
+ return NODE_SYMBOL;
107
111
  }
108
112
 
109
113
  static VALUE read_metadata (STATE)
@@ -111,6 +115,7 @@ static VALUE read_metadata (STATE)
111
115
  VALUE result;
112
116
  VALUE* metadatas = NULL;
113
117
  size_t length = 0;
118
+ size_t i;
114
119
 
115
120
  while (CURRENT == '^') {
116
121
  metadatas = realloc(metadatas, ++length * sizeof(VALUE));
@@ -129,7 +134,7 @@ static VALUE read_metadata (STATE)
129
134
  }
130
135
 
131
136
  // FIXME: this could lead to a memleak if #metadata= raises
132
- for (size_t i = 0; i < length; i++) {
137
+ for (i = 0; i < length; i++) {
133
138
  rb_funcall(result, rb_intern("metadata="), 1, metadatas[i]);
134
139
  }
135
140
 
@@ -138,14 +143,24 @@ static VALUE read_metadata (STATE)
138
143
  return result;
139
144
  }
140
145
 
141
- static VALUE read_nil (STATE)
146
+ static VALUE read_symbol (STATE)
142
147
  {
143
- if (!IS_NOT_EOF_UP_TO(3)) {
144
- rb_raise(rb_eSyntaxError, "unexpected EOF");
148
+ size_t length = 0;
149
+
150
+ while (IS_SYMBOL(AFTER(length))) {
151
+ length++;
145
152
  }
146
153
 
147
- if (!IS_EQUAL_UP_TO("nil", 3)) {
148
- rb_raise(rb_eSyntaxError, "expected nil, got n%c%c", AFTER(1), AFTER(2));
154
+ SEEK(length);
155
+
156
+ return rb_funcall(rb_funcall(rb_str_new(BEFORE_PTR(length), length), rb_intern("to_sym"), 0),
157
+ rb_intern("symbol!"), 0);
158
+ }
159
+
160
+ static VALUE read_nil (STATE)
161
+ {
162
+ if (!IS_NOT_EOF_UP_TO(3) || !IS_EQUAL_UP_TO("nil", 3) || !IS_BOTH_SEPARATOR(AFTER(3))) {
163
+ return CALL(read_symbol);
149
164
  }
150
165
 
151
166
  SEEK(3);
@@ -156,25 +171,17 @@ static VALUE read_nil (STATE)
156
171
  static VALUE read_boolean (STATE)
157
172
  {
158
173
  if (CURRENT == 't') {
159
- if (!IS_NOT_EOF_UP_TO(4)) {
160
- rb_raise(rb_eSyntaxError, "unexpected EOF");
174
+ if (!IS_NOT_EOF_UP_TO(4) || !IS_EQUAL_UP_TO("true", 4) || !IS_BOTH_SEPARATOR(AFTER(4))) {
175
+ return CALL(read_symbol);
161
176
  }
162
-
163
- if (!IS_EQUAL_UP_TO("true", 4)) {
164
- rb_raise(rb_eSyntaxError, "expected true, got t%c%c%c", AFTER(1), AFTER(2), AFTER(3));
165
- }
166
-
177
+
167
178
  SEEK(4);
168
179
 
169
180
  return Qtrue;
170
181
  }
171
182
  else {
172
- if (!IS_NOT_EOF_UP_TO(5)) {
173
- rb_raise(rb_eSyntaxError, "unexpected EOF");
174
- }
175
-
176
- if (!IS_EQUAL_UP_TO("false", 5)) {
177
- rb_raise(rb_eSyntaxError, "expected false, got f%c%c%c%c", AFTER(1), AFTER(2), AFTER(3), AFTER(4));
183
+ if (!IS_NOT_EOF_UP_TO(5) || !IS_EQUAL_UP_TO("false", 5) || !IS_BOTH_SEPARATOR(AFTER(5))) {
184
+ return CALL(read_symbol);
178
185
  }
179
186
 
180
187
  SEEK(5);
@@ -190,7 +197,7 @@ static VALUE read_number (STATE)
190
197
  char* cPiece;
191
198
  char* tmp;
192
199
 
193
- while (!IS_EOF_AFTER(length) && !IS_BOTH(AFTER(length))) {
200
+ while (!IS_EOF_AFTER(length) && !IS_BOTH_SEPARATOR(AFTER(length))) {
194
201
  length++;
195
202
  }
196
203
 
@@ -227,50 +234,49 @@ static VALUE read_char (STATE)
227
234
  {
228
235
  SEEK(1);
229
236
 
230
- if (IS_EOF_AFTER(1) || IS_BOTH(AFTER(1))) {
237
+ if (IS_EOF_AFTER(1) || IS_BOTH_SEPARATOR(AFTER(1))) {
231
238
  SEEK(1); return rb_str_new(BEFORE_PTR(1), 1);
232
239
  }
233
- else if (IS_NOT_EOF_UP_TO(7) && IS_EQUAL_UP_TO("newline", 7) && (IS_EOF_AFTER(7) || IS_BOTH(AFTER(7)))) {
240
+ else if (IS_NOT_EOF_UP_TO(7) && IS_EQUAL_UP_TO("newline", 7) && IS_BOTH_SEPARATOR(AFTER(7))) {
234
241
  SEEK(7); return rb_str_new2("\n");
235
242
  }
236
- else if (IS_NOT_EOF_UP_TO(5) && IS_EQUAL_UP_TO("space", 5) && (IS_EOF_AFTER(5) || IS_BOTH(AFTER(5)))) {
243
+ else if (IS_NOT_EOF_UP_TO(5) && IS_EQUAL_UP_TO("space", 5) && IS_BOTH_SEPARATOR(AFTER(5))) {
237
244
  SEEK(5); return rb_str_new2(" ");
238
245
  }
239
- else if (IS_NOT_EOF_UP_TO(3) && IS_EQUAL_UP_TO("tab", 3) && (IS_EOF_AFTER(3) || IS_BOTH(AFTER(3)))) {
246
+ else if (IS_NOT_EOF_UP_TO(3) && IS_EQUAL_UP_TO("tab", 3) && IS_BOTH_SEPARATOR(AFTER(3))) {
240
247
  SEEK(3); return rb_str_new2("\t");
241
248
  }
242
- else if (IS_NOT_EOF_UP_TO(9) && IS_EQUAL_UP_TO("backspace", 9) && (IS_EOF_AFTER(9) || IS_BOTH(AFTER(9)))) {
249
+ else if (IS_NOT_EOF_UP_TO(9) && IS_EQUAL_UP_TO("backspace", 9) && IS_BOTH_SEPARATOR(AFTER(9))) {
243
250
  SEEK(9); return rb_str_new2("\b");
244
251
  }
245
- else if (IS_NOT_EOF_UP_TO(8) && IS_EQUAL_UP_TO("formfeed", 8) && (IS_EOF_AFTER(8) || IS_BOTH(AFTER(8)))) {
252
+ else if (IS_NOT_EOF_UP_TO(8) && IS_EQUAL_UP_TO("formfeed", 8) && IS_BOTH_SEPARATOR(AFTER(8))) {
246
253
  SEEK(8); return rb_str_new2("\f");
247
254
  }
248
- else if (IS_NOT_EOF_UP_TO(6) && IS_EQUAL_UP_TO("return", 6) && (IS_EOF_AFTER(6) || IS_BOTH(AFTER(6)))) {
255
+ else if (IS_NOT_EOF_UP_TO(6) && IS_EQUAL_UP_TO("return", 6) && IS_BOTH_SEPARATOR(AFTER(6))) {
249
256
  SEEK(6); return rb_str_new2("\r");
250
257
  }
251
- else if (CURRENT == 'u' && IS_NOT_EOF_UP_TO(5) && !NIL_P(rb_funcall(rb_str_new(AFTER_PTR(1), 4), rb_intern("=~"), 1, UNICODE_REGEX)) && (IS_EOF_AFTER(5) || IS_BOTH(AFTER(5)))) {
258
+ else if (CURRENT == 'u' && IS_NOT_EOF_UP_TO(5) && !NIL_P(rb_funcall(rb_str_new(AFTER_PTR(1), 4), rb_intern("=~"), 1, UNICODE_REGEX)) && IS_BOTH_SEPARATOR(AFTER(5))) {
252
259
  SEEK(5); return rb_funcall(rb_ary_new3(1, rb_funcall(rb_str_new(BEFORE_PTR(4), 4), rb_intern("to_i"), 1, INT2FIX(16))),
253
260
  rb_intern("pack"), 1, rb_str_new2("U"));
254
261
  }
255
262
  else if (CURRENT == 'o') {
256
263
  size_t length = 1;
264
+ size_t i;
257
265
 
258
- for (size_t i = 1; i < 5; i++) {
259
- if (IS_EOF_AFTER(i) || IS_BOTH(AFTER(i))) {
266
+ for (i = 1; i < 5; i++) {
267
+ if (IS_BOTH_SEPARATOR(AFTER(i))) {
260
268
  break;
261
269
  }
262
270
 
263
271
  length++;
264
272
  }
265
273
 
266
- if (length > 1 && !NIL_P(rb_funcall(rb_str_new(AFTER_PTR(1), length - 1), rb_intern("=~"), 1, OCTAL_REGEX)) && (IS_EOF_AFTER(length) || IS_BOTH(AFTER(length)))) {
274
+ if (length > 1 && !NIL_P(rb_funcall(rb_str_new(AFTER_PTR(1), length - 1), rb_intern("=~"), 1, OCTAL_REGEX)) && IS_BOTH_SEPARATOR(AFTER(length))) {
267
275
  SEEK(length); return rb_funcall(rb_funcall(rb_str_new(BEFORE_PTR(length - 1), length - 1), rb_intern("to_i"), 1, INT2FIX(8)),
268
276
  rb_intern("chr"), 0);
269
277
  }
270
278
  }
271
279
 
272
- // TODO: add unicode and octal chars support
273
-
274
280
  rb_raise(rb_eSyntaxError, "unknown character type");
275
281
  }
276
282
 
@@ -280,13 +286,14 @@ static VALUE read_keyword (STATE)
280
286
 
281
287
  SEEK(1);
282
288
 
283
- while (!IS_EOF_AFTER(length) && !IS_KEYWORD(AFTER(length))) {
289
+ while (!IS_KEYWORD_SEPARATOR(AFTER(length))) {
284
290
  length++;
285
291
  }
286
292
 
287
293
  SEEK(length);
288
294
 
289
- return rb_funcall(rb_str_new(BEFORE_PTR(length), length), rb_intern("to_sym"), 0);
295
+ return rb_funcall(rb_funcall(rb_str_new(BEFORE_PTR(length), length), rb_intern("to_sym"), 0),
296
+ rb_intern("keyword!"), 0);
290
297
  }
291
298
 
292
299
  static VALUE read_string (STATE)
@@ -309,8 +316,6 @@ static VALUE read_string (STATE)
309
316
 
310
317
  SEEK(length + 1);
311
318
 
312
- // TODO: make the escapes work properly
313
-
314
319
  return rb_funcall(cClojure, rb_intern("unescape"), 1, rb_str_new(BEFORE_PTR(length + 1), length));
315
320
  }
316
321
 
@@ -457,6 +462,7 @@ static VALUE read_next (STATE)
457
462
  case NODE_INSTANT: return CALL(read_instant);
458
463
  case NODE_SET: return CALL(read_set);
459
464
  case NODE_REGEXP: return CALL(read_regexp);
465
+ case NODE_SYMBOL: return CALL(read_symbol);
460
466
  }
461
467
  }
462
468
 
data/lib/clj/parser.rb CHANGED
@@ -13,7 +13,8 @@ require 'stringio'
13
13
  module Clojure
14
14
 
15
15
  class Parser
16
- NUMBERS = '0' .. '9'
16
+ NUMBERS = '0' .. '9'
17
+ SYMBOL = ('0' .. '9').to_a | ('a' .. 'z').to_a | ('A' .. 'Z').to_a | %w[+ ! - _ ? . : /]
17
18
 
18
19
  UNICODE_REGEX = /[0-9|a-f|A-F]{4}/
19
20
  OCTAL_REGEX = /[0-3]?[0-7]?[0-7]/
@@ -29,7 +30,15 @@ class Parser
29
30
  end
30
31
 
31
32
  def parse
32
- read_next
33
+ result = read_next
34
+
35
+ ignore(false)
36
+
37
+ if @source.read(1)
38
+ raise SyntaxError, 'there is some unconsumed input'
39
+ end
40
+
41
+ result
33
42
  end
34
43
 
35
44
  private
@@ -51,7 +60,8 @@ private
51
60
  when '{' then :set
52
61
  when '"' then :regexp
53
62
  end
54
- end or raise SyntaxError, 'unknown type'
63
+ else :symbol
64
+ end
55
65
  end
56
66
 
57
67
  def read_next
@@ -83,45 +93,39 @@ private
83
93
  end
84
94
 
85
95
  def read_nil (ch)
86
- check = @source.read(2)
96
+ check = @source.read(3)
87
97
 
88
- if check.length != 2
89
- raise SyntaxError, 'unexpected EOF'
90
- elsif check != 'il'
91
- raise SyntaxError, "expected nil, found n#{check}"
98
+ if check[0, 2] != 'il' || !both_separator?(check[2])
99
+ revert(check.length) and read_symbol(ch)
100
+ else
101
+ nil
92
102
  end
93
-
94
- nil
95
103
  end
96
104
 
97
105
  def read_boolean (ch)
98
106
  if ch == 't'
99
- check = @source.read(3)
107
+ check = @source.read(4)
100
108
 
101
- if check.length != 3
102
- raise SyntaxError, 'unexpected EOF'
103
- elsif check != 'rue'
104
- raise SyntaxError, "expected true, found t#{check}"
109
+ if check[0, 3] != 'rue' || !both_separator?(check[3])
110
+ revert(check.length) and read_symbol(ch)
111
+ else
112
+ true
105
113
  end
106
-
107
- true
108
114
  else
109
- check = @source.read(4)
115
+ check = @source.read(5)
110
116
 
111
- if check.length != 4
112
- raise SyntaxError, 'unexpected EOF'
113
- elsif check != 'alse'
114
- raise SyntaxError, "expected false, found f#{check}"
117
+ if check[0, 4] != 'alse' || !both_separator?(check[4])
118
+ revert(check.length) and read_symbol(ch)
119
+ else
120
+ false
115
121
  end
116
-
117
- false
118
122
  end
119
123
  end
120
124
 
121
125
  def read_number (ch)
122
126
  piece = ch
123
127
 
124
- while (ch = @source.read(1)) && !both?(ch)
128
+ while (ch = @source.read(1)) && !both_separator?(ch)
125
129
  piece << ch
126
130
  end
127
131
 
@@ -149,41 +153,57 @@ private
149
153
  end
150
154
 
151
155
  def read_char (ch)
152
- if (ahead = lookahead(2)) && (!ahead[1] || both?(ahead[1]))
156
+ if (ahead = lookahead(2)) && both_separator?(ahead[1])
153
157
  @source.read(1)
154
- elsif (ahead = lookahead(8)) && ahead[0, 7] == 'newline' && (!ahead[7] || both?(ahead[7]))
158
+ elsif (ahead = lookahead(8)) && ahead[0, 7] == 'newline' && both_separator?(ahead[7])
155
159
  @source.read(7) and "\n"
156
- elsif (ahead = lookahead(6)) && ahead[0, 5] == 'space' && (!ahead[5] || both?(ahead[5]))
160
+ elsif (ahead = lookahead(6)) && ahead[0, 5] == 'space' && both_separator?(ahead[5])
157
161
  @source.read(5) and ' '
158
- elsif (ahead = lookahead(4)) && ahead[0, 3] == 'tab' && (!ahead[3] || both?(ahead[3]))
162
+ elsif (ahead = lookahead(4)) && ahead[0, 3] == 'tab' && both_separator?(ahead[3])
159
163
  @source.read(3) and "\t"
160
- elsif (ahead = lookahead(10)) && ahead[0, 9] == 'backspace' && (!ahead[9] || both?(ahead[9]))
164
+ elsif (ahead = lookahead(10)) && ahead[0, 9] == 'backspace' && both_separator?(ahead[9])
161
165
  @source.read(9) and "\b"
162
- elsif (ahead = lookahead(9)) && ahead[0, 8] == 'formfeed' && (!ahead[8] || both?(ahead[8]))
166
+ elsif (ahead = lookahead(9)) && ahead[0, 8] == 'formfeed' && both_separator?(ahead[8])
163
167
  @source.read(8) and "\f"
164
- elsif (ahead = lookahead(7)) && ahead[0, 6] == 'return' && (!ahead[6] || both?(ahead[6]))
168
+ elsif (ahead = lookahead(7)) && ahead[0, 6] == 'return' && both_separator?(ahead[6])
165
169
  @source.read(6) and "\r"
166
- elsif (ahead = lookahead(6)) && ahead[0] == 'u' && ahead[1, 5] =~ UNICODE_REGEX && (!ahead[5] || both?(ahead[5]))
170
+ elsif (ahead = lookahead(6)) && ahead[0] == 'u' && ahead[1, 5] =~ UNICODE_REGEX && both_separator?(ahead[5])
167
171
  [@source.read(5)[1, 4].to_i(16)].pack('U')
168
172
  elsif (ahead = lookahead(5)) && ahead[0] == 'o' && matches = ahead[1, 3].match(OCTAL_REGEX)
169
173
  length = matches[0].length + 1
170
174
 
171
- if !ahead[length] || both?(ahead[length])
175
+ if both_separator?(ahead[length])
172
176
  @source.read(length)[1, 3].to_i(8).chr
173
177
  end
174
178
  end or raise SyntaxError, 'unknown character type'
175
179
  end
176
180
 
181
+ def read_symbol (ch)
182
+ result = ch
183
+
184
+ while (ch = @source.read(1)) && is_symbol?(ch)
185
+ result << ch
186
+ end
187
+
188
+ revert if ch
189
+
190
+ if result.include? '::'
191
+ raise SyntaxError, 'symbols cannot have repeating :'
192
+ end
193
+
194
+ result.to_sym.symbol!
195
+ end
196
+
177
197
  def read_keyword (ch)
178
198
  result = ''
179
199
 
180
- while (ch = @source.read(1)) && !keyword?(ch)
200
+ while (ch = @source.read(1)) && !keyword_separator?(ch)
181
201
  result << ch
182
202
  end
183
203
 
184
204
  revert if ch
185
205
 
186
- result.to_sym
206
+ result.to_sym.keyword!
187
207
  end
188
208
 
189
209
  def read_string (ch)
@@ -321,12 +341,16 @@ private
321
341
  ch == ' ' || ch == ',' || ch == "\n" || ch == "\r" || ch == "\t"
322
342
  end
323
343
 
324
- def both? (ch)
325
- ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == "\n" || ch == "\r" || ch == "\t"
344
+ def is_symbol? (ch)
345
+ SYMBOL.include?(ch)
346
+ end
347
+
348
+ def both_separator? (ch)
349
+ ch == nil || ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == "\n" || ch == "\r" || ch == "\t"
326
350
  end
327
351
 
328
- def keyword? (ch)
329
- ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == "'" || ch == '^' || ch == '@' || ch == '`' || ch == '~' || ch == '\\' || ch == ';' || ch == "\n" || ch == "\r" || ch == "\t"
352
+ def keyword_separator? (ch)
353
+ ch == nil || ch == ' ' || ch == ',' || ch == '"' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '#' || ch == ':' || ch == "'" || ch == '^' || ch == '@' || ch == '`' || ch == '~' || ch == '\\' || ch == ';' || ch == "\n" || ch == "\r" || ch == "\t"
330
354
  end
331
355
  end
332
356
 
data/lib/clj/types.rb CHANGED
@@ -8,6 +8,8 @@
8
8
  # 0. You just DO WHAT THE FUCK YOU WANT TO.
9
9
  #++
10
10
 
11
+ require 'forwardable'
12
+
11
13
  module Clojure
12
14
  module Metadata
13
15
  def metadata
@@ -73,6 +75,35 @@ module Clojure
73
75
  metadata_to_clj(options) + '#{' + uniq.map { |o| o.to_clj(options) }.join(' ') + '}'
74
76
  end
75
77
  end
78
+
79
+ class Symbol
80
+ def initialize (sym)
81
+ @internal = sym
82
+ end
83
+
84
+ def keyword?; false; end
85
+ def symbol?; true; end
86
+
87
+ def to_clj (*)
88
+ result = to_sym.to_s
89
+
90
+ unless result =~ %r([\w:+!-_?./][\w\d:+!-_?./]*)
91
+ raise ArgumentError, "#{result} cannot be transformed into clojure"
92
+ end
93
+
94
+ result
95
+ end
96
+
97
+ def == (other)
98
+ return false unless other.is_a?(Symbol)
99
+
100
+ to_sym == other.to_sym
101
+ end
102
+
103
+ def to_sym; @internal; end
104
+ def to_s; to_sym.to_s; end
105
+ def inspect; to_s end
106
+ end
76
107
  end
77
108
 
78
109
  [Numeric, TrueClass, FalseClass, NilClass].each {|klass|
@@ -84,8 +115,19 @@ end
84
115
  }
85
116
 
86
117
  class Symbol
87
- def to_clj (options = {})
88
- result = inspect
118
+ def keyword!
119
+ self
120
+ end
121
+
122
+ def symbol!
123
+ Clojure::Symbol.new(self)
124
+ end
125
+
126
+ def keyword?; true; end
127
+ def symbol?; false; end
128
+
129
+ def to_clj (*)
130
+ result = to_sym.inspect
89
131
 
90
132
  unless result =~ /:([^(\[{'^@`~\"\\,\s;)\]}]+)/
91
133
  raise ArgumentError, "#{result} cannot be transformed into clojure"
@@ -96,12 +138,8 @@ class Symbol
96
138
  end
97
139
 
98
140
  class String
99
- def to_clj (options = {})
100
- result = if respond_to? :encode
101
- encode('UTF-16be').inspect
102
- else
103
- inspect
104
- end
141
+ def to_clj (*)
142
+ result = (encode('UTF-16be') rescue self).inspect
105
143
 
106
144
  result.gsub!(/(^|[^\\])\\e/, '\1\u001b')
107
145
  result.gsub!(/(^|[^\\])\\a/, '\1\u0003')
@@ -111,13 +149,13 @@ class String
111
149
  end
112
150
 
113
151
  class Rational
114
- def to_clj (options = {})
152
+ def to_clj (*)
115
153
  to_s
116
154
  end
117
155
  end
118
156
 
119
157
  class Regexp
120
- def to_clj (options = {})
158
+ def to_clj (*)
121
159
  '#"' + inspect[1 .. -2] + '"'
122
160
  end
123
161
  end
@@ -141,13 +179,13 @@ class Time
141
179
  end
142
180
 
143
181
  class Bignum < Integer
144
- def to_clj (options = {})
182
+ def to_clj (*)
145
183
  to_s + 'N'
146
184
  end
147
185
  end
148
186
 
149
187
  class BigDecimal < Numeric
150
- def to_clj (options = {})
188
+ def to_clj (*)
151
189
  to_s('F') + 'M'
152
190
  end
153
191
  end
data/lib/clj.rb CHANGED
@@ -71,8 +71,10 @@ end
71
71
 
72
72
  require 'clj/types'
73
73
 
74
- if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
74
+ begin
75
+ raise LoadError if RUBY_ENGINE == 'jruby'
76
+
75
77
  require 'clj/parser_ext'
76
- else
78
+ rescue LoadError
77
79
  require 'clj/parser'
78
80
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clj
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6.1
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-01 00:00:00.000000000 Z
12
+ date: 2012-03-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &7244020 !ruby/object:Gem::Requirement
16
+ requirement: &17788760 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *7244020
24
+ version_requirements: *17788760
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &7243040 !ruby/object:Gem::Requirement
27
+ requirement: &18290880 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *7243040
35
+ version_requirements: *18290880
36
36
  description:
37
37
  email: meh@paranoici.org
38
38
  executables: []