js2 0.0.10 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/Manifest +42 -0
  2. data/README.md +65 -0
  3. data/Rakefile +19 -35
  4. data/bin/js2 +80 -66
  5. data/config/js2.yml +2 -0
  6. data/js2.gemspec +33 -0
  7. data/lib/js2/{haml_parser.rb → parser/haml.rb} +2 -2
  8. data/lib/js2/{haml_engine.rb → parser/haml_engine.rb} +1 -1
  9. data/lib/js2/parser/lexer.rb +37 -0
  10. data/lib/js2/{parser.rb → parser/tokenizer.rb} +157 -143
  11. data/lib/js2/{replace.rb → ragel/helper.rb} +16 -5
  12. data/lib/js2/ragel/tokenizer.rl +561 -0
  13. data/lib/js2/{tokenizer.rl.erb → ragel/tokenizer.rl.erb} +12 -19
  14. data/lib/js2/standard/factory.rb +289 -0
  15. data/lib/js2/standard/node.rb +75 -0
  16. data/lib/js2/util/compilation.rb +77 -0
  17. data/lib/js2/util/config.rb +84 -0
  18. data/lib/js2/util/exec.rb +34 -0
  19. data/lib/js2/util/file_handler.rb +73 -0
  20. data/lib/js2/{js2bootstrap.js2 → util/js2bootstrap.js2} +12 -68
  21. data/lib/js2/util/processor.rb +88 -0
  22. data/lib/js2/util/rdoc.rb +35 -0
  23. data/lib/js2/{sel_decorator.rb → util/sel_decorator.rb} +11 -1
  24. data/lib/js2.rb +22 -45
  25. data/test/compiled/bar.js +3 -0
  26. data/test/compiled/basic.comp.js +31 -0
  27. data/test/compiled/basic.js +27 -0
  28. data/test/compiled/foo.js +3 -0
  29. data/test/fixtures/bar.js2 +3 -0
  30. data/test/fixtures/basic.js2 +27 -0
  31. data/test/fixtures/basic.js2.haml +4 -0
  32. data/test/fixtures/basic.js2.yml +5 -0
  33. data/test/fixtures/curry.js2 +5 -0
  34. data/test/fixtures/foo.js2 +3 -0
  35. data/test/fixtures/member.js2 +14 -0
  36. data/test/fixtures/private.js2 +5 -0
  37. data/test/fixtures/property.js2 +4 -0
  38. data/test/test_helper.rb +25 -0
  39. data/test/test_js2.rb +43 -0
  40. data/wiki/features.md +106 -0
  41. data/wiki/installation.md +53 -0
  42. metadata +89 -83
  43. data/Changelog +0 -33
  44. data/History.txt +0 -4
  45. data/Manifest.txt +0 -35
  46. data/PostInstall.txt +0 -7
  47. data/README +0 -69
  48. data/README.rdoc +0 -69
  49. data/README.txt +0 -69
  50. data/examples/js2.yml +0 -8
  51. data/examples/test.yml +0 -5
  52. data/lib/javascript/sel_marker.js2 +0 -150
  53. data/lib/javascript/test.js2 +0 -73
  54. data/lib/js2/config.rb +0 -39
  55. data/lib/js2/daemon.rb +0 -35
  56. data/lib/js2/file_handler.rb +0 -91
  57. data/lib/js2/foo.js2.haml +0 -3
  58. data/lib/js2/js2.js +0 -110
  59. data/lib/js2/processor.rb +0 -112
  60. data/lib/js2/test/selenium.rb +0 -119
  61. data/lib/js2/test/selenium_element.rb +0 -234
  62. data/lib/js2/test/selenium_helper.rb +0 -27
  63. data/lib/js2/tree.rb +0 -351
  64. data/lib/js2/universe.rb +0 -123
  65. data/lib/tasks/js2.rake +0 -9
  66. data/website/index.txt +0 -86
  67. /data/{LICENSE → lib/js2/standard/class_node.rb} +0 -0
@@ -2,7 +2,7 @@ require 'erb'
2
2
 
