Multiple assignment done.

This commit is contained in:
Onoshko Dan 2014-05-16 19:27:51 +07:00
parent af6f8ebf7b
commit dd22a18eb0
6 changed files with 971 additions and 110 deletions

View File

@ -79,7 +79,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
..info += ", student"; ..info += ", student";
- `a > b > c` - `a > b > c`, status: done
if( 0 < x < 100 ) console.log("x E (0; 100)"); if( 0 < x < 100 ) console.log("x E (0; 100)");
@ -112,18 +112,6 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
case 35: 'hot'; case 35: 'hot';
}; };
- `with` scoping, status: it need??
with(document.body.querySelectorAll('ul').childNodes){
var txt = 'text';
forEach((li){
li.innerHTML = txt;
});
}
console.log(txt); // undefined
## Vars ## Vars
- declaration with type, status: done, only declaration - declaration with type, status: done, only declaration
@ -133,10 +121,10 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
Object obj = {}; Object obj = {};
String str = ""; String str = "";
- multiple assignment - multiple assignment, status: done
[a, b, c] = [b, c, a]; [a, b, c] = [b, c, a];
{poet: {String name, address: [street, city]}} = futurists; var {poet: {String name, address: [street, city]}} = futurists;
[a, ..., b] = someArray; [a, ..., b] = someArray;
@ -325,5 +313,5 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
### Statistic ### Statistic
- 34 features ( without classes ) - 33 features ( without classes )
- 27 done - 29 done

View File

