mochiscript 0.4.0.pre1

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.
Files changed (2) hide show
  1. data/lib/mochiscript.rb +704 -0
  2. metadata +57 -0
@@ -0,0 +1,704 @@
1
+ require 'v8'
2
+ require 'json'
3
+
4
+ module Mochiscript
5
+ VERSION = "0.4.0-pre1".sub("-", '.')
6
+ class Context
7
+ def initialize
8
+ @ctx = V8::Context.new
9
+ @ctx['_$m_adapter'] = Adapter.new
10
+ @ctx.eval(Parser::JAVASCRIPT)
11
+ end
12
+
13
+ def parse(str)
14
+ @ctx.eval_js("$m.parse(#{str.to_json})")
15
+ end
16
+
17
+ def eval_ms(str)
18
+ @ctx.eval_js(parse(str))
19
+ end
20
+
21
+ protected
22
+
23
+ def method_missing(name, *args, &block)
24
+ @ctx.send(name, *args, &block)
25
+ end
26
+ end
27
+
28
+ class Adapter
29
+ def out(arg)
30
+ print arg
31
+ end
32
+
33
+ def outs(arg)
34
+ puts arg
35
+ end
36
+ end
37
+
38
+ class Parser
39
+ JAVASCRIPT = <<'FINISH'
40
+ var $m = { ROOT: this, ADAPTER: _$m_adapter };
41
+ var JS2 = $m;
42
+ (function () {
43
+
44
+ // CLASS HELPERS
45
+ (function (undefined, $m) {
46
+
47
+ var OO = function (klass, par) {
48
+ this.klass = klass;
49
+ this.par = par;
50
+
51
+ this.members = {};
52
+ this.staticMembers = {};
53
+ this.children = [];
54
+ this.included = [];
55
+
56
+ if (this.par) this.par.OO.children.push(klass);
57
+ };
58
+
59
+ OO.prototype = {
60
+ forbiddenMembers: {
61
+ 'prototype': undefined,
62
+ 'OO': undefined
63
+ },
64
+
65
+ include: function(module) {
66
+ this.included.push(module);
67
+ var members = module.OO.members;
68
+ for (var name in members) {
69
+ if (members.hasOwnProperty(name)) {
70
+ this.addMember(name, members[name]);
71
+ }
72
+ }
73
+
74
+ var staticMembers = module.OO.staticMembers;
75
+ for (var name in staticMembers) {
76
+ if (staticMembers.hasOwnProperty(name)) {
77
+ this.addStaticMember(name, staticMembers[name]);
78
+ }
79
+ }
80
+
81
+ if (typeof staticMembers['included'] == 'function') {
82
+ staticMembers['included'](this.klass);
83
+ }
84
+ },
85
+
86
+ createNamespace: function(name) {
87
+ var splitted = name.split('.');
88
+ var klassName = splitted.pop();
89
+ var root = $m.ROOT;
90
+
91
+ while (splitted.length > 0) {
92
+ var name = splitted.shift();
93
+ if (!root[name]) root[name] = $m.Class.extend({});
94
+ root = root[name];
95
+ }
96
+
97
+ return [ root, klassName ];
98
+ },
99
+
100
+ makeSuper: function(newMethod, oldMethod) {
101
+ if (!oldMethod) return newMethod;
102
+
103
+ return function() {
104
+ this.$super = oldMethod;
105
+ return newMethod.apply(this, arguments);
106
+ };
107
+ },
108
+
109
+ addMember: function(name, member) {
110
+ if (this.forbiddenMembers.hasOwnProperty(name)) return;
111
+
112
+ var proto = this.klass.prototype;
113
+ if (typeof proto[name] == 'function' && !(proto[name] instanceof RegExp)) {
114
+ member = this.makeSuper(member, proto[name]);
115
+ }
116
+
117
+ proto[name] = member;
118
+ this.members[name] = member;
119
+ },
120
+
121
+ addStaticMember: function(name, member) {
122
+ if (this.forbiddenMembers.hasOwnProperty(name)) return;
123
+
124
+ if (typeof this.klass[name] == 'function') {
125
+ if (!this.klass.hasOwnProperty(name)) {
126
+ member = this.makeSuper(member, this.klass[name]);
127
+ }
128
+ }
129
+
130
+ this.klass[name] = member;
131
+ this.staticMembers[name] = member;
132
+ }
133
+ };
134
+
135
+ $m.Class = function() { this.initialize.apply(this, arguments); };
136
+ $m.Class.OO = new OO($m.Class);
137
+ $m.Class.prototype = {
138
+ initialize: function () {},
139
+ oo: $m.Class.OO
140
+ };
141
+
142
+ var namedClasses = {};
143
+ $m.getClass = function(name) {
144
+ return namedClasses[name];
145
+ };
146
+
147
+ var noInit = false;
148
+ $m.Class.extend = function(name, klassDef) {
149
+ var klass = function() { if (!noInit) this.initialize.apply(this, arguments); };
150
+ klass.OO = new OO(klass, this);
151
+
152
+ if (typeof name != 'string') {
153
+ klassDef = name;
154
+ } else {
155
+ namedClasses[name] = klass;
156
+ var namespace = this.OO.createNamespace(name);
157
+ namespace[0][namespace[1]] = klass;
158
+ }
159
+
160
+ // create instance of this as prototype for new this
161
+ noInit = true;
162
+ var proto = new this();
163
+ noInit = false;
164
+
165
+ klass.prototype = proto;
166
+ var oo = klass.OO;
167
+ proto.OO = oo;
168
+
169
+ for (var name in this) {
170
+ oo.addStaticMember(name, this[name]);
171
+ }
172
+
173
+ if (typeof klassDef == 'function') {
174
+ klassDef(klass, oo);
175
+ } else {
176
+ for (var name in klassDef) {
177
+ oo.addMember(name, klassDef[name]);
178
+ }
179
+ }
180
+
181
+ return klass;
182
+ };
183
+
184
+ $m.Module = $m.Class;
185
+
186
+ var assert = {
187
+ 'eq': function(expected, actual) { if (expected != actual) $m.outs("Expected "+expected+", but got "+actual+".") },
188
+ 'isFalse': function(val) { if (val) $m.outs("Expected false, but got "+JSON.stringify(val)+".") },
189
+ 'isTrue': function(val) { if (!val) $m.outs("Expected true, but got " +val+".") }
190
+ };
191
+
192
+ $m.test = function(message, callback) {
193
+ if (!callback) callback = message;
194
+ callback(assert);
195
+ };
196
+
197
+ function addListener(type, listener) {
198
+ var events = this.__$events || (this.__$events = {});
199
+ this.emit('newListener', type, listener);
200
+ if (!events[type]) events[type] = [];
201
+ events[type].push(listener);
202
+ }
203
+
204
+ $m.EventEmitter = $m.Module.extend({
205
+ emit: function () {
206
+ // TODO optimize
207
+ var type = arguments[0];
208
+ var events = this.__$events || (this.__$events = {});
209
+ var handlers = events[type];
210
+
211
+ if (!handlers) return false;
212
+
213
+ var args = [];
214
+ for (var i=1,len=arguments.length; i<len; i++) args[i-1] = arguments[i];
215
+ for (var i=0,len=handlers.length; i<len; i++) handlers[i].apply(this, args);
216
+ },
217
+
218
+ addListener: addListener,
219
+ on: addListener
220
+ });
221
+
222
+ $m.out = function () {
223
+ for(var i=0,_c1=arguments,_l1=_c1.length,arg;(arg=_c1[i])||(i<_l1);i++){
224
+ $m.ADAPTER.out(arg);
225
+ if (i < arguments.length-1) {
226
+ $m.ADAPTER.out(',');
227
+ }
228
+ }
229
+ };
230
+
231
+ $m.outs = function () {
232
+ for(var _i1=0,_c1=arguments,_l1=_c1.length,arg;(arg=_c1[_i1])||(_i1<_l1);_i1++){
233
+ $m.ADAPTER.outs(arg);
234
+ }
235
+ };
236
+
237
+
238
+ return $m;
239
+ })(undefined, $m);
240
+
241
+ var IDENT = "[\\$\\w]+";
242
+ var TOKENS = [
243
+ [ "SPACE", "\\s+" ],
244
+
245
+ [ "MODULE", "module\\b", 'ModuleParser' ],
246
+ [ "CLASS", "class\\b", 'ClassParser' ],
247
+ [ "FUNCTION", "function\\b" ],
248
+ [ "INCLUDE", "include\\b" ],
249
+ [ "VAR", "var\\b" ],
250
+ [ "STATIC", "static\\b" ],
251
+ [ "PRIVATE", "private\\b" ],
252
+ [ "EXTENDS", "extends\\b" ],
253
+ [ "FOREACH", "foreach\\b", 'ForeachParser' ],
254
+
255
+ [ "SHORTHAND_FUNCTION", "#(?:{|\\()", 'ShorthandFunctionParser' ],
256
+ [ "ISTRING_START", "%{", 'IStringParser' ],
257
+ [ "HEREDOC", "<<[A-Z][0-9A-Z]*", 'HereDocParser' ],
258
+
259
+ [ "DSTRING", "\"(?:\\\\.|[^\"])*\"" ],
260
+ [ "SSTRING", "\'(?:\\\\.|[^\'])*\'" ],
261
+
262
+ [ "SEMICOLON", ";" ],
263
+ [ "OPERATOR", "\\+|\\-|\\++" ],
264
+ [ "EQUALS", "=" ],
265
+
266
+ [ "COMMENT", "\\/\\/|\\/\\*", "CommentParser" ],
267
+
268
+ [ "LBRACE", "\\(" ],
269
+ [ "RBRACE", "\\)" ],
270
+ [ "LCURLY", "\\{" ],
271
+ [ "RCURLY", "\\}" ],
272
+
273
+ [ "IDENT", IDENT ],
274
+ [ "WHATEVER", "." ]
275
+ ];
276
+
277
+ var $c = $m.ROOT;
278
+ var TYPES = {};
279
+ var REGEXES = [];
280
+ var MAIN_REGEX = null;
281
+
282
+ for(var i=0,_c1=TOKENS,_l1=_c1.length,t;(t=_c1[i])||(i<_l1);i++){
283
+ TYPES[t[0]] = i;
284
+ REGEXES.push("(" + t[1] + ")");
285
+ }
286
+
287
+ var EXTRA_REGEX_STRINGS = {
288
+ ARGS: "\\(\s*(?:" + IDENT + ")?(?:\\s*,\\s*" + IDENT + ")*\s*\\)",
289
+ CLASSNAME: "[\\$\\w\\.]+"
290
+ };
291
+
292
+ var MAIN_REGEX = new RegExp("^" + REGEXES.join('|'));
293
+
294
+ JS2.Class.extend('Tokens', function(KLASS, OO){
295
+ OO.addMember("initialize",function (str) {
296
+ this.orig = str;
297
+ this.str = str;
298
+ this.iterator = 0;
299
+ });
300
+
301
+ OO.addMember("peek",function () {
302
+ if (this._peek) return this._peek;
303
+
304
+ var m = this.str.match(MAIN_REGEX);
305
+ if (!m) return null;
306
+
307
+ for(var i=0,_c1=TOKENS,_l1=_c1.length,ele;(ele=_c1[i])||(i<_l1);i++){
308
+ if (m[i+1]) return this._peek = [ i, m[i+1], ele[2] ];
309
+ }
310
+ });
311
+
312
+ OO.addStaticMember("regex",function (str) {
313
+ var regexStr = str.replace(/\*\*/g, "\\s*").replace(/\s+/g, "\\s+").replace(/\>\</g, ">\\s*<").replace(/\<(\w+)\>/g, function($1,$2,$3){
314
+ return "(" + (EXTRA_REGEX_STRINGS[$2] || TOKENS[TYPES[$2]][1]) + ")";
315
+ });
316
+
317
+ return new RegExp("^" + regexStr);
318
+ });
319
+
320
+ OO.addMember("consume",function (n) {
321
+ this.str = this.str.substr(n, this.str.length-n);
322
+ this._peek = null;
323
+ });
324
+
325
+ OO.addMember("any",function () {
326
+ return this.str.length > 0;
327
+ });
328
+
329
+ OO.addMember("match",function (regex) {
330
+ return this.str.match(regex);
331
+ });
332
+ });
333
+ var Tokens = $c.Tokens;
334
+
335
+ $m.parse = function (str) {
336
+ var parser = new $c.RootParser();
337
+ parser.parse(new $c.Tokens(str));
338
+ return parser.toString();
339
+ };
340
+
341
+ JS2.Class.extend('RootParser', function(KLASS, OO){
342
+ OO.addMember("handlers",{});
343
+
344
+ OO.addMember("initialize",function () {
345
+ this.out = [];
346
+ this.finished = false;
347
+ });
348
+
349
+ OO.addMember("parse",function (tokens) {
350
+ this.startParse(tokens);
351
+
352
+ var sanity = 100;
353
+ while (tokens.any()) {
354
+ var origLen = tokens.length;
355
+ var token = tokens.peek();
356
+ if (!token) break;
357
+ var handlerClass = this.getHandler(token) || token[2];
358
+ if (handlerClass) {
359
+ var handler = new $c[handlerClass];
360
+ handler.parse(tokens);
361
+ this.out.push(handler);
362
+ } else {
363
+ this.handleToken(token, tokens);
364
+ }
365
+ if (this.finished) break;
366
+
367
+ if (origLen == tokens.length && sanity-- == 0) {
368
+ throw "parse error";
369
+ } else {
370
+ sanity = 100;
371
+ }
372
+ }
373
+
374
+ this.endParse(tokens);
375
+ });
376
+
377
+ OO.addMember("startParse",function () { });
378
+ OO.addMember("endParse",function () { });
379
+
380
+ OO.addMember("handleToken",function (token, tokens) {
381
+ this.out.push(token[1]);
382
+ tokens.consume(token[1].length);
383
+ });
384
+
385
+ OO.addMember("toString",function () {
386
+ var ret = [];
387
+ for(var _i1=0,_c1=this.out,_l1=_c1.length,ele;(ele=_c1[_i1])||(_i1<_l1);_i1++){
388
+ ret.push(ele.toString());
389
+ }
390
+ return ret.join("");
391
+ });
392
+
393
+ OO.addMember("getHandler",function (token) {
394
+ return null;
395
+ });
396
+
397
+ OO.addMember("chop",function () {
398
+ this.out.pop();
399
+ });
400
+ });
401
+
402
+ var RootParser = $c.RootParser;
403
+
404
+ RootParser.extend('ClassParser', function(KLASS, OO){
405
+ // private closure
406
+
407
+ var REGEX = Tokens.regex("<CLASS> <CLASSNAME><LCURLY>");
408
+ var EXTENDS = Tokens.regex("<CLASS> <CLASSNAME><EXTENDS><CLASSNAME><LCURLY>");
409
+
410
+
411
+ OO.addMember("parse",function (tokens) {
412
+ var m = tokens.match(REGEX) || tokens.match(EXTENDS);
413
+ var name = m[2];
414
+ var extending = m[4] || "$m.Class";
415
+
416
+ tokens.consume(m[0].length-1);
417
+
418
+ var content = new $c.ClassContentParser();
419
+ content.parse(tokens);
420
+
421
+ this.out = [ "var ", name, " = " + extending + ".extend(function(KLASS, OO)", content, ");" ];
422
+ });
423
+ });
424
+
425
+ RootParser.extend('ModuleParser', function(KLASS, OO){
426
+ // private closure
427
+
428
+ var REGEX = Tokens.regex("<MODULE> <CLASSNAME><LCURLY>");
429
+
430
+
431
+ OO.addMember("parse",function (tokens) {
432
+ var m = tokens.match(REGEX);
433
+ var name = m[2];
434
+ tokens.consume(m[0].length-1);
435
+
436
+ var content = new $c.ClassContentParser();
437
+ content.parse(tokens);
438
+
439
+ this.out = [ "var ", name, " = $m.Module.extend(function(KLASS, OO)", content, ");" ];
440
+ });
441
+ });
442
+
443
+ RootParser.extend('CurlyParser', function(KLASS, OO){
444
+ OO.addMember("initialize",function (chop) {
445
+ this.chop = chop;
446
+ this.$super();
447
+ });
448
+
449
+ OO.addMember("handleToken",function (token, tokens) {
450
+ if (this.curly === undefined) this.curly = 0;
451
+ if (token[0] == TYPES.RCURLY) {
452
+ this.curly--;
453
+ } else if (token[0] == TYPES.LCURLY) {
454
+ this.curly++;
455
+ }
456
+
457
+ this.$super(token, tokens);
458
+ if (this.curly == 0) this.finished = true;
459
+ });
460
+
461
+ OO.addMember("endParse",function (tokens) {
462
+ if (this.chop) {
463
+ this.out.pop();
464
+ this.out.shift();
465
+ }
466
+ });
467
+ });
468
+
469
+ var CurlyParser = $c.CurlyParser;
470
+
471
+ CurlyParser.extend('ClassContentParser', function(KLASS, OO){
472
+ OO.addMember("getHandler",function (token) {
473
+ switch(token[0]) {
474
+ case TYPES.VAR: return "MemberParser";
475
+ case TYPES.FUNCTION: return "MethodParser";
476
+ case TYPES.PRIVATE: return "PrivateParser";
477
+ case TYPES.INCLUDE: return "IncludeParser";
478
+ }
479
+ });
480
+
481
+ });
482
+
483
+ RootParser.extend('LineParser', function(KLASS, OO){
484
+ OO.addMember("handleToken",function (token, tokens) {
485
+ this.$super(token, tokens);
486
+ if (token[0] == TYPES.SEMICOLON) {
487
+ this.finished = true;
488
+ }
489
+ });
490
+ });
491
+
492
+ CurlyParser.extend('PrivateParser', function(KLASS, OO){
493
+ // private closure
494
+
495
+ var REGEX = Tokens.regex("<PRIVATE>\\s*");
496
+
497
+
498
+ OO.addMember("startParse",function (tokens) {
499
+ var m = tokens.match(REGEX);
500
+ tokens.consume(m[0].length);
501
+ });
502
+
503
+ OO.addMember("endParse",function (tokens) {
504
+ this.out.pop();
505
+ this.out.shift();
506
+ });
507
+ });
508
+
509
+
510
+ RootParser.extend('IStringParser', function(KLASS, OO){
511
+ // private closure
512
+
513
+ var BEGIN = Tokens.regex("<ISTRING_START>");
514
+
515
+
516
+ OO.addMember("parse",function (tokens) {
517
+ var m = tokens.match(BEGIN);
518
+ tokens.consume(m[0].length);
519
+ this.out.push('"');
520
+
521
+ while (1) {
522
+ var m = tokens.match(/^((?:\\.|.)*?)(#\{|})/);
523
+ var str = m[1];
524
+ var len = m[0].length;
525
+ str.replace(/"/, '\\"');
526
+
527
+ if (m[2] == '#{') {
528
+ this.out.push(str+'"+(');
529
+ tokens.consume(len-1);
530
+ this.parseMiddle(tokens);
531
+ this.out.push(')+"');
532
+ }
533
+
534
+ else if (m[2] == '}') {
535
+ this.out.push(str);
536
+ this.out.push('"');
537
+ tokens.consume(len);
538
+ return;
539
+ }
540
+ }
541
+ });
542
+
543
+ OO.addMember("parseMiddle",function (tokens) {
544
+ var parser = new CurlyParser(true);
545
+ parser.parse(tokens);
546
+ this.out.push(parser);
547
+ });
548
+ });
549
+
550
+ RootParser.extend('MemberParser', function(KLASS, OO){
551
+ // private closure
552
+
553
+ var REGEX = Tokens.regex("var <IDENT>\\s*=\\s*?");
554
+
555
+
556
+ OO.addMember("parse",function (tokens) {
557
+ var m = tokens.str.match(REGEX);
558
+ this.name = m[1];
559
+ tokens.consume(m[0].length);
560
+
561
+ var parser = new $c.LineParser();
562
+ parser.parse(tokens);
563
+ parser.chop();
564
+
565
+ this.out = [ "OO.addMember(", JSON.stringify(this.name), ",", parser, ");" ];
566
+ });
567
+ });
568
+
569
+ RootParser.extend('IncludeParser', function(KLASS, OO){
570
+ // private closure
571
+
572
+ var REGEX = Tokens.regex("<INCLUDE> <CLASSNAME><SEMICOLON>");
573
+
574
+
575
+ OO.addMember("parse",function (tokens) {
576
+ var m = tokens.match(REGEX);
577
+ tokens.consume(m[0].length);
578
+ this.out = [ 'OO.include(', m[2], ');' ];
579
+ });
580
+ });
581
+
582
+ RootParser.extend('HereDocParser', function(KLASS, OO){
583
+ // private closure
584
+
585
+ var REGEX = Tokens.regex("<HEREDOC>");
586
+
587
+
588
+ OO.addMember("parse",function (tokens) {
589
+ var beginning = tokens.match(/^<<(\w+)\s*([;\)])*\n/);
590
+ tokens.consume(beginning[0].length);
591
+
592
+ var spacing = tokens.match(/^(\s*)/);
593
+ var regexSub = new RegExp("^" + (spacing[0] || ''), "mg");
594
+
595
+
596
+ var strMatch = tokens.match(new RegExp("^([\\s\\S]*?)\\n\\s*" + beginning[1] + "\\s*\\n"));
597
+ var toParse = strMatch[1] || '';
598
+
599
+ toParse = toParse.replace(regexSub, '');
600
+ toParse = toParse.replace("\n", "\\n");
601
+
602
+ var string = $m.parse('%{' + toParse + '}');
603
+ tokens.consume(strMatch[0] ? strMatch[0].length : 0);
604
+
605
+ this.out = [ string, beginning[2] || ';' ];
606
+ });
607
+ });
608
+
609
+ RootParser.extend('MethodParser', function(KLASS, OO){
610
+ // private closure
611
+
612
+ var REGEX = Tokens.regex("<FUNCTION> <IDENT><ARGS><SPACE>");
613
+
614
+
615
+ OO.addMember("parse",function (tokens) {
616
+ var m = tokens.str.match(REGEX);
617
+ tokens.consume(m[0].length);
618
+ this.name = m[2];
619
+ this.args = m[3];
620
+ this.body = new CurlyParser();
621
+ this.body.foo = true;
622
+ this.body.parse(tokens);
623
+
624
+ this.out = [ 'OO.addMember(', JSON.stringify(this.name), ', function', this.args, this.body, ');' ];
625
+ });
626
+ });
627
+
628
+ RootParser.extend('ShorthandFunctionParser', function(KLASS, OO){
629
+ // private closure
630
+
631
+ var ARGS_REGEX = Tokens.regex("<ARGS>\\s*");
632
+
633
+
634
+ OO.addMember("parse",function (tokens) {
635
+ tokens.consume(1);
636
+ var argsMatch = tokens.match(ARGS_REGEX);
637
+ var args = null;
638
+
639
+ if (argsMatch) {
640
+ args = argsMatch[0];
641
+ tokens.consume(argsMatch[0].length);
642
+ } else {
643
+ args = "($1,$2,$3)";
644
+ }
645
+
646
+ var body = new CurlyParser();
647
+ body.parse(tokens);
648
+ var semi = tokens.match(/^\s*[,;\)]/) ? '' : ';';
649
+
650
+ this.out = [ 'function', args, body, semi ];
651
+ });
652
+ });
653
+
654
+ RootParser.extend('CommentParser', function(KLASS, OO){
655
+ OO.addMember("parse",function (tokens) {
656
+ var m = tokens.match(/^\/\/.*?\n/);
657
+ if (m) {
658
+ tokens.consume(m[0].length);
659
+ this.out = [ m[0] ];
660
+ return;
661
+ }
662
+
663
+ var m2 = tokens.match(/^\/\*.*?\*\//);
664
+ if (m2) {
665
+ tokens.consume(m2[0].length);
666
+ this.out = [ m2[0] ];
667
+ return;
668
+ }
669
+ });
670
+ });
671
+
672
+ CurlyParser.extend('ForeachParser', function(KLASS, OO){
673
+ // private closure
674
+
675
+ var REGEX = Tokens.regex("<FOREACH><LBRACE><VAR> <IDENT>(?:**:**<IDENT>)? in (.*?)**<RBRACE>**{");
676
+
677
+
678
+ OO.addMember("startParse",function (tokens) {
679
+ var m = tokens.match(REGEX);
680
+ namespace = tokens.iterator++;
681
+
682
+ this.item = m[4];
683
+ this.iterator = m[5] || "_i_" + namespace;
684
+ this.list = m[6];
685
+
686
+ // TODO ugly, revisit this later
687
+ tokens.consume(m[0].length-1);
688
+ var declare = [ this.iterator + "=0", this.item + "=null", "_list_" + namespace + "=" + this.list, "_len_" + namespace + "=_list_.length" ].join(',');
689
+
690
+ var bool = "(" + this.item + "=" + "_list_" + namespace + "[" + this.iterator + "])||" + this.iterator + "<_len_" + namespace;
691
+
692
+ this.out = [ "for (", declare, ";", bool, ';', this.iterator + "++)" ];
693
+ });
694
+
695
+ OO.addMember("endParse",function (tokens) {
696
+ tokens.iterator--;
697
+ });
698
+
699
+ });
700
+
701
+ })();
702
+ FINISH
703
+ end
704
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mochiscript
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: 6
5
+ version: 0.4.0.pre1
6
+ platform: ruby
7
+ authors:
8
+ - Jeff Su
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-09-25 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Javascript Dessert
18
+ email:
19
+ - me@jeffsu.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - lib/mochiscript.rb
28
+ has_rdoc: true
29
+ homepage: ""
30
+ licenses: []
31
+
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">"
47
+ - !ruby/object:Gem::Version
48
+ version: 1.3.1
49
+ requirements: []
50
+
51
+ rubyforge_project: mochiscript
52
+ rubygems_version: 1.6.2
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: Javascript Dessert
56
+ test_files: []
57
+