3
3
  LITERALS = [ '!=', '!==', '#', '%', '%=', '&&', '&&=', '&=', '*', '*=', '+', '+=', ',', '-', '-=', '->', '.', '/', '/=', ':', '::', '<', '<<', '<<=', '<=', '=', '==', '===', '>', '>=', '>>', '>>=', '>>>', '>>>=', '?', '@', '[', '^', '^=', '^^', '^^=', '|', '|=', '||', '||=', 'abstract', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'field', 'final', 'finally', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'native', 'new', 'package', 'private', 'protected', 'public', 'return', 'static', 'switch', 'synchronized', 'throw', 'throws', 'transient', 'try', 'typeof', 'var', 'volatile', 'while', 'with', 'foreach', 'module', 'include' ]
4
4
 
5
- class Replacer
5
+ class Helper
6
6
  def initialize
7
7
  @types = []
8
8
  end
@@ -40,6 +40,20 @@ class Replacer
40
40
  END
41
41
  end
42
42
 
43
+ def comment ()
44
+ return <<-END
45
+ start_argv[0] = sym_COMMENT;
46
+ start_argv[1] = INT2FIX(ts-data);
47
+ start_argv[2] = INT2FIX(is_static);
48
+ rb_funcall2(self, start_sym, 3, start_argv);
49
+ is_static = 0;
50
+ stop_argv[0] = INT2FIX(te-data);
51
+ rb_funcall2(self, stop_sym, 1, stop_argv);
52
+ END
53
+
54
+ end
55
+
56
+
43
57
  def start_member (type, idx = nil)
44
58
  return <<-END
45
59
  close_on_semi = 1;
@@ -95,10 +109,7 @@ class Replacer
95
109
 
96
110
  end
97
111
 
98
- module JS2
99
- end
100
-
101
- replacer = Replacer.new
112
+ replacer = Helper.new
102
113
  template = ERB.new(File.read('./tokenizer.rl.erb'), 0, "%<>")
103
114
 
104
115
  File.open('./tokenizer.rl', 'w') do |f|
