Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

0.6.12

  • Loading branch information...
commit ce395cda7916a8d6b430ee1ec18216b7257f1e13 1 parent 1126931
@jeffsu authored
View
3  CHANGELOG
@@ -1,6 +1,7 @@
### 0.6.12
- * fixing bad merge
+ * allowing arbitrary mochiscript code in foreach braces
+ * a little bit better error reporting when there is a parse error
### 0.6.11
View
57 mochiscript-full.js
@@ -689,6 +689,7 @@ RootParser.extend("ClassParser", function(KLASS, OO){
});
});
+
RootParser.extend("ModuleParser", function(KLASS, OO){
var REGEX = Tokens.regex("<MODULE> <CLASSNAME><LCURLY>");
@@ -740,6 +741,39 @@ RootParser.extend("CurlyParser", function(KLASS, OO){
var CurlyParser = $c.CurlyParser;
+RootParser.extend("BraceParser", function(KLASS, OO){
+ OO.addMember("_TYPE", 'BraceParser');
+
+ OO.addMember("initialize", function(chop){var self=this;
+ this.chop = chop;
+ this.$super();
+ });
+
+ OO.addMember("handleToken", function(token, tokens){var self=this;
+ if (this.brace === undefined) this.brace = 0;
+ if (token[0] == TYPES.LBRACE) {
+ this.brace--;
+ } else if (token[0] == TYPES.RBRACE) {
+ this.brace++;
+ }
+
+ this.$super(token, tokens);
+
+ if (this.brace == 0) {
+ this.finished = true;
+ }
+ });
+
+ OO.addMember("endParse", function(tokens){var self=this;
+ if (this.chop) {
+ this.out.pop();
+ this.out.shift();
+ }
+ });
+});
+
+var BraceParser = $c.BraceParser;
+
CurlyParser.extend("ClassContentParser", function(KLASS, OO){
OO.addMember("getHandler", function(token){var self=this;
switch(token[0]) {
@@ -1074,19 +1108,28 @@ CurlyParser.extend("ForeachParser", function(KLASS, OO){
OO.addMember("_TYPE", 'Foreach');
- var REGEX = Tokens.regex("<FOREACH><LBRACE><VAR> <IDENT>(?:**:**<IDENT>)? in (.*?)**<RBRACE>**");
+ var REGEX = Tokens.regex("(<FOREACH>\\s*)<LBRACE>");
+ var REGEX_INNER = Tokens.regex("<LBRACE><VAR> <IDENT>(?:**:**<IDENT>)?\\s+in\\s+(.*)<RBRACE>");
OO.addMember("startParse", function(tokens){var self=this;
var m = tokens.match(REGEX);
- namespace = tokens.iterator++;
+ if (!m) return false;
+ tokens.consume(m[0].length-1);
- this.item = m[4];
- this.iterator = m[5] || "_i_" + namespace;
- this.list = m[6];
- // TODO ugly, revisit this later
- tokens.consume(m[0].length-1);
+ var content = new $c.BraceParser();
+ content.parse(tokens);
+
+ var mInner = content.toString().match(REGEX_INNER);
+ if (!mInner) return false;
+
+ var namespace = tokens.iterator++;
+
+ this.item = mInner[3];
+ this.iterator = mInner[4] || "_i_" + namespace;
+ this.list = mInner[5];
+
var declare = [ this.iterator + "=0", this.item + "=null", "_list_" + namespace + "=" + this.list, "_len_" + namespace + "=_list_" + namespace + ".length" ].join(',');
var bool = "(" + this.item + "=" + "_list_" + namespace + "[" + this.iterator + "])||" + this.iterator + "<_len_" + namespace;
View
57 platforms/gem/lib/mochiscript/core.rb
@@ -724,6 +724,7 @@ class Parser
});
});
+
RootParser.extend("ModuleParser", function(KLASS, OO){
var REGEX = Tokens.regex("<MODULE> <CLASSNAME><LCURLY>");
@@ -775,6 +776,39 @@ class Parser
var CurlyParser = $c.CurlyParser;
+RootParser.extend("BraceParser", function(KLASS, OO){
+ OO.addMember("_TYPE", 'BraceParser');
+
+ OO.addMember("initialize", function(chop){var self=this;
+ this.chop = chop;
+ this.$super();
+ });
+
+ OO.addMember("handleToken", function(token, tokens){var self=this;
+ if (this.brace === undefined) this.brace = 0;
+ if (token[0] == TYPES.LBRACE) {
+ this.brace--;
+ } else if (token[0] == TYPES.RBRACE) {
+ this.brace++;
+ }
+
+ this.$super(token, tokens);
+
+ if (this.brace == 0) {
+ this.finished = true;
+ }
+ });
+
+ OO.addMember("endParse", function(tokens){var self=this;
+ if (this.chop) {
+ this.out.pop();
+ this.out.shift();
+ }
+ });
+});
+
+var BraceParser = $c.BraceParser;
+
CurlyParser.extend("ClassContentParser", function(KLASS, OO){
OO.addMember("getHandler", function(token){var self=this;
switch(token[0]) {
@@ -1109,19 +1143,28 @@ class Parser
OO.addMember("_TYPE", 'Foreach');
- var REGEX = Tokens.regex("<FOREACH><LBRACE><VAR> <IDENT>(?:**:**<IDENT>)? in (.*?)**<RBRACE>**");
+ var REGEX = Tokens.regex("(<FOREACH>\\s*)<LBRACE>");
+ var REGEX_INNER = Tokens.regex("<LBRACE><VAR> <IDENT>(?:**:**<IDENT>)?\\s+in\\s+(.*)<RBRACE>");
OO.addMember("startParse", function(tokens){var self=this;
var m = tokens.match(REGEX);
- namespace = tokens.iterator++;
+ if (!m) return false;
+ tokens.consume(m[0].length-1);
- this.item = m[4];
- this.iterator = m[5] || "_i_" + namespace;
- this.list = m[6];
- // TODO ugly, revisit this later
- tokens.consume(m[0].length-1);
+ var content = new $c.BraceParser();
+ content.parse(tokens);
+
+ var mInner = content.toString().match(REGEX_INNER);
+ if (!mInner) return false;
+
+ var namespace = tokens.iterator++;
+
+ this.item = mInner[3];
+ this.iterator = mInner[4] || "_i_" + namespace;
+ this.list = mInner[5];
+
var declare = [ this.iterator + "=0", this.item + "=null", "_list_" + namespace + "=" + this.list, "_len_" + namespace + "=_list_" + namespace + ".length" ].join(',');
var bool = "(" + this.item + "=" + "_list_" + namespace + "[" + this.iterator + "])||" + this.iterator + "<_len_" + namespace;
View
76 platforms/npm/lib/mochiscript/mochiscript.js
@@ -723,6 +723,7 @@ RootParser.extend("ClassParser", function(KLASS, OO){
});
});
+
RootParser.extend("ModuleParser", function(KLASS, OO){
var REGEX = Tokens.regex("<MODULE> <CLASSNAME><LCURLY>");
@@ -774,6 +775,39 @@ RootParser.extend("CurlyParser", function(KLASS, OO){
var CurlyParser = $c.CurlyParser;
+RootParser.extend("BraceParser", function(KLASS, OO){
+ OO.addMember("_TYPE", 'BraceParser');
+
+ OO.addMember("initialize", function(chop){var self=this;
+ this.chop = chop;
+ this.$super();
+ });
+
+ OO.addMember("handleToken", function(token, tokens){var self=this;
+ if (this.brace === undefined) this.brace = 0;
+ if (token[0] == TYPES.LBRACE) {
+ this.brace--;
+ } else if (token[0] == TYPES.RBRACE) {
+ this.brace++;
+ }
+
+ this.$super(token, tokens);
+
+ if (this.brace == 0) {
+ this.finished = true;
+ }
+ });
+
+ OO.addMember("endParse", function(tokens){var self=this;
+ if (this.chop) {
+ this.out.pop();
+ this.out.shift();
+ }
+ });
+});
+
+var BraceParser = $c.BraceParser;
+
CurlyParser.extend("ClassContentParser", function(KLASS, OO){
OO.addMember("getHandler", function(token){var self=this;
switch(token[0]) {
@@ -1108,19 +1142,28 @@ CurlyParser.extend("ForeachParser", function(KLASS, OO){
OO.addMember("_TYPE", 'Foreach');
- var REGEX = Tokens.regex("<FOREACH><LBRACE><VAR> <IDENT>(?:**:**<IDENT>)? in (.*?)**<RBRACE>**");
+ var REGEX = Tokens.regex("(<FOREACH>\\s*)<LBRACE>");
+ var REGEX_INNER = Tokens.regex("<LBRACE><VAR> <IDENT>(?:**:**<IDENT>)?\\s+in\\s+(.*)<RBRACE>");
OO.addMember("startParse", function(tokens){var self=this;
var m = tokens.match(REGEX);
- namespace = tokens.iterator++;
+ if (!m) return false;
+ tokens.consume(m[0].length-1);
- this.item = m[4];
- this.iterator = m[5] || "_i_" + namespace;
- this.list = m[6];
- // TODO ugly, revisit this later
- tokens.consume(m[0].length-1);
+ var content = new $c.BraceParser();
+ content.parse(tokens);
+
+ var mInner = content.toString().match(REGEX_INNER);
+ if (!mInner) return false;
+
+ var namespace = tokens.iterator++;
+
+ this.item = mInner[3];
+ this.iterator = mInner[4] || "_i_" + namespace;
+ this.list = mInner[5];
+
var declare = [ this.iterator + "=0", this.item + "=null", "_list_" + namespace + "=" + this.list, "_len_" + namespace + "=_list_" + namespace + ".length" ].join(',');
var bool = "(" + this.item + "=" + "_list_" + namespace + "[" + this.iterator + "])||" + this.iterator + "<_len_" + namespace;
@@ -1224,10 +1267,23 @@ var requireScript = "var $m = require('mochiscript').mochi; $m.PUSH_ROOT(root);"
var endScript = "$m.POP_ROOT();";
if (require.extensions) {
require.extensions['.ms'] = function(module, filename) {
- return module._compile($m.parse(requireScript + fs.readFileSync(filename, 'utf8') + endScript), filename);
+ var content = fs.readFileSync(filename, 'utf8');
+ try {
+ var parsed = $m.parse(content);
+ } catch(e) {
+ console.log("Error parsing " + filename + "!");
+ throw e;
+ }
+
+ return module._compile(requireScript + parsed + endScript, filename);
};
} else if (require.registerExtension) {
- require.registerExtension('.ms', function(content) {
- return $m.parse(requireScript + content);
+ require.registerExtension('.ms', function(content, filename) {
+ try {
+ return $m.parse(requireScript + content + endScript);
+ } catch(e) {
+ console.warn("Error parsing mochiscript.");
+ throw e;
+ }
});
}
View
57 platforms/www/mochiscript-full.js
@@ -689,6 +689,7 @@ RootParser.extend("ClassParser", function(KLASS, OO){
});
});
+
RootParser.extend("ModuleParser", function(KLASS, OO){
var REGEX = Tokens.regex("<MODULE> <CLASSNAME><LCURLY>");
@@ -740,6 +741,39 @@ RootParser.extend("CurlyParser", function(KLASS, OO){
var CurlyParser = $c.CurlyParser;
+RootParser.extend("BraceParser", function(KLASS, OO){
+ OO.addMember("_TYPE", 'BraceParser');
+
+ OO.addMember("initialize", function(chop){var self=this;
+ this.chop = chop;
+ this.$super();
+ });
+
+ OO.addMember("handleToken", function(token, tokens){var self=this;
+ if (this.brace === undefined) this.brace = 0;
+ if (token[0] == TYPES.LBRACE) {
+ this.brace--;
+ } else if (token[0] == TYPES.RBRACE) {
+ this.brace++;
+ }
+
+ this.$super(token, tokens);
+
+ if (this.brace == 0) {
+ this.finished = true;
+ }
+ });
+
+ OO.addMember("endParse", function(tokens){var self=this;
+ if (this.chop) {
+ this.out.pop();
+ this.out.shift();
+ }
+ });
+});
+
+var BraceParser = $c.BraceParser;
+
CurlyParser.extend("ClassContentParser", function(KLASS, OO){
OO.addMember("getHandler", function(token){var self=this;
switch(token[0]) {
@@ -1074,19 +1108,28 @@ CurlyParser.extend("ForeachParser", function(KLASS, OO){
OO.addMember("_TYPE", 'Foreach');
- var REGEX = Tokens.regex("<FOREACH><LBRACE><VAR> <IDENT>(?:**:**<IDENT>)? in (.*?)**<RBRACE>**");
+ var REGEX = Tokens.regex("(<FOREACH>\\s*)<LBRACE>");
+ var REGEX_INNER = Tokens.regex("<LBRACE><VAR> <IDENT>(?:**:**<IDENT>)?\\s+in\\s+(.*)<RBRACE>");
OO.addMember("startParse", function(tokens){var self=this;
var m = tokens.match(REGEX);
- namespace = tokens.iterator++;
+ if (!m) return false;
+ tokens.consume(m[0].length-1);
- this.item = m[4];
- this.iterator = m[5] || "_i_" + namespace;
- this.list = m[6];
- // TODO ugly, revisit this later
- tokens.consume(m[0].length-1);
+ var content = new $c.BraceParser();
+ content.parse(tokens);
+
+ var mInner = content.toString().match(REGEX_INNER);
+ if (!mInner) return false;
+
+ var namespace = tokens.iterator++;
+
+ this.item = mInner[3];
+ this.iterator = mInner[4] || "_i_" + namespace;
+ this.list = mInner[5];
+
var declare = [ this.iterator + "=0", this.item + "=null", "_list_" + namespace + "=" + this.list, "_len_" + namespace + "=_list_" + namespace + ".length" ].join(',');
var bool = "(" + this.item + "=" + "_list_" + namespace + "[" + this.iterator + "])||" + this.iterator + "<_len_" + namespace;
View
57 src/parsers.ms
@@ -164,6 +164,7 @@ class ClassParser extends RootParser {
}
}
+
class ModuleParser extends RootParser {
private {
var REGEX = Tokens.regex("<MODULE> <CLASSNAME><LCURLY>");
@@ -215,6 +216,39 @@ class CurlyParser extends RootParser {
var CurlyParser = $c.CurlyParser;
+class BraceParser extends RootParser {
+ var _TYPE = 'BraceParser';
+
+ function initialize(chop) {
+ this.chop = chop;
+ this.$super();
+ }
+
+ function handleToken(token, tokens) {
+ if (this.brace === undefined) this.brace = 0;
+ if (token[0] == TYPES.LBRACE) {
+ this.brace--;
+ } else if (token[0] == TYPES.RBRACE) {
+ this.brace++;
+ }
+
+ this.$super(token, tokens);
+
+ if (this.brace == 0) {
+ this.finished = true;
+ }
+ }
+
+ function endParse(tokens) {
+ if (this.chop) {
+ this.out.pop();
+ this.out.shift();
+ }
+ }
+}
+
+var BraceParser = $c.BraceParser;
+
class ClassContentParser extends CurlyParser {
function getHandler(token) {
switch(token[0]) {
@@ -549,19 +583,28 @@ class ForeachParser extends CurlyParser {
var _TYPE = 'Foreach';
private {
- var REGEX = Tokens.regex("<FOREACH><LBRACE><VAR> <IDENT>(?:**:**<IDENT>)? in (.*?)**<RBRACE>**");
+ var REGEX = Tokens.regex("(<FOREACH>\\s*)<LBRACE>");
+ var REGEX_INNER = Tokens.regex("<LBRACE><VAR> <IDENT>(?:**:**<IDENT>)?\\s+in\\s+(.*)<RBRACE>");
}
function startParse(tokens) {
var m = tokens.match(REGEX);
- namespace = tokens.iterator++;
+ if (!m) return false;
+ tokens.consume(m[0].length-1);
- this.item = m[4];
- this.iterator = m[5] || "_i_" + namespace;
- this.list = m[6];
- // TODO ugly, revisit this later
- tokens.consume(m[0].length-1);
+ var content = new $c.BraceParser();
+ content.parse(tokens);
+
+ var mInner = content.toString().match(REGEX_INNER);
+ if (!mInner) return false;
+
+ var namespace = tokens.iterator++;
+
+ this.item = mInner[3];
+ this.iterator = mInner[4] || "_i_" + namespace;
+ this.list = mInner[5];
+
var declare = [ this.iterator + "=0", this.item + "=null", "_list_" + namespace + "=" + this.list, "_len_" + namespace + "=_list_" + namespace + ".length" ].join(',');
var bool = "(" + this.item + "=" + "_list_" + namespace + "[" + this.iterator + "])||" + this.iterator + "<_len_" + namespace;
View
19 src/platforms/npm/lib/mochiscript/mochiscript.js.erb
@@ -92,10 +92,23 @@ var requireScript = "var $m = require('mochiscript').mochi; $m.PUSH_ROOT(root);"
var endScript = "$m.POP_ROOT();";
if (require.extensions) {
require.extensions['.ms'] = function(module, filename) {
- return module._compile($m.parse(requireScript + fs.readFileSync(filename, 'utf8') + endScript), filename);
+ var content = fs.readFileSync(filename, 'utf8');
+ try {
+ var parsed = $m.parse(content);
+ } catch(e) {
+ console.log("Error parsing " + filename + "!");
+ throw e;
+ }
+
+ return module._compile(requireScript + parsed + endScript, filename);
};
} else if (require.registerExtension) {
- require.registerExtension('.ms', function(content) {
- return $m.parse(requireScript + content);
+ require.registerExtension('.ms', function(content, filename) {
+ try {
+ return $m.parse(requireScript + content + endScript);
+ } catch(e) {
+ console.warn("Error parsing mochiscript.");
+ throw e;
+ }
});
}
View
7 tests/foreach-bug1.ms
@@ -0,0 +1,7 @@
+
+var foo = { hello: #{ => [ 1, 2, 3 ] } };
+var val = null;
+
+foreach (var i in foo.hello()) val = i;
+
+$m.test(#{ $1.eq(val, 3) });
Please sign in to comment.
Something went wrong with that request. Please try again.