@ -398,7 +398,7 @@ Cola.AST_Namedarg = Cola.DEFNODE("Namedarg", "start end name value", {
} }
}, Cola.AST_SymbolRef); }, Cola.AST_SymbolRef);
Cola.AST_Defarg = Cola.DEFNODE("Defarg", "start end name type argtype defval", { Cola.AST_ArgDef = Cola.DEFNODE("ArgDef", "start end name type argtype defval", {
$documentation: "A function argument expression", $documentation: "A function argument expression",
$propdoc: { $propdoc: {
type: "Data type", type: "Data type",
@ -563,7 +563,7 @@ Cola.AST_Const = Cola.DEFNODE("Const", null, {
$documentation: "A `const` statement" $documentation: "A `const` statement"
}, Cola.AST_Definitions); }, Cola.AST_Definitions);
Cola.AST_VarDef = Cola.DEFNODE("VarDef", "name value", { Cola.AST_VarDef = Cola.DEFNODE("VarDef", "name value type", {
$documentation: "A variable declaration; only appears in a AST_Definitions node", $documentation: "A variable declaration; only appears in a AST_Definitions node",
$propdoc: { $propdoc: {
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable", name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
@ -759,7 +759,7 @@ Cola.AST_Assign = Cola.DEFNODE("Assign", null, {
/* -----[ LITERALS ]----- */ /* -----[ LITERALS ]----- */
Cola.AST_Array = Cola.DEFNODE("Array", "elements", { Cola.AST_Array = Cola.DEFNODE("Array", "elements template vardef", {
$documentation: "An array literal", $documentation: "An array literal",
$propdoc: { $propdoc: {
elements: "[AST_Node*] array of elements" elements: "[AST_Node*] array of elements"
@ -773,7 +773,11 @@ Cola.AST_Array = Cola.DEFNODE("Array", "elements", {
} }
}); });
Cola.AST_ArrayRange = Cola.DEFNODE("ArrayRange", "from to", { Cola.AST_ArrayTemplate = Cola.DEFNODE("ArrayTemplate", null, {
$documentation: "Array assignment template.",
}, Cola.AST_Array);
Cola.AST_ArrayRange = Cola.DEFNODE("ArrayRange", "from to triple", {
$documentation: "An array range.", $documentation: "An array range.",
$propdoc: { $propdoc: {
from: "[AST_Node] range from", from: "[AST_Node] range from",
@ -787,7 +791,7 @@ Cola.AST_ArrayRange = Cola.DEFNODE("ArrayRange", "from to", {
} }
}); });
Cola.AST_Object = Cola.DEFNODE("Object", "properties", { Cola.AST_Object = Cola.DEFNODE("Object", "properties template vardef", {
$documentation: "An object literal", $documentation: "An object literal",
$propdoc: { $propdoc: {
properties: "[AST_ObjectProperty*] array of properties" properties: "[AST_ObjectProperty*] array of properties"
@ -801,7 +805,11 @@ Cola.AST_Object = Cola.DEFNODE("Object", "properties", {
} }
}); });
Cola.AST_ObjectProperty = Cola.DEFNODE("ObjectProperty", "key value", { Cola.AST_ObjectTemplate = Cola.DEFNODE("ObjectTemplate", null, {
$documentation: "Object assignment template.",
}, Cola.AST_Object);
Cola.AST_ObjectProperty = Cola.DEFNODE("ObjectProperty", "key value type", {
$documentation: "Base class for literal object properties", $documentation: "Base class for literal object properties",
$propdoc: { $propdoc: {
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.", key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",

View File

@ -140,6 +140,8 @@ Cola.OPERATORS.push('void');
Cola.OPERATORS = Cola.makePredicate(Cola.OPERATORS); Cola.OPERATORS = Cola.makePredicate(Cola.OPERATORS);
Cola.COMPARISON = Cola.makePredicate("< > <= >= == === != !==");
Cola.WHITESPACE_CHARS = Cola.makePredicate(Cola.characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000")); Cola.WHITESPACE_CHARS = Cola.makePredicate(Cola.characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000"));
Cola.PUNC_BEFORE_EXPRESSION = Cola.makePredicate(Cola.characters("[{(,.;:")); Cola.PUNC_BEFORE_EXPRESSION = Cola.makePredicate(Cola.characters("[{(,.;:"));
@ -256,7 +258,8 @@ Cola.Tokenizer = function ($TEXT, filename, is_js, html5_comments) {
regex_allowed : false, regex_allowed : false,
comments_before : [] comments_before : []
}; };
this.dumps = {}; this.dumps = [];
this.dumpi = -1;
if(!is_js) this.S.string = { if(!is_js) this.S.string = {
at : [ new Cola.Tokenizer.StringInfo() ], at : [ new Cola.Tokenizer.StringInfo() ],
@ -301,11 +304,13 @@ Cola.Tokenizer.with_eof_error = function (eof_error, cont) {
}; };
Cola.Tokenizer.prototype.dumpS = function () { Cola.Tokenizer.prototype.dumpS = function () {
this.dumps = Cola.clone(this.S); this.dumps[++this.dumpi] = Cola.clone(this.S);
}; };
Cola.Tokenizer.prototype.restoreS = function () { Cola.Tokenizer.prototype.restoreS = function () {
this.S = this.dumps; if(this.dumpi == -1) return;
this.S = this.dumps[this.dumpi];
delete this.dumps[this.dumpi--];
}; };
Cola.Tokenizer.prototype.peek = function (offset) { return this.S.text.charAt(this.S.pos + (offset ? offset : 0)); }; Cola.Tokenizer.prototype.peek = function (offset) { return this.S.text.charAt(this.S.pos + (offset ? offset : 0)); };
@ -791,11 +796,10 @@ Cola.cPRECEDENCE = Cola.mergeTokens(
["^"], ["^"],
["&"], ["&"],
["==", "===", "!=", "!=="], ["==", "===", "!=", "!=="],
["<", ">", "<=", ">=", "in", "instanceof"], ["<", ">", "<=", ">=", "in", "instanceof", "is", "isnt"],
[">>", "<<", ">>>"], [">>", "<<", ">>>"],
["+", "-"], ["+", "-"],
["*", "/", "%"], ["*", "/", "%", "**", "%%"]
["is", "isnt", "**", "%%"]
], ],
{} {}
); );
@ -837,7 +841,8 @@ Cola.Parser = function ($TEXT, options) {
}; };
this.S.input.context = function(){ return _this.tokenizer.context() }; this.S.input.context = function(){ return _this.tokenizer.context() };
this.S.token = this.next(); this.S.token = this.next();
this.dumps = {}; this.dumps = [];
this.dumpi = -1;
if(this.is_js){ if(this.is_js){
this.UNARY_PREFIX = Cola.UNARY_PREFIX; this.UNARY_PREFIX = Cola.UNARY_PREFIX;
@ -877,13 +882,15 @@ Cola.Parser.prototype.parse = function () {
}; };
Cola.Parser.prototype.dumpS = function () { Cola.Parser.prototype.dumpS = function () {
this.dumps = Cola.clone(this.S); this.dumps[++this.dumpi] = Cola.clone(this.S);
this.tokenizer.dumpS(); this.tokenizer.dumpS();
}; };
Cola.Parser.prototype.restoreS = function () { Cola.Parser.prototype.restoreS = function () {
if(this.dumpi == -1) return;
this.tokenizer.restoreS(); this.tokenizer.restoreS();
this.S = this.dumps; this.S = this.dumps[this.dumpi];
delete this.dumps[this.dumpi--];
}; };
Cola.Parser.prototype.next_until = function (until) { Cola.Parser.prototype.next_until = function (until) {
@ -900,6 +907,10 @@ Cola.Parser.prototype.is = function (type, value) {
Cola.Parser.prototype.peek = function () { return this.S.peeked || (this.S.peeked = this.S.input()); }; Cola.Parser.prototype.peek = function () { return this.S.peeked || (this.S.peeked = this.S.input()); };
Cola.Parser.prototype.next_is = function (type, value) {
return Cola.is_token(this.peek(), type, value);
};
Cola.Parser.prototype.next = function () { Cola.Parser.prototype.next = function () {
this.S.prev = this.S.token; this.S.prev = this.S.token;
if (this.S.peeked) { if (this.S.peeked) {
@ -968,7 +979,7 @@ Cola.Parser.prototype.parenthesised = function () {
Cola.Parser.embed_tokens = function (parser) { Cola.Parser.embed_tokens = function (parser) {
return function() { return function() {
var start = this.S.token; var start = this.S.token;
var expr = parser.call(this); var expr = parser.apply(this, arguments);
var end = this.prev(); var end = this.prev();
expr.start = start; expr.start = start;
expr.end = end; expr.end = end;
@ -1000,9 +1011,9 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
return this.simple_statement(); return this.simple_statement();
case "name": case "name":
if(!this.is_js && Cola.is_token(this.peek(), "name")){ if(!this.is_js && this.next_is("name")){
type = this.S.token.value, this.next(); type = this.S.token.value, this.next();
if(Cola.is_token(this.peek(), "punc", "(")) return this.function_(Cola.AST_Defun, type); if(this.next_is("punc", "(")) return this.function_(Cola.AST_Defun, type);
return tmp = this.var_(false, type), this.semicolon(), tmp; return tmp = this.var_(false, type), this.semicolon(), tmp;
} }
@ -1026,18 +1037,31 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
if(isfun) return this.function_(Cola.AST_Defun); if(isfun) return this.function_(Cola.AST_Defun);
} }
return Cola.is_token(this.peek(), "punc", ":") return this.next_is("punc", ":")
? this.labeled_statement() ? this.labeled_statement()
: this.simple_statement(); : this.simple_statement();
case "punc": case "punc":
switch (this.S.token.value) { switch (this.S.token.value) {
case "{": case "{":
this.dumpS();
var balance = 0, is_object = false;
this.next_until(function(){
if(_this.is('punc', '{')) balance++;
else if(_this.is('punc', '}')) balance--;
return balance == 0 || _this.is('eof');
});
is_object = this.next_is("operator");
this.restoreS();
if (is_object) return this.simple_statement();
return new Cola.AST_BlockStatement({ return new Cola.AST_BlockStatement({
start : this.S.token, start : this.S.token,
body : this.block_(), body : this.block_(),
end : this.prev() end : this.prev()
}); });
case "[": case "[":
case "(": case "(":
return this.simple_statement(); return this.simple_statement();
@ -1241,7 +1265,7 @@ Cola.Parser.prototype.as_funcarg = function(splatedexist) {
} }
} }
return new Cola.AST_Defarg({ return new Cola.AST_ArgDef({
name : name, name : name,
type : argtype == "splated" ? "Array" : type == name ? "dynamic" : type.name, type : argtype == "splated" ? "Array" : type == name ? "dynamic" : type.name,
argtype : argtype, argtype : argtype,
@ -1392,13 +1416,20 @@ Cola.Parser.prototype.try_ = function () {
}); });
}; };
Cola.Parser.prototype.vardefs = function (no_in, in_const) { Cola.Parser.prototype.vardefs = function (no_in, in_const, type) {
var a = []; var a = [], was_template = false;
for (;;) { for (;;) {
was_template = false;
a.push(new Cola.AST_VarDef({ a.push(new Cola.AST_VarDef({
start : this.S.token, start : this.S.token,
name : this.as_symbol(in_const ? Cola.AST_SymbolConst : Cola.AST_SymbolVar), type : type,
value : this.is("operator", "=") ? (this.next(), this.expression(false, no_in)) : null, name : (function(_this){
was_template = !_this.is_js && ( _this.is("punc","[") || _this.is("punc","{") );
if (!_this.is_js && _this.is("punc","[")) return _this.array_(true, true);
if (!_this.is_js && _this.is("punc","{")) return _this.object_(true, true);
return _this.as_symbol(in_const ? Cola.AST_SymbolConst : Cola.AST_SymbolVar);
})(this),
value : this.is("operator", "=") ? (this.next(), this.expression(false, no_in)) : ( was_template ? this.expect_token("operator","=") : null ),
end : this.prev() end : this.prev()
})); }));
if (!this.is("punc", ",")) if (!this.is("punc", ","))
@ -1412,7 +1443,7 @@ Cola.Parser.prototype.var_ = function(no_in, type) {
!type && (type = "dynamic"); !type && (type = "dynamic");
return new Cola.AST_Var({ return new Cola.AST_Var({
start : this.prev(), start : this.prev(),
definitions : this.vardefs(no_in, false), definitions : this.vardefs(no_in, false, type),
type : type, type : type,
end : this.prev() end : this.prev()
}); });
@ -1577,7 +1608,7 @@ Cola.Parser.prototype.expr_atom = function(allow_calls) {
this.unexpected(); this.unexpected();
} }
if (!this.is_js && this.is("name")) { if (!this.is_js && this.is("name")) {
if(Cola.is_token(this.peek(), "name")){ if(this.next_is("name")){
type = this.S.token.value, this.next(); type = this.S.token.value, this.next();
return this.function_(Cola.AST_Defun, type); return this.function_(Cola.AST_Defun, type);
} }
@ -1643,32 +1674,107 @@ Cola.Parser.prototype.expr_list = function (closing, allow_trailing_comma, allow
return a; return a;
}; };
Cola.Parser.prototype.array_ = Cola.Parser.embed_tokens(function() { Cola.Parser.prototype.array_ = Cola.Parser.embed_tokens(function(is_template, is_var) {
this.expect("["); this.expect("[");
if(!this.is_js && !this.is("punc","]")){ if(!this.is_js && !this.is("punc","]") && !this.is("punc",",") && !(this.is("name") && this.next_is("name"))){
this.dumpS(); this.dumpS();
var tmp, from = this.expression(true, false, true); var tmp, from = this.expression(false, false, true), triple;
if(this.is("punc","..")){ if((this.is("punc","..") || this.is("punc","...")) && !this.next_is("punc", ",") && !this.next_is("punc", "]")){
triple = this.is("punc","...");
this.next(); this.next();
return new Cola.AST_ArrayRange({ return new Cola.AST_ArrayRange({
from : from, from : from,
to : (tmp = this.expression(true, false, true), this.expect("]"), tmp), to : (tmp = this.expression(true, false, true), this.expect("]"), tmp),
start : from.start, triple : triple,
end : this.prev() start : from.start,
end : this.prev()
}); });
} }
this.restoreS(); this.restoreS();
} }
return new Cola.AST_Array({ if(this.is_js) return new Cola.AST_Array({
elements: this.expr_list("]", !this.options.strict, true) elements: this.expr_list("]", !this.options.strict, true)
}); });
var is_array = ( is_template ? false : null ), vardef = false, first = true, a = [], val, skiped = false;
while (!this.is("punc", "]")) {
if (first) first = false; else this.expect(",");
if (this.is("punc", ",") || this.is("punc", "]")) {
a.push(new Cola.AST_Hole({ start: this.S.token, end: this.S.token }));
if (!this.options.strict && this.is("punc", "]")) break;
} else
if (this.is("punc", "...") && is_array !== true) {
if (skiped) this.unexpected();
this.next();
skiped = true;
is_array = false;
a.push(new Cola.AST_Noop());
} else
if (!is_var && this.is("name") && this.next_is("name") && !Cola.cKEYWORDS(this.peek().value)) {
if (is_array === true) this.unexpected();
is_array = false;
vardef = true;
a.push(new Cola.AST_VarDef({
start : this.S.token,
type : this.S.token.value,
name : (function(_this){
_this.next();
val = _this.as_symbol(Cola.AST_SymbolVar);
if (_this.is("punc", "...") && is_array !== true) {
if (skiped) _this.unexpected();
_this.next();
skiped = true;
is_array = false;
val.splated = true;
}
return val;
})(this),
value : null,
end : this.prev()
}))
} else {
if (is_array === false && this.is("punc","[")) val = this.array_(true, is_var);
else if (is_array === false && this.is("punc","{")) val = this.object_(true, is_var);
else val = this.expression(false);
if (val.vardef) vardef = true;
if (this.is("punc", "...") && is_array !== true) {
if (skiped) this.unexpected();
this.next();
skiped = true;
is_array = false;
val.splated = true;
}
if (val instanceof Cola.AST_ObjectTemplate || val instanceof Cola.AST_ArrayTemplate) {
if (is_array === true) this.unexpected();
is_array = false;
}
if (!(val instanceof Cola.AST_SymbolRef ||
val instanceof Cola.AST_ObjectTemplate || val instanceof Cola.AST_ArrayTemplate ||
!is_var && ( val instanceof Cola.AST_Dot || val instanceof Cola.AST_Sub ) ||
val instanceof Cola.AST_Object && val.template == true ||
val instanceof Cola.AST_Array && val.template == true)) {
if (is_array === false) this.unexpected();
is_array = true;
}
a.push(val);
}
}
this.next();
return is_array === true || is_array === null
? new Cola.AST_Array({ elements: a, template: is_array === null, vardef : vardef })
: new Cola.AST_ArrayTemplate({ elements: a, vardef : vardef });
}); });
Cola.Parser.prototype.object_ = Cola.Parser.embed_tokens(function() { Cola.Parser.prototype.object_ = Cola.Parser.embed_tokens(function(is_template, is_var) {
this.expect("{"); this.expect("{");
var first = true, a = []; var first = true, a = [], ptype, is_object = ( is_template ? false : null ), vardef = false, val;
while (!this.is("punc", "}")) { while (!this.is("punc", "}")) {
if (first) first = false; else this.expect(","); if (first) first = false; else this.expect(",");
if (!this.options.strict && this.is("punc", "}")) if (!this.options.strict && this.is("punc", "}"))
@ -1677,10 +1783,18 @@ Cola.Parser.prototype.object_ = Cola.Parser.embed_tokens(function() {
var start = this.S.token; var start = this.S.token;
var type = start.type; var type = start.type;
var name = this.as_property_name(); var name = this.as_property_name();
if (!this.is_js && !is_var && this.is("name") && !this.next_is("punc", "(") && !Cola.cKEYWORDS(name)) {
vardef = true;
ptype = name;
name = this.as_name();
} else ptype = false;
if (type == "name" && !this.is("punc", ":")) { if (type == "name" && !this.is("punc", ":")) {
if (name == "get") { if (name == "get") {
if (!this.is_js && is_object === false) this.unexpected();
is_object = true;
a.push(new Cola.AST_ObjectGetter({ a.push(new Cola.AST_ObjectGetter({
start : start, start : start,
type : ptype,
key : this.as_atom_node(), key : this.as_atom_node(),
value : this.function_(Cola.AST_Accessor), value : this.function_(Cola.AST_Accessor),
end : this.prev() end : this.prev()
@ -1688,8 +1802,11 @@ Cola.Parser.prototype.object_ = Cola.Parser.embed_tokens(function() {
continue; continue;
} }
if (name == "set") { if (name == "set") {
if (!this.is_js && is_object === false) this.unexpected();
is_object = true;
a.push(new Cola.AST_ObjectSetter({ a.push(new Cola.AST_ObjectSetter({
start : start, start : start,
type : ptype,
key : this.as_atom_node(), key : this.as_atom_node(),
value : this.function_(Cola.AST_Accessor), value : this.function_(Cola.AST_Accessor),
end : this.prev() end : this.prev()
@ -1697,16 +1814,47 @@ Cola.Parser.prototype.object_ = Cola.Parser.embed_tokens(function() {
continue; continue;
} }
} }
this.expect(":"); if (!this.is_js && !this.is("punc",":")) {
if (is_object === true) this.unexpected();
is_object = false;
val = new Cola.AST_Noop();
} else {
this.expect(":");
if (is_object === false && this.is("punc","[")) val = this.array_(true, is_var);
else if (is_object === false && this.is("punc","{")) val = this.object_(true, is_var);
else val = this.expression(false);
if (ptype && !(val instanceof Cola.AST_SymbolRef)) this.unexpected(val.start);
if (val.vardef) vardef = true;
if (val instanceof Cola.AST_ObjectTemplate || val instanceof Cola.AST_ArrayTemplate) {
if (is_object === true || ptype) this.unexpected();
is_object = false;
}
if (!(val instanceof Cola.AST_SymbolRef ||
val instanceof Cola.AST_ObjectTemplate || val instanceof Cola.AST_ArrayTemplate ||
!is_var && ( val instanceof Cola.AST_Dot || val instanceof Cola.AST_Sub ) ||
val instanceof Cola.AST_Object && val.template == true ||
val instanceof Cola.AST_Array && val.template == true)) {
if (is_object === false) this.unexpected();
is_object = true;
}
}
a.push(new Cola.AST_ObjectKeyVal({ a.push(new Cola.AST_ObjectKeyVal({
start : start, start : start,
type : ptype,
key : name, key : name,
value : this.expression(false), value : val,
end : this.prev() end : this.prev()
})); }));
} }
this.next(); this.next();
return new Cola.AST_Object({ properties: a });
return is_object === true || is_object === null
? new Cola.AST_Object({ properties: a, template: is_object === null, vardef : vardef })
: new Cola.AST_ObjectTemplate({ properties: a, vardef : vardef });
}); });
Cola.Parser.prototype.as_property_name = function () { Cola.Parser.prototype.as_property_name = function () {
@ -1772,19 +1920,22 @@ Cola.Parser.prototype.subscripts = function(expr, allow_calls) {
if (this.is("punc", "[")) { if (this.is("punc", "[")) {
this.next(); this.next();
var prop; var prop, triple;
if(this.is_js) prop = this.expression(true); if(this.is_js) prop = this.expression(true);
else if(this.is("punc","]")) prop = new Cola.AST_Noop(); else if(this.is("punc","]")) prop = new Cola.AST_Noop();
else { else {
prop = this.expression(true, false, true); if(this.is("punc","..") || this.is("punc","...")) prop = new Cola.AST_Number({ value : 0 });
else prop = this.expression(true, false, true);
this.dumpS(); this.dumpS();
if(this.is("punc","..")){ if(this.is("punc","..") || this.is("punc","...")){
triple = this.is("punc","...");
this.next(); this.next();
prop = new Cola.AST_ArrayRange({ prop = new Cola.AST_ArrayRange({
from : prop, from : prop,
to : this.expression(true, false, true), to : ( this.is("punc","]") ? new Cola.AST_Noop() : this.expression(true, false, true) ),
start : prop.start, triple : triple,
end : this.prev() start : prop.start,
end : this.prev()
}); });
} else this.restoreS(); } else this.restoreS();
} }
@ -1835,20 +1986,45 @@ Cola.Parser.prototype.make_unary = function (ctor, op, expr) {
return new ctor({ operator: op, expression: expr }); return new ctor({ operator: op, expression: expr });
}; };
Cola.Parser.prototype.expr_op = function(left, min_prec, no_in) { /*
var op = this.is("operator") ? this.S.token.value : null; a <= b < c == d
as
(((a <= b) && (b < c)) && c == d)
*/
Cola.Parser.prototype.expr_op = function(left, min_prec, no_in, is_comp, rightest) {
var op = this.is("operator") ? this.S.token.value : null, cop = Cola.COMPARISON(op);
if (op == "in" && no_in) op = null; if (op == "in" && no_in) op = null;
var prec = op != null ? this.PRECEDENCE[op] : null; var prec = op != null ? this.PRECEDENCE[op] : null;
if (!this.is_js && is_comp && cop) {
this.next();
var right = this.maybe_unary(true);
return this.expr_op(new Cola.AST_Binary({
start : left.start,
left : left,
operator : "&&",
right : new Cola.AST_Binary({
start : rightest.start,
left : rightest,
operator : op,
right : right,
end : right.end
}),
end : right.end
}), min_prec, no_in, true, right);
}
if (prec != null && prec > min_prec) { if (prec != null && prec > min_prec) {
this.next(); this.next();
var right = this.expr_op(this.maybe_unary(true), prec, no_in); var right = !this.is_js && cop ? this.maybe_unary(true) : this.expr_op(this.maybe_unary(true), prec, no_in);
return this.expr_op(new Cola.AST_Binary({ return this.expr_op(new Cola.AST_Binary({
start : left.start, start : left.start,
left : left, left : left,
operator : op, operator : op,
right : right, right : right,
end : right.end end : right.end
}), min_prec, no_in); }), min_prec, no_in, cop, right);
} }
return left; return left;
}; };
@ -1934,6 +2110,8 @@ Cola.Parser.prototype.expression = function(commas, no_in, in_dd) {
var expr = this.maybe_assign(no_in); var expr = this.maybe_assign(no_in);
if (!in_dd && !this.is_js && this.is("punc", "..")) return this.cascade(expr, start); if (!in_dd && !this.is_js && this.is("punc", "..")) return this.cascade(expr, start);
if (commas && this.is("punc", ",")) { if (commas && this.is("punc", ",")) {
if (expr instanceof Cola.AST_Assign && (expr.left instanceof Cola.AST_ArrayTemplate || expr.left instanceof Cola.AST_ObjectTemplate ||
(expr.left instanceof Cola.AST_Array || expr.left instanceof Cola.AST_Object) && expr.left.template) && expr.left.vardef) this.unexpected();
this.next(); this.next();
return new Cola.AST_Seq({ return new Cola.AST_Seq({
start : start, start : start,

View File

@ -122,7 +122,7 @@ Cola.$_cola_func_named_args.i = 9;
Cola.$_cola_func_set_named_args = function $_cola_func_set_named_args(_args){ Cola.$_cola_func_set_named_args = function $_cola_func_set_named_args(_args){
if(_args[_args.length - 1] instanceof $_cola_func_named_args){ if(_args[_args.length - 1] instanceof $_cola_func_named_args){
var nargs = [].pop.call(_args).$; var nargs = _args[_args.length - 1].$;
for(var i in nargs) if(nargs.hasOwnProperty(i)) for(var i in nargs) if(nargs.hasOwnProperty(i))
_args[i] = nargs[i]; _args[i] = nargs[i];
} }

View File

@ -51,7 +51,8 @@ Cola.TreeTransformer = function (before, after) {
this.before = before; this.before = before;
this.after = after; this.after = after;
} }
Cola.TreeTransformer.prototype = new Cola.TreeWalker;
Cola.TreeTransformer.prototype.__proto__ = new Cola.TreeWalker;
(function(undefined){ (function(undefined){
@ -79,7 +80,14 @@ Cola.TreeTransformer.prototype = new Cola.TreeWalker;
function do_list(list, tw) { function do_list(list, tw) {
return Cola.MAP(list, function(node){ return Cola.MAP(list, function(node){
return node.transform(tw, true);
var r = node.transform(tw, true);
r = r instanceof Array
? Cola.MAP.splice(r)
: r;
return r;
}); });
}; };

View File

@ -46,8 +46,8 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
main_event : 'DOMContentLoaded' main_event : 'DOMContentLoaded'
}); });
var $_cola_ast = Cola.parse(Cola.$_cola, { is_js : true}), $_cola_hash = {}, _this, var $_cola_ast = Cola.parse(Cola.$_cola, { is_js : true }), $_cola_hash = {}, _this,
tt = new Cola.TreeTransformer(function(node, descend){ tt = new Cola.TreeTransformer(function(node, descend, in_list){
var newNode, props = {}, parent = this.parent(); var newNode, props = {}, parent = this.parent();
node = node.clone(); node = node.clone();
@ -442,6 +442,13 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
}) })
}; };
if(node.left.property.to instanceof Cola.AST_Noop) props.args[2] = new Cola.AST_Number({ value : '9e9' });
else if(node.left.property.triple) props.args[2] = new Cola.AST_Binary({
operator : "-",
left : node.left.property.to,
right : new Cola.AST_Number({ value : 1 })
});
node = new Cola.AST_Call(props); node = new Cola.AST_Call(props);
} else } else
@ -459,16 +466,20 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
expression : node.expression expression : node.expression
}; };
props = { props = {
args : [node.property.from, new Cola.AST_Binary({ args : [node.property.from],
operator : "+",
left : node.property.to,
right : new Cola.AST_Number({ value : 1})
})],
start : node.start, start : node.start,
end : node.end, end : node.end,
expression : new Cola.AST_Dot(props) expression : new Cola.AST_Dot(props)
}; };
if(!node.property.triple && !(node.property.to instanceof Cola.AST_Noop)) props.args[1] = new Cola.AST_Binary({
operator : "+",
left : node.property.to,
right : new Cola.AST_Number({ value : 1 })
}); else
if(!(node.property.to instanceof Cola.AST_Noop)) props.args[1] = node.property.to;
node = new Cola.AST_Call(props); node = new Cola.AST_Call(props);
} else } else
@ -491,6 +502,12 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
}) })
}; };
if(node.triple) props.args[1] = new Cola.AST_Binary({
operator : "-",
left : node.to,
right : new Cola.AST_Number({ value : 1 })
});
node = new Cola.AST_Call(props); node = new Cola.AST_Call(props);
} else } else
@ -548,7 +565,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
function func(s){ function func(s){
$_cola_func_set_named_args(arguments); $_cola_func_set_named_args(arguments);
var $_cola_i, list = 3 <= arguments.length ? [].slice.call(arguments, 1, $_cola_i = arguments.length - 1) : ($_cola_i = 2, []), var $_cola_i, list = 3 <= arguments.length ? [].slice.call(arguments, 1, $_cola_i = arguments.length - 1) : ($_cola_i = 2, []),
b = arguments[$_cola_i+0] !== undefiend ? arguments[$_cola_i+0] : false, b = arguments[$_cola_i+0] !== undefined ? arguments[$_cola_i+0] : false,
n = arguments.n, n = arguments.n,
h = arguments.h !== undefined ? arguments.h : 123; h = arguments.h !== undefined ? arguments.h : 123;
} }
@ -591,12 +608,13 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if(val.argtype == "splated"){ if(val.argtype == "splated"){
aftersplated = 0; aftersplated = 0;
props.definitions.push(new Cola.AST_VarDef({ props.definitions.push(new Cola.AST_VarDef({
name : new Cola.AST_SymbolRef({ name : '$_cola_i' }), type : "int",
name : new Cola.AST_SymbolVar({ name : '$_cola_i' }),
value : null value : null
})); }));
props.definitions.push(new Cola.AST_VarDef({ props.definitions.push(new Cola.AST_VarDef({
name : splated.val.name, name : new Cola.AST_SymbolVar(splated.val.name),
value : new Cola.AST_Conditional({ value : new Cola.AST_Conditional({
condition : new Cola.AST_Binary({ condition : new Cola.AST_Binary({
operator : "<=", operator : "<=",
@ -645,7 +663,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
else else
if(val.defval instanceof Cola.AST_Noop) props.definitions.push(new Cola.AST_VarDef({ if(val.defval instanceof Cola.AST_Noop) props.definitions.push(new Cola.AST_VarDef({
name : val.name, name : new Cola.AST_SymbolVar(val.name),
value : new Cola.AST_Sub({ value : new Cola.AST_Sub({
expression : new Cola.AST_SymbolRef({ name : 'arguments' }), expression : new Cola.AST_SymbolRef({ name : 'arguments' }),
property : aftersplated == -1 property : aftersplated == -1
@ -658,7 +676,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
}) })
})); }));
else props.definitions.push(new Cola.AST_VarDef({ else props.definitions.push(new Cola.AST_VarDef({
name : val.name, name : new Cola.AST_SymbolVar(val.name),
value : new Cola.AST_Conditional({ value : new Cola.AST_Conditional({
condition : new Cola.AST_Binary({ condition : new Cola.AST_Binary({
operator : "!==", operator : "!==",
@ -691,14 +709,14 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
named.forEach(function(val, i){ named.forEach(function(val, i){
if(val.defval instanceof Cola.AST_Noop) props.definitions.push(new Cola.AST_VarDef({ if(val.defval instanceof Cola.AST_Noop) props.definitions.push(new Cola.AST_VarDef({
name : val.name, name : new Cola.AST_SymbolVar(val.name),
value : new Cola.AST_Dot({ value : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name : 'arguments' }), expression : new Cola.AST_SymbolRef({ name : 'arguments' }),
property : val.name.name property : val.name.name
}) })
})); }));
else props.definitions.push(new Cola.AST_VarDef({ else props.definitions.push(new Cola.AST_VarDef({
name : val.name, name : new Cola.AST_SymbolVar(val.name),
value : new Cola.AST_Conditional({ value : new Cola.AST_Conditional({
condition : new Cola.AST_Binary({ condition : new Cola.AST_Binary({
operator : "!==", operator : "!==",
@ -742,32 +760,37 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
; ;
to to
fix: this and arguments objects
(function($_cola_expr, arguments){
$_cola_expr[0] = yes;
$_cola_expr.foo = bar;
$_cola_expr.baz();
(function($_cola_ml_expr){ (function($_cola_expr, arguments){
$_cola_ml_expr[0] = yes; $_cola_expr.subfoo = no;
$_cola_ml_expr.foo = bar; $_cola_expr.subaz();
$_cola_ml_expr.baz();
(function($_cola_ml_expr){ return $_cola_expr;
$_cola_ml_expr.subfoo = no; }).call(this, $_cola_expr.sub, arguments);
$_cola_ml_expr.subaz();
return $_cola_ml_expr; return $_cola_expr;
})($_cola_ml_expr.sub); }).call(this, obj, arguments);
return $_cola_ml_expr;
})(obj);
*/ */
if(node instanceof Cola.AST_Cascade){ if(node instanceof Cola.AST_Cascade){
props = { props = {
type : "dynamic", type : "dynamic",
body : [], body : [],
argnames : [new Cola.AST_Defarg({ argnames : [new Cola.AST_ArgDef({
argtype : "positional", argtype : "positional",
type : "dynamic", type : "dynamic",
defval : new Cola.AST_Noop(), defval : new Cola.AST_Noop(),
name : new Cola.AST_SymbolFunarg({ name : "$_cola_ml_expr" }) name : new Cola.AST_SymbolFunarg({ name : "$_cola_expr", start : node.expression.start, end : node.expression.end })
}), new Cola.AST_ArgDef({
argtype : "positional",
type : "dynamic",
defval : new Cola.AST_Noop(),
name : new Cola.AST_SymbolFunarg({ name : "arguments", start : new Cola.AST_Token(), end : new Cola.AST_Token() })
})] })]
}; };
@ -790,13 +813,13 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if(expr instanceof Cola.AST_Array || expr instanceof Cola.AST_ArrayRange) Expr = new Cola.AST_Sub({ if(expr instanceof Cola.AST_Array || expr instanceof Cola.AST_ArrayRange) Expr = new Cola.AST_Sub({
start : Expr.start, start : Expr.start,
end : Expr.end, end : Expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }), expression : new Cola.AST_SymbolRef({ name : "$_cola_expr" }),
property : expr instanceof Cola.AST_ArrayRange ? expr : ( expr.elements.length == 0 ? new Cola.AST_Noop() : expr.elements[0] ) property : expr instanceof Cola.AST_ArrayRange ? expr : ( expr.elements.length == 0 ? new Cola.AST_Noop() : expr.elements[0] )
}); else }); else
if(expr instanceof Cola.AST_SymbolRef) Expr = new Cola.AST_Dot({ if(expr instanceof Cola.AST_SymbolRef) Expr = new Cola.AST_Dot({
start : Expr.start, start : Expr.start,
end : Expr.end, end : Expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }), expression : new Cola.AST_SymbolRef({ name : "$_cola_expr" }),
property : Expr.name property : Expr.name
}); });
} else { } else {
@ -804,14 +827,14 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
expr = new Cola.AST_Sub({ expr = new Cola.AST_Sub({
start : expr.start, start : expr.start,
end : expr.end, end : expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }), expression : new Cola.AST_SymbolRef({ name : "$_cola_expr" }),
property : expr instanceof Cola.AST_ArrayRange ? expr : ( expr.elements.length == 0 ? new Cola.AST_Noop() : expr.elements[0] ) property : expr instanceof Cola.AST_ArrayRange ? expr : ( expr.elements.length == 0 ? new Cola.AST_Noop() : expr.elements[0] )
}); });
else else
expr = new Cola.AST_Dot({ expr = new Cola.AST_Dot({
start : expr.start, start : expr.start,
end : expr.end, end : expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }), expression : new Cola.AST_SymbolRef({ name : "$_cola_expr" }),
property : expr.name property : expr.name
}); });
@ -829,17 +852,667 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
}); });
props.body.push(new Cola.AST_Return({ props.body.push(new Cola.AST_Return({
value : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }) value : new Cola.AST_SymbolRef({ name : "$_cola_expr" })
})); }));
props = {
expression : new Cola.AST_Function(props),
property : "call"
}
node = new Cola.AST_Call({ node = new Cola.AST_Call({
start : node.start, start : node.start,
end : node.end, end : node.end,
args : [node.expression], args : [new Cola.AST_SymbolRef({ name : "this" }), node.expression, new Cola.AST_SymbolRef({ name : "arguments" })],
expression : new Cola.AST_Function(props) expression : new Cola.AST_Dot(props)
}); });
} else } else
/*
var [c, [b, b2], ..., { key : a }] = obj;
var { "key" : d } = { key : "val" };
to
var c = obj[0], b = obj[1][0], b2 = obj[1][1], $_cola_i = obj.length - 1, a = obj[$_cola_i++].key;
var $_cola_tmp = { key : "val" }, d = $_cola_tmp["key"];
*/
if(node instanceof Cola.AST_Var){
var defs = [];
node.definitions.forEach(function(def, i){
if(!(def.name instanceof Cola.AST_ArrayTemplate || def.name instanceof Cola.AST_ObjectTemplate)){
defs.push(def);
return;
}
var Symbol = def.value instanceof Cola.AST_SymbolRef
? def.value
: new Cola.AST_SymbolRef({ name : "$_cola_tmp" });
if(!(def.value instanceof Cola.AST_SymbolRef)) defs.push(new Cola.AST_VarDef({
type : node.type,
name : new Cola.AST_SymbolVar(Symbol),
value : def.value
}));
(function _rec(def, symbol, uid){
var skiped = false, k = 0, is_arrayt = def instanceof Cola.AST_ArrayTemplate, _ = is_arrayt ? def.elements : def.properties;
_.forEach( is_arrayt
? function(el, j){
if(el instanceof Cola.AST_SymbolRef && el.splated){
skiped = true;
defs.push(new Cola.AST_VarDef({
type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
value : null
}));
el.splated = undefined;
defs.push(new Cola.AST_VarDef({
name : new Cola.AST_SymbolVar(el),
value : new Cola.AST_Conditional({
condition : new Cola.AST_Binary({
operator : "<=",
left : new Cola.AST_Number({ value : _.length }),
right : new Cola.AST_Dot({
expression : symbol,
property : "length"
})
}),
consequent : new Cola.AST_Call({
expression : new Cola.AST_Dot({
property : "call",
expression : new Cola.AST_Dot({
property : "slice",
expression : new Cola.AST_Array({ elements : [] })
})
}),
args : [
symbol,
new Cola.AST_Number({ value : j }),
new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Binary({
operator : '-',
left : new Cola.AST_Dot({
property : "length",
expression : symbol
}),
right : new Cola.AST_Number({ value : _.length - j - 1 })
})
})
]
}),
alternative : new Cola.AST_Seq({
car : new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : j })
}),
cdr : new Cola.AST_Array({ elements : [] })
})
})
}));
} else
if(el instanceof Cola.AST_SymbolRef) defs.push(new Cola.AST_VarDef({
start : node.start,
end : node.end,
type : node.type,
name : new Cola.AST_SymbolVar(el),
value : new Cola.AST_Sub({
expression : symbol,
property : !skiped
? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({
operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ })
})
})
})); else
if(el instanceof Cola.AST_Noop){
skiped = true;
defs.push(new Cola.AST_VarDef({
type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
value : new Cola.AST_Binary({
operator : '-',
left : new Cola.AST_Dot({
property : "length",
expression : symbol
}),
right : new Cola.AST_Number({ value : _.length -1 - j })
})
}));
} else
if(el instanceof Cola.AST_Hole || el instanceof Cola.AST_ArrayTemplate && el.elements.length == 0 || el instanceof Cola.AST_ObjectTemplate && el.properties.length == 0)
k++;
else
_rec(el, new Cola.AST_Sub({
expression : symbol,
property : !skiped
? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({
operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ })
})
}), uid + "_");
}
: function(el, j){
if(el.value instanceof Cola.AST_SymbolRef || el.value instanceof Cola.AST_Noop && el.start.type == "name") defs.push(new Cola.AST_VarDef({
start : node.start,
end : node.end,
type : node.type,
name : el.value instanceof Cola.AST_Noop ? new Cola.AST_SymbolVar({ name : el.key }) : new Cola.AST_SymbolVar(el.value),
value : el.start.type == "name"
? new Cola.AST_Dot({
expression : symbol,
property : el.key
})
: new Cola.AST_Sub({
expression : symbol,
property : new Cola.AST_String({ value : el.key })
})
})); else
_rec(el.value, el.start.type == "name"
? new Cola.AST_Dot({
expression : symbol,
property : el.key
})
: new Cola.AST_Sub({
expression : symbol,
property : new Cola.AST_String({ value : el.key })
}), uid + "_");
});
})(def.name, Symbol, "_");
});
node.definitions = defs;
} else
/*
{ String name, age : ages.age } = pro;
to
var name = pro.name;
ages.age = pro.age;
*/
if(node.body instanceof Cola.AST_Assign && (node.body.left instanceof Cola.AST_ArrayTemplate || node.body.left instanceof Cola.AST_ObjectTemplate ||
(node.body.left instanceof Cola.AST_Array || node.body.left instanceof Cola.AST_Object) && node.body.left.template) &&
node instanceof Cola.AST_SimpleStatement){
node = node.body;
var defs = [];
var Symbol = node.right instanceof Cola.AST_SymbolRef
? node.right
: new Cola.AST_SymbolRef({ name : "$_cola_tmp" });
if(!(node.right instanceof Cola.AST_SymbolRef)) defs.push(new Cola.AST_VarDef({
type : "dynamic",
name : new Cola.AST_SymbolVar(Symbol),
value : node.right
}));
(function _rec(def, symbol, uid){
var skiped = false, k = 0, is_arrayt = def instanceof Cola.AST_Array || def instanceof Cola.AST_ArrayTemplate, _ = is_arrayt ? def.elements : def.properties;
_.forEach( is_arrayt
? function(el, j){
if(el instanceof Cola.AST_VarDef && el.name.splated){
skiped = true;
defs.push(new Cola.AST_VarDef({
type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
value : null
}));
el.name.splated = undefined;
el.value = new Cola.AST_Conditional({
condition : new Cola.AST_Binary({
operator : "<=",
left : new Cola.AST_Number({ value : _.length }),
right : new Cola.AST_Dot({
expression : symbol,
property : "length"
})
}),
consequent : new Cola.AST_Call({
expression : new Cola.AST_Dot({
property : "call",
expression : new Cola.AST_Dot({
property : "slice",
expression : new Cola.AST_Array({ elements : [] })
})
}),
args : [
symbol,
new Cola.AST_Number({ value : j }),
new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Binary({
operator : '-',
left : new Cola.AST_Dot({
property : "length",
expression : symbol
}),
right : new Cola.AST_Number({ value : _.length - j - 1 })
})
})
]
}),
alternative : new Cola.AST_Seq({
car : new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : j })
}),
cdr : new Cola.AST_Array({ elements : [] })
})
});
defs.push(el);
} else
if((el instanceof Cola.AST_SymbolRef || el instanceof Cola.AST_Sub || el instanceof Cola.AST_Dot) && el.splated){
skiped = true;
defs.push(new Cola.AST_VarDef({
type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
value : null
}));
el.splated = undefined;
defs.push(new Cola.AST_Assign({
operator : "=",
left : el,
right : new Cola.AST_Conditional({
condition : new Cola.AST_Binary({
operator : "<=",
left : new Cola.AST_Number({ value : _.length }),
right : new Cola.AST_Dot({
expression : symbol,
property : "length"
})
}),
consequent : new Cola.AST_Call({
expression : new Cola.AST_Dot({
property : "call",
expression : new Cola.AST_Dot({
property : "slice",
expression : new Cola.AST_Array({ elements : [] })
})
}),
args : [
symbol,
new Cola.AST_Number({ value : j }),
new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Binary({
operator : '-',
left : new Cola.AST_Dot({
property : "length",
expression : symbol
}),
right : new Cola.AST_Number({ value : _.length - j - 1 })
})
})
]
}),
alternative : new Cola.AST_Seq({
car : new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : j })
}),
cdr : new Cola.AST_Array({ elements : [] })
})
})
}));
} else
if(el instanceof Cola.AST_VarDef){
el.value = new Cola.AST_Sub({
expression : symbol,
property : !skiped
? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({
operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ })
})
});
defs.push(el);
} else
if(el instanceof Cola.AST_SymbolRef || el instanceof Cola.AST_Sub || el instanceof Cola.AST_Dot) defs.push(new Cola.AST_Assign({
operator : "=",
left : el,
right : new Cola.AST_Sub({
expression : symbol,
property : !skiped
? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({
operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ })
})
})
})); else
if(el instanceof Cola.AST_Noop){
skiped = true;
defs.push(new Cola.AST_VarDef({
type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
value : new Cola.AST_Binary({
operator : '-',
left : new Cola.AST_Dot({
property : "length",
expression : symbol
}),
right : new Cola.AST_Number({ value : _.length -1 - j })
})
}));
} else
if(el instanceof Cola.AST_Hole || el instanceof Cola.AST_ArrayTemplate && el.elements.length == 0 || el instanceof Cola.AST_ObjectTemplate && el.properties.length == 0)
k++;
else
_rec(el, new Cola.AST_Sub({
expression : symbol,
property : !skiped
? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({
operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ })
})
}), uid + "_");
}
: function(el, j){
if(el.type && (el.value instanceof Cola.AST_SymbolRef || el.value instanceof Cola.AST_Noop && el.start.type == "name")) defs.push(new Cola.AST_VarDef({
start : node.start,
end : node.end,
type : el.type,
name : el.value instanceof Cola.AST_Noop ? new Cola.AST_SymbolVar({ name : el.key }) : new Cola.AST_SymbolVar(el.value),
value : el.start.type == "name"
? new Cola.AST_Dot({
expression : symbol,
property : el.key
})
: new Cola.AST_Sub({
expression : symbol,
property : new Cola.AST_String({ value : el.key })
})
})); else
if(el.value instanceof Cola.AST_SymbolRef || el.value instanceof Cola.AST_Sub || el.value instanceof Cola.AST_Dot || el.value instanceof Cola.AST_Noop && el.start.type == "name") defs.push(new Cola.AST_Assign({
operator : "=",
left : el.value instanceof Cola.AST_Noop ? new Cola.AST_SymbolRef({ name : el.key }) : el.value,
right : el.start.type == "name"
? new Cola.AST_Dot({
expression : symbol,
property : el.key
})
: new Cola.AST_Sub({
expression : symbol,
property : new Cola.AST_String({ value : el.key })
})
})); else
_rec(el.value, el.start.type == "name"
? new Cola.AST_Dot({
expression : symbol,
property : el.key
})
: new Cola.AST_Sub({
expression : symbol,
property : new Cola.AST_String({ value : el.key })
}), uid + "_");
});
})(node.left, Symbol, "_");
if (defs.length == 0) return node;
node = [];
var sdef, sdefs = [], prev = defs[0].CTOR;
defs.forEach(function _(def, i){
sdef = false;
if(def instanceof prev) sdefs.push(def);
else {
if(prev == Cola.AST_VarDef) sdef = new Cola.AST_Var({
type : "dynamic",
definitions : sdefs
}); else if(sdefs.length == 1) sdef = sdefs[0]
else {
sdefs.reverse().forEach(function(def){
if(!sdef) sdef = def;
else sdef = new Cola.AST_Seq({
car : def,
cdr : sdef
});
});
}
node.push(!(sdef instanceof Cola.AST_Var)
? new Cola.AST_SimpleStatement({ body : sdef })
: sdef
);
prev = def.CTOR;
sdefs = [def];
}
if(i == defs.length - 1) _(false);
});
} else
/*
func({ a : aname, b : bname } = obj)
to
func((function($_cola_expr, arguments){
aname = obj.a;
bname = obj.b;
return $_cola_expr;
}).call(this, obj, arguments))
*/
if(node instanceof Cola.AST_Assign && (node.left instanceof Cola.AST_ArrayTemplate || node.left instanceof Cola.AST_ObjectTemplate ||
(node.left instanceof Cola.AST_Array || node.left instanceof Cola.AST_Object) && node.left.template)){
if(node.vardef) Cola.Parser.prototype.unexpected.call({}, node.start);
var defs = [];
var Symbol = node.right instanceof Cola.AST_SymbolRef
? node.right
: new Cola.AST_SymbolRef({ name : "$_cola_expr" });
(function _rec(def, symbol, uid){
var skiped = false, k = 0, is_arrayt = def instanceof Cola.AST_Array || def instanceof Cola.AST_ArrayTemplate, _ = is_arrayt ? def.elements : def.properties;
_.forEach( is_arrayt
? function(el, j){
if((el instanceof Cola.AST_SymbolRef || el instanceof Cola.AST_Sub || el instanceof Cola.AST_Dot) && el.splated){
skiped = true;
defs.push(new Cola.AST_VarDef({
type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
value : null
}));
el.splated = undefined;
defs.push(new Cola.AST_Assign({
operator : "=",
left : el,
right : new Cola.AST_Conditional({
condition : new Cola.AST_Binary({
operator : "<=",
left : new Cola.AST_Number({ value : _.length }),
right : new Cola.AST_Dot({
expression : symbol,
property : "length"
})
}),
consequent : new Cola.AST_Call({
expression : new Cola.AST_Dot({
property : "call",
expression : new Cola.AST_Dot({
property : "slice",
expression : new Cola.AST_Array({ elements : [] })
})
}),
args : [
symbol,
new Cola.AST_Number({ value : j }),
new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Binary({
operator : '-',
left : new Cola.AST_Dot({
property : "length",
expression : symbol
}),
right : new Cola.AST_Number({ value : _.length - j - 1 })
})
})
]
}),
alternative : new Cola.AST_Seq({
car : new Cola.AST_Assign({
operator : '=',
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : j })
}),
cdr : new Cola.AST_Array({ elements : [] })
})
})
}));
} else
if(el instanceof Cola.AST_SymbolRef || el instanceof Cola.AST_Sub || el instanceof Cola.AST_Dot) defs.push(new Cola.AST_Assign({
operator : "=",
left : el,
right : new Cola.AST_Sub({
expression : symbol,
property : !skiped
? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({
operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ })
})
})
})); else
if(el instanceof Cola.AST_Noop){
skiped = true;
defs.push(new Cola.AST_VarDef({
type : "int",
name : new Cola.AST_SymbolVar({ name : "$_cola" + uid + "i" }),
value : new Cola.AST_Binary({
operator : '-',
left : new Cola.AST_Dot({
property : "length",
expression : symbol
}),
right : new Cola.AST_Number({ value : _.length -1 - j })
})
}));
} else
if(el instanceof Cola.AST_Hole || el instanceof Cola.AST_ArrayTemplate && el.elements.length == 0 || el instanceof Cola.AST_ObjectTemplate && el.properties.length == 0)
k++;
else
_rec(el, new Cola.AST_Sub({
expression : symbol,
property : !skiped
? new Cola.AST_Number({ value : j })
: new Cola.AST_Binary({
operator : "+",
left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }),
right : new Cola.AST_Number({ value : k++ })
})
}), uid + "_");
}
: function(el, j){
if(el.value instanceof Cola.AST_SymbolRef || el.value instanceof Cola.AST_Sub || el.value instanceof Cola.AST_Dot || el.value instanceof Cola.AST_Noop && el.start.type == "name") defs.push(new Cola.AST_Assign({
operator : "=",
left : el.value instanceof Cola.AST_Noop ? new Cola.AST_SymbolRef({ name : el.key }) : el.value,
right : el.start.type == "name"
? new Cola.AST_Dot({
expression : symbol,
property : el.key
})
: new Cola.AST_Sub({
expression : symbol,
property : new Cola.AST_String({ value : el.key })
})
})); else
_rec(el.value, el.start.type == "name"
? new Cola.AST_Dot({
expression : symbol,
property : el.key
})
: new Cola.AST_Sub({
expression : symbol,
property : new Cola.AST_String({ value : el.key })
}), uid + "_");
});
})(node.left, Symbol, "_");
if (defs.length == 0) return node;
props = {
type : "dynamic",
body : [],
argnames : [new Cola.AST_ArgDef({
argtype : "positional",
type : "dynamic",
defval : new Cola.AST_Noop(),
name : new Cola.AST_SymbolFunarg({ name : "$_cola_expr", start : node.right.start, end : node.right.end })
}), new Cola.AST_ArgDef({
argtype : "positional",
type : "dynamic",
defval : new Cola.AST_Noop(),
name : new Cola.AST_SymbolFunarg({ name : "arguments", start : new Cola.AST_Token(), end : new Cola.AST_Token() })
})]
};
var sdef, sdefs = [], prev = defs[0].CTOR;
defs.forEach(function _(def, i){
sdef = false;
if(def instanceof prev) sdefs.push(def);
else {
if(prev == Cola.AST_VarDef) sdef = new Cola.AST_Var({
type : "dynamic",
definitions : sdefs
}); else if(sdefs.length == 1) sdef = sdefs[0]
else {
sdefs.reverse().forEach(function(def){
if(!sdef) sdef = def;
else sdef = new Cola.AST_Seq({
car : def,
cdr : sdef
});
});
}
props.body.push(!(sdef instanceof Cola.AST_Var)
? new Cola.AST_SimpleStatement({ body : sdef })
: sdef
);
prev = def.CTOR;
sdefs = [def];
}
if(i == defs.length - 1) _(false);
});
props = {
expression : new Cola.AST_Function(props),
property : "call"
}
node = new Cola.AST_Call({
start : node.start,
end : node.end,
args : [new Cola.AST_SymbolRef({ name : "this" }), node.right, new Cola.AST_SymbolRef({ name : "arguments" })],
expression : new Cola.AST_Dot(props)
});
} else
/* /*
"test @a @{b} {{c}}" "test @a @{b} {{c}}"
@ -883,8 +1556,14 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if(node instanceof Cola.AST_RegExp && (node.value.indexOf('\n') != -1 || /\/[\w]*x[\w]*$/.test(node.value))){ if(node instanceof Cola.AST_RegExp && (node.value.indexOf('\n') != -1 || /\/[\w]*x[\w]*$/.test(node.value))){
node.value = node.value.replace(/[\r\n\s]/g,'').replace(/(\/[\w]*)x([\w]*$)/, '$1$2'); node.value = node.value.replace(/[\r\n\s]/g,'').replace(/(\/[\w]*)x([\w]*$)/, '$1$2');
} }
node._descend(node, this); if(node instanceof Array){
_this = this;
node.forEach(function(nd){
nd._descend(nd, _this);
})
} else node._descend(node, this);
return node; return node;
}); });