@@ -0,0 +1,561 @@
1
+ # Somewhat based on http://www.mozilla.org/js/language/js20-2000-07/formal/lexer-grammar.html
2
+ # Regular Expression Literals determined with these rules:
3
+ # http://www.mozilla.org/js/language/js20-1999-03-25/tokens.html
4
+
5
+ %%{
6
+ machine dude;
7
+ alphtype char;
8
+
9
+ action actionStringBegin {
10
+ }
11
+
12
+ action actionStringAcc {
13
+ }
14
+
15
+ action actionStringAccBsEscape {
16
+ }
17
+
18
+ action actionStringAccUtf16 {
19
+ }
20
+
21
+ unicodecharacter = any;
22
+ unicodeinitialalphabetic = alpha;
23
+ unicodealphanumeric = alnum;
24
+ whitespacecharacter = [\t\v\f ];
25
+ lineterminator = ('\r' | '\n');
26
+ asciidigit = digit;
27
+ ws = (whitespacecharacter | lineterminator);
28
+
29
+ literals = (
30
+ '==' | '!=' | '===' | '!==' | '<=' | '>=' | '||' | '&&' | '++' | '--' | '<<' | '<<=' | '>>' | '>>=' | '>>>' | '>>>='| '&=' | '%=' | '^=' | '|=' | '+=' | '-=' | '*=' | '/='
31
+ );
32
+
33
+ # put in class
34
+ # put in accessor
35
+ keywords = (
36
+ 'break' | 'case' | 'catch' | 'continue' | 'default' | 'delete' | 'do' |
37
+ 'else' | 'finally' | 'for' | 'function' | 'if' | 'in' | 'instanceof' |
38
+ 'new' | 'return' | 'switch' | 'this' | 'throw' | 'try' | 'typeof' | 'var' | 'accessor' |
39
+ 'void' | 'while' | 'with' | 'const' | 'true' | 'false' | 'null' | 'debugger' |
40
+ 'class' | 'static' | 'foreach' | 'module' | 'include' | 'property'
41
+ );
42
+
43
+ # took out class
44
+ reserved = (
45
+ 'abstract' | 'boolean' | 'byte' | 'char' | 'double' | 'enum' | 'export' |
46
+ 'extends' | 'final' | 'float' | 'goto' | 'implements' | 'import' | 'int' | 'interface' |
47
+ 'long' | 'native' | 'package' | 'private' | 'protected' | 'public' | 'short' |
48
+ 'super' | 'synchronized' | 'throws' | 'transient' | 'volatile'
49
+ );
50
+
51
+ nonterminator = any - lineterminator;
52
+ linecommentcharacters = nonterminator*;
53
+ nonterminatororslash = nonterminator - '/';
54
+ nonterminatororastreisk = nonterminator - '*';
55
+ nonterminatororasteriskorslash = nonterminator - ('*' | '/');
56
+ blockcommentcharacters = (nonterminatororslash | (nonterminatororastreisk '/'))*;
57
+ multilineblockcommentcharacters = (blockcommentcharacters lineterminator)*;
58
+
59
+ linecomment = '//' linecommentcharacters;
60
+ singlelineblockcomment = '/*' blockcommentcharacters '*/';
61
+ multilineblockcomment = '/*' multilineblockcommentcharacters blockcommentcharacters '*/';
62
+ comment = linecomment | singlelineblockcomment | multilineblockcomment;
63
+
64
+ string_begin = '\'' @ actionStringBegin;
65
+ string_end = '\'';
66
+ stringchar_normal = ^(['\\] | 0..0x1f) @ actionStringAcc;
67
+ stringchar_bs_esc = '\\'['\\/bfnrt] @ actionStringAccBsEscape;
68
+ stringchar_utf16 = '\\u'[0-9a-fA-F]{4} @ actionStringAccUtf16;
69
+ stringchar_bs_other = '\\'^(['\\/bfnrtu]|0..0x1f) @ actionStringAccBsEscape;
70
+ stringchar = (stringchar_normal | stringchar_bs_esc | stringchar_utf16 | stringchar_bs_other);
71
+ string = string_begin . stringchar* . string_end;
72
+
73
+ ds_string_begin = '"' @ actionStringBegin;
74
+ ds_string_end = '"';
75
+ ds_stringchar_normal = ^(["\\] | 0..0x1f) @ actionStringAcc;
76
+ ds_stringchar_bs_esc = '\\'["\\/bfnrt] @ actionStringAccBsEscape;
77
+ ds_stringchar_utf16 = '\\u'[0-9a-fA-F]{4} @ actionStringAccUtf16;
78
+ ds_stringchar_bs_other = '\\'^(["\\/bfnrtu]|0..0x1f) @ actionStringAccBsEscape;
79
+ ds_stringchar = (ds_stringchar_normal | ds_stringchar_bs_esc | ds_stringchar_utf16 | ds_stringchar_bs_other);
80
+ ds_string = ds_string_begin . ds_stringchar* . ds_string_end;
81
+
82
+ all_string = string | ds_string;
83
+
84
+ integer = '-'? . digit+;
85
+ float = '-'? (
86
+ (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
87
+ | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
88
+ );
89
+ number = integer | float;
90
+
91
+ identifier_char = ([a-zA-Z0-9_]) | '$';
92
+ identifier = identifier_char+;
93
+
94
+ ordinaryregexpchar = nonterminator - ('/' | '\\');
95
+ regexpchars = (ordinaryregexpchar | '\\' nonterminator)+;
96
+ regexpbody = '/' @ {regexp_start = p;} regexpchars '/';
97
+ regexpflags = ('g' | 'i' | 'm')*;
98
+ regexpliteral = regexpbody regexpflags;
99
+
100
+ specialcasedivide = (
101
+ identifier '/'
102
+ );
103
+ single_char = any;
104
+
105
+ var_list = (identifier . ws* . ',' . ws*)* . identifier?;
106
+ arg_list = '(' . ws* . var_list . ws* .')';
107
+
108
+ curry_with = 'with' . ws* . arg_list;
109
+ curry = 'curry' . ws* . arg_list? . ws* . curry_with? . ws*;
110
+
111
+ foreach = 'foreach' . ws* . '(' . ws* . 'var' . ws* . identifier . (ws* . ':' . ws* . identifier)? . ws*;
112
+
113
+ js2_include = 'include' . ws+ . identifier;
114
+ js2_class = 'class' . ws+ . identifier;
115
+ js2_module = 'module' . ws+ . identifier;
116
+
117
+ property = ws . 'property' . ws . var_list;
118
+ member = ws . ('static' . ws+)? . 'var' . ws+ . identifier;
119
+ method = ws . ('static' . ws+)? . 'function' . ws* . identifier;
120
+ private = ws . 'private' . ws;
121
+ accessor = ws . 'accessor' . ws;
122
+
123
+
124
+
125
+
126
+ main := |*
127
+
128
+ lineterminator => {
129
+ //line_number++;
130
+ };
131
+
132
+ js2_class => {
133
+ if (in_class == 0) {
134
+ curlies[++curly_idx] = cb_count;;
135
+
136
+ start_argv[0] = sym_CLASS;
137
+ start_argv[1] = INT2FIX(ts-data);
138
+ start_argv[2] = INT2FIX(is_static);
139
+ rb_funcall2(self, start_sym, 3, start_argv);
140
+ is_static = 0;
141
+
142
+ in_class = curly_idx;
143
+ }
144
+ };
145
+
146
+ private => {
147
+ if (in_class && in_class == curly_idx) {
148
+ curlies[++curly_idx] = cb_count;;
149
+
150
+ start_argv[0] = sym_PRIVATE;
151
+ start_argv[1] = INT2FIX(ts-data);
152
+ start_argv[2] = INT2FIX(is_static);
153
+ rb_funcall2(self, start_sym, 3, start_argv);
154
+ is_static = 0;
155
+
156
+ if (curly_idx) curly_idx--;
157
+ stop_argv[0] = INT2FIX(te-data);
158
+ rb_funcall2(self, stop_sym, 1, stop_argv);
159
+
160
+ }
161
+ };
162
+
163
+ js2_module => {
164
+ if (in_class == 0) {
165
+ curlies[++curly_idx] = cb_count;;
166
+
167
+ start_argv[0] = sym_MODULE;
168
+ start_argv[1] = INT2FIX(ts-data);
169
+ start_argv[2] = INT2FIX(is_static);
170
+ rb_funcall2(self, start_sym, 3, start_argv);
171
+ is_static = 0;
172
+
173
+ in_class = curly_idx;
174
+ }
175
+ };
176
+
177
+ property => {
178
+ if (in_class && in_class == curly_idx) {
179
+ close_on_semi = 1;
180
+ start_argv[0] = sym_PROPERTY;
181
+ start_argv[1] = INT2FIX(ts-data);
182
+ start_argv[2] = INT2FIX(is_static);
183
+ rb_funcall2(self, start_sym, 3, start_argv);
184
+ is_static = 0;
185
+
186
+ }
187
+ };
188
+
189
+ accessor => {
190
+ if (in_class && in_class == curly_idx) {
191
+ close_on_semi = 1;
192
+ start_argv[0] = sym_ACCESSOR;
193
+ start_argv[1] = INT2FIX(ts-data);
194
+ start_argv[2] = INT2FIX(is_static);
195
+ rb_funcall2(self, start_sym, 3, start_argv);
196
+ is_static = 0;
197
+
198
+ }
199
+ };
200
+
201
+
202
+ member => {
203
+ if (in_class && in_class == curly_idx) {
204
+ close_on_semi = 1;
205
+ start_argv[0] = sym_MEMBER;
206
+ start_argv[1] = INT2FIX(ts-data);
207
+ start_argv[2] = INT2FIX(is_static);
208
+ rb_funcall2(self, start_sym, 3, start_argv);
209
+ is_static = 0;
210
+
211
+ }
212
+ };
213
+
214
+ method => {
215
+ if (in_class && in_class == curly_idx) {
216
+ curlies[++curly_idx] = cb_count;;
217
+
218
+ start_argv[0] = sym_METHOD;
219
+ start_argv[1] = INT2FIX(ts-data);
220
+ start_argv[2] = INT2FIX(is_static);
221
+ rb_funcall2(self, start_sym, 3, start_argv);
222
+ is_static = 0;
223
+
224
+ }
225
+ };
226
+
227
+
228
+ js2_include => {
229
+ if (in_class && in_class == curly_idx) {
230
+ close_on_semi = 1;
231
+ start_argv[0] = sym_INCLUDE;
232
+ start_argv[1] = INT2FIX(ts-data);
233
+ start_argv[2] = INT2FIX(is_static);
234
+ rb_funcall2(self, start_sym, 3, start_argv);
235
+ is_static = 0;
236
+
237
+ }
238
+ };
239
+
240
+ foreach => {
241
+ curlies[++curly_idx] = cb_count;;
242
+
243
+ start_argv[0] = sym_FOREACH;
244
+ start_argv[1] = INT2FIX(ts-data);
245
+ start_argv[2] = INT2FIX(is_static);
246
+ rb_funcall2(self, start_sym, 3, start_argv);
247
+ is_static = 0;
248
+
249
+ mark_on_br = br_count;
250
+ br_count++;
251
+ };
252
+
253
+ curry => {
254
+ curlies[++curly_idx] = cb_count;;
255
+
256
+ start_argv[0] = sym_CURRY;
257
+ start_argv[1] = INT2FIX(ts-data);
258
+ start_argv[2] = INT2FIX(is_static);
259
+ rb_funcall2(self, start_sym, 3, start_argv);
260
+ is_static = 0;
261
+
262
+ };
263
+
264
+ whitespacecharacter => {};
265
+ comment => {
266
+ start_argv[0] = sym_COMMENT;
267
+ start_argv[1] = INT2FIX(ts-data);
268
+ start_argv[2] = INT2FIX(is_static);
269
+ rb_funcall2(self, start_sym, 3, start_argv);
270
+ is_static = 0;
271
+ stop_argv[0] = INT2FIX(te-data);
272
+ rb_funcall2(self, stop_sym, 1, stop_argv);
273
+
274
+ };
275
+
276
+ all_string => {};
277
+ number => {};
278
+ keywords => { };
279
+
280
+ literals => { };
281
+ reserved => { };
282
+ identifier => { };
283
+
284
+ '!=' ws* regexpliteral => { };
285
+ '!==' ws* regexpliteral => { };
286
+ '#' ws* regexpliteral => { };
287
+ '%' ws* regexpliteral => { };
288
+ '%=' ws* regexpliteral => { };
289
+ '&&' ws* regexpliteral => { };
290
+ '&&=' ws* regexpliteral => { };
291
+ '&=' ws* regexpliteral => { };
292
+ '*' ws* regexpliteral => { };
293
+ '*=' ws* regexpliteral => { };
294
+ '+' ws* regexpliteral => { };
295
+ '+=' ws* regexpliteral => { };
296
+ ',' ws* regexpliteral => { };
297
+ '-' ws* regexpliteral => { };
298
+ '-=' ws* regexpliteral => { };
299
+ '->' ws* regexpliteral => { };
300
+ '.' ws* regexpliteral => { };
301
+ '/' ws* regexpliteral => { };
302
+ '/=' ws* regexpliteral => { };
303
+ ':' ws* regexpliteral => { };
304
+ '::' ws* regexpliteral => { };
305
+ '<' ws* regexpliteral => { };
306
+ '<<' ws* regexpliteral => { };
307
+ '<<=' ws* regexpliteral => { };
308
+ '<=' ws* regexpliteral => { };
309
+ '=' ws* regexpliteral => { };
310
+ '==' ws* regexpliteral => { };
311
+ '===' ws* regexpliteral => { };
312
+ '>' ws* regexpliteral => { };
313
+ '>=' ws* regexpliteral => { };
314
+ '>>' ws* regexpliteral => { };
315
+ '>>=' ws* regexpliteral => { };
316
+ '>>>' ws* regexpliteral => { };
317
+ '>>>=' ws* regexpliteral => { };
318
+ '?' ws* regexpliteral => { };
319
+ '@' ws* regexpliteral => { };
320
+ '[' ws* regexpliteral => { };
321
+ '^' ws* regexpliteral => { };
322
+ '^=' ws* regexpliteral => { };
323
+ '^^' ws* regexpliteral => { };
324
+ '^^=' ws* regexpliteral => { };
325
+ '|' ws* regexpliteral => { };
326
+ '|=' ws* regexpliteral => { };
327
+ '||' ws* regexpliteral => { };
328
+ '||=' ws* regexpliteral => { };
329
+ 'abstract' ws* regexpliteral => { };
330
+ 'break' ws* regexpliteral => { };
331
+ 'case' ws* regexpliteral => { };
332
+ 'catch' ws* regexpliteral => { };
333
+ 'class' ws* regexpliteral => { };
334
+ 'const' ws* regexpliteral => { };
335
+ 'continue' ws* regexpliteral => { };
336
+ 'debugger' ws* regexpliteral => { };
337
+ 'default' ws* regexpliteral => { };
338
+ 'delete' ws* regexpliteral => { };
339
+ 'do' ws* regexpliteral => { };
340
+ 'else' ws* regexpliteral => { };
341
+ 'enum' ws* regexpliteral => { };
342
+ 'export' ws* regexpliteral => { };
343
+ 'extends' ws* regexpliteral => { };
344
+ 'field' ws* regexpliteral => { };
345
+ 'final' ws* regexpliteral => { };
346
+ 'finally' ws* regexpliteral => { };
347
+ 'for' ws* regexpliteral => { };
348
+ 'function' ws* regexpliteral => { };
349
+ 'goto' ws* regexpliteral => { };
350
+ 'if' ws* regexpliteral => { };
351
+ 'implements' ws* regexpliteral => { };
352
+ 'import' ws* regexpliteral => { };
353
+ 'in' ws* regexpliteral => { };
354
+ 'instanceof' ws* regexpliteral => { };
355
+ 'native' ws* regexpliteral => { };
356
+ 'new' ws* regexpliteral => { };
357
+ 'package' ws* regexpliteral => { };
358
+ 'private' ws* regexpliteral => { };
359
+ 'protected' ws* regexpliteral => { };
360
+ 'public' ws* regexpliteral => { };
361
+ 'return' ws* regexpliteral => { };
362
+ 'static' ws* regexpliteral => { };
363
+ 'switch' ws* regexpliteral => { };
364
+ 'synchronized' ws* regexpliteral => { };
365
+ 'throw' ws* regexpliteral => { };
366
+ 'throws' ws* regexpliteral => { };
367
+ 'transient' ws* regexpliteral => { };
368
+ 'try' ws* regexpliteral => { };
369
+ 'typeof' ws* regexpliteral => { };
370
+ 'var' ws* regexpliteral => { };
371
+ 'volatile' ws* regexpliteral => { };
372
+ 'while' ws* regexpliteral => { };
373
+ 'with' ws* regexpliteral => { };
374
+ 'foreach' ws* regexpliteral => { };
375
+ 'module' ws* regexpliteral => { };
376
+ 'include' ws* regexpliteral => { };
377
+
378
+
379
+ single_char | (('(' | '{' | ';' | '}') ws* regexpliteral) => {
380
+ char single = data[ts-data];
381
+
382
+ if (single == '{') {
383
+ in_foreach = 0;
384
+ cb_count++;
385
+ } else if (single == '}') {
386
+ cb_count--;
387
+ if (curly_idx && curlies[curly_idx] == cb_count) {
388
+ in_foreach = 0;
389
+ if (curly_idx) curly_idx--;
390
+ stop_argv[0] = INT2FIX(te-data);
391
+ rb_funcall2(self, stop_sym, 1, stop_argv);
392
+
393
+ if (curlies[in_class] == cb_count) {
394
+ in_class = 0;
395
+ }
396
+ }
397
+ } else if (single == ';' && close_on_semi == 1) {
398
+ close_on_semi = 0;
399
+ stop_argv[0] = INT2FIX(te-data);
400
+ rb_funcall2(self, stop_sym, 1, stop_argv);
401
+
402
+ }
403
+
404
+ if (single == ';' || single == '}') {
405
+ classable = 1;
406
+ }
407
+
408
+ if (single == '(') {
409
+ br_count++;
410
+ } else if (single == ')') {
411
+ br_count--;
412
+ if (mark_on_br == br_count) {
413
+ if (curly_idx) curly_idx--;
414
+ stop_argv[0] = INT2FIX(te-data);
415
+ rb_funcall2(self, stop_sym, 1, stop_argv);
416
+
417
+ mark_on_br = -1;
418
+ }
419
+ }
420
+ };
421
+
422
+ *|;
423
+ }%%
424
+
425
+ require 'rubygems'
426
+ require 'inline'
427
+
428
+ class JS2::Parser::Tokenizer
429
+ attr_accessor :data
430
+
431
+ inline do |builder|
432
+ builder.c_raw <<-END
433
+
434
+ int tokenize (int argc, VALUE *argv, VALUE self) {
435
+ // convert ruby string to char*
436
+ VALUE r_str = argv[0];
437
+ int data_length = RSTRING(r_str)->len;
438
+ char* data = STR2CSTR(r_str);
439
+
440
+ int in_class = 0;
441
+ int in_module = 0;
442
+ int close_on_semi = 0;
443
+ int classable = 1;
444
+ int in_foreach = 0;
445
+
446
+ // start vars
447
+ VALUE start_argv[3];
448
+ ID start_sym = rb_intern("start_node");
449
+
450
+ // stop vars
451
+ VALUE stop_argv[1];
452
+ ID stop_sym = rb_intern("stop_node");
453
+
454
+ // mark vars
455
+ VALUE mark_argv[1];
456
+ ID mark_sym = rb_intern("mark_node");
457
+ int mark_on_br = -1;
458
+
459
+
460
+ VALUE warn_intv[1];
461
+ ID warn_sym = rb_intern("warn_int");
462
+
463
+
464
+ // state vars
465
+ int i = 0; // iterator
466
+ int j = 0; // iterator
467
+
468
+ char keyword[100]; // keyword
469
+ char single;
470
+ int is_static = 0;
471
+ int is_private = 0;
472
+
473
+ // curly handling
474
+ int curlies[1000];
475
+ curlies[0] = 0;
476
+ int curly_idx = 0; // on purpose!
477
+ int cb_count = 0;
478
+ int br_count = 0;
479
+ int close_on_br = 0;
480
+
481
+ // CLASS
482
+ ID sym_CLASS = ID2SYM(rb_intern("CLASS"));
483
+ // METHOD
484
+ ID sym_METHOD = ID2SYM(rb_intern("METHOD"));
485
+ // MEMBER
486
+ ID sym_MEMBER = ID2SYM(rb_intern("MEMBER"));
487
+ // STUFF
488
+ ID sym_STUFF = ID2SYM(rb_intern("STUFF"));
489
+ // ACCESSOR
490
+ ID sym_ACCESSOR = ID2SYM(rb_intern("ACCESSOR"));
491
+ // COMMENT
492
+ ID sym_COMMENT = ID2SYM(rb_intern("COMMENT"));
493
+ // FOREACH
494
+ ID sym_FOREACH = ID2SYM(rb_intern("FOREACH"));
495
+ // MODULE
496
+ ID sym_MODULE = ID2SYM(rb_intern("MODULE"));
497
+ // INCLUDE
498
+ ID sym_INCLUDE = ID2SYM(rb_intern("INCLUDE"));
499
+ // CURRY
500
+ ID sym_CURRY = ID2SYM(rb_intern("CURRY"));
501
+ // PROPERTY
502
+ ID sym_PROPERTY = ID2SYM(rb_intern("PROPERTY"));
503
+ // PRIVATE
504
+ ID sym_PRIVATE = ID2SYM(rb_intern("PRIVATE"));
505
+ // STATIC
506
+ ID sym_STATIC = ID2SYM(rb_intern("STATIC"));
507
+
508
+ // ragel variables
509
+ int cs, act;
510
+ char *ts = NULL;
511
+ char *te = NULL;
512
+ char *p = data;
513
+ char *pe = p + data_length;
514
+ char *eof = pe;
515
+ char* regexp_start = NULL;
516
+
517
+ ;
518
+
519
+ start_argv[0] = sym_STUFF;
520
+ start_argv[1] = INT2FIX(0);
521
+ start_argv[2] = INT2FIX(is_static);
522
+ rb_funcall2(self, start_sym, 3, start_argv);
523
+ is_static = 0;
524
+
525
+
526
+ %% write data;
527
+ %% write init;
528
+ %% write exec;
529
+
530
+ if (curly_idx) curly_idx--;
531
+ stop_argv[0] = INT2FIX(data_length-1);
532
+ rb_funcall2(self, stop_sym, 1, stop_argv);
533
+
534
+ }
535
+
536
+ END
537
+ end
538
+
539
+ def warn_int (int)
540
+ puts int.to_s
541
+ end
542
+
543
+ def start_node (type, idx, is_static)
544
+ @lexer.start_node(type, idx, is_static == 1)
545
+ end
546
+
547
+ def stop_node (idx)
548
+ @lexer.stop_node(idx)
549
+ end
550
+
551
+ def mark_node (idx)
552
+ @lexer.mark_node(idx)
553
+ end
554
+
555
+ def tokenize! (data, lexer)
556
+ @data = data
557
+ @lexer = lexer
558
+ self.tokenize(data)
559
+ end
560
+
561
+ end
@@ -193,7 +193,9 @@
193
193
  };
194
194
 
195
195
  whitespacecharacter => {};
196
- comment => { };
196
+ comment => {
197
+ <%= replacer.comment %>
198
+ };
197
199
 
198
200
  all_string => {};
199
201
  number => {};
@@ -245,13 +247,13 @@
245
247
  require 'rubygems'
246
248
  require 'inline'
247
249
 
248
- class JS2::Parser
250
+ class JS2::Parser::Tokenizer
249
251
  attr_accessor :data
250
252
 
251
253
  inline do |builder|
252
254
  builder.c_raw <<-END
253
255
 
254
- int do_parse (int argc, VALUE *argv, VALUE self) {
256
+ int tokenize (int argc, VALUE *argv, VALUE self) {
255
257
  // convert ruby string to char*
256
258
  VALUE r_str = argv[0];
257
259
  int data_length = RSTRING(r_str)->len;
@@ -325,30 +327,21 @@ class JS2::Parser
325
327
  end
326
328
 
327
329
  def start_node (type, idx, is_static)
328
- @ph.start_node(type, idx, is_static == 1)
330
+ @lexer.start_node(type, idx, is_static == 1)
329
331
  end
330
332
 
331
333
  def stop_node (idx)
332
- @ph.stop_node(idx)
334
+ @lexer.stop_node(idx)
333
335
  end
334
336
 
335
337
  def mark_node (idx)
336
- @ph.mark_node(idx)
337
- end
338
-
339
-
340
- def parse (data)
341
- @data = data
342
- @ph = JS2::ParserHelper.new(data)
343
- self.do_parse(data)
344
- return @ph
338
+ @lexer.mark_node(idx)
345
339
  end
346
340
 
347
- def parse_file (filename)
348
- data = File.read(filename)
349
- ph = self.parse(data)
350
- ph.filename = filename
351
- return ph
341
+ def tokenize! (data, lexer)
342
+ @data = data
343
+ @lexer = lexer
344
+ self.tokenize(data)
352
345
  end
353
346
 
354
347
  end