clj 0.0.6.1 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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: []