diff --git a/lib/translate.js b/lib/translate.js index da7a2035..733f6f8c 100644 --- a/lib/translate.js +++ b/lib/translate.js @@ -146,6 +146,48 @@ Cola.Constructions.SplatedConditional = function(name, uid, pos, after, length){ }); }; +/* + {{name}}[{{pos}}] + + or + + {{name}}[$_cola{{uid}}i + {{after}}] + +*/ +Cola.Constructions.ValueWithOffset = function(name, uid, cond, pos, after){ + if(Cola.$_cola_is(name, String)) name = new Cola.AST_SymbolRef({ name : name }); + return new Cola.AST_Sub({ + expression : name, + property : cond + ? new Cola.AST_Number({ value : pos }) + : new Cola.AST_Binary({ + operator : "+", + left : new Cola.AST_SymbolRef({ name : "$_cola" + uid + "i" }), + right : new Cola.AST_Number({ value : after }) + }) + }); +}; + +/* + {{name}}.{{key}} + + or + + {{name}}["{{key}}"] + +*/ +Cola.Constructions.ValueWithKey = function(cond, name, key){ + return cond + ? new Cola.AST_Dot({ + expression : name, + property : key + }) + : new Cola.AST_Sub({ + expression : name, + property : new Cola.AST_String({ value : key }) + }); +}; + /* {{name}} = {{length}} <= arguments.length ? [].slice.call(arguments, {{pos}}, $_cola_i = arguments.length - {{after}}) : ($_cola_i = {{pos}}, []) @@ -159,24 +201,31 @@ Cola.Constructions.SplatedVarDef = function(name, pos, after, length){ }); }; +/* + {{name}} = arguments[{{pos}}] + + or + + {{name}} = arguments[$_cola_i + {{aftersplated}}] + +*/ Cola.Constructions.PosedVarDef = function(name, type, pos, aftersplated){ if(Cola.$_cola_is(name, String)) name = { name : name }; return new Cola.AST_VarDef({ type : type, name : new Cola.AST_SymbolVar(name), - value : new Cola.AST_Sub({ - expression : new Cola.AST_SymbolRef({ name : 'arguments' }), - property : aftersplated == -1 - ? new Cola.AST_Number({ value : pos }) - : new Cola.AST_Binary({ - operator : '+', - left : new Cola.AST_SymbolRef({ name : '$_cola_i' }), - right : new Cola.AST_Number({ value : aftersplated }) - }) - }) + value : Cola.Constructions.ValueWithOffset('arguments', '_', aftersplated == -1, pos, aftersplated) }); }; +/* + {{name}} = arguments[{{pos}}] !== undefined ? arguments[{{pos}}] : {{defval}} + + or + + {{name}} = arguments[$_cola_i + {{aftersplated}}] !== undefined ? arguments[$_cola_i + {{aftersplated}}] : {{defval}} + +*/ Cola.Constructions.PosedWithDefsVarDef = function(name, type, defval, pos, aftersplated){ if(Cola.$_cola_is(name, String)) name = { name : name }; return new Cola.AST_VarDef({ @@ -185,33 +234,19 @@ Cola.Constructions.PosedWithDefsVarDef = function(name, type, defval, pos, after value : new Cola.AST_Conditional({ condition : new Cola.AST_Binary({ operator : "!==", - left : new Cola.AST_Sub({ - expression : new Cola.AST_SymbolRef({ name : 'arguments' }), - property : aftersplated == -1 - ? new Cola.AST_Number({ value : pos }) - : new Cola.AST_Binary({ - operator : '+', - left : new Cola.AST_SymbolRef({ name : '$_cola_i' }), - right : new Cola.AST_Number({ value : aftersplated }) - }) - }), + left : Cola.Constructions.ValueWithOffset('arguments', '_', aftersplated == -1, pos, aftersplated), right : new Cola.AST_SymbolRef({ name : 'undefined' }) }), - consequent : new Cola.AST_Sub({ - expression : new Cola.AST_SymbolRef({ name : 'arguments' }), - property : aftersplated == -1 - ? new Cola.AST_Number({ value : pos }) - : new Cola.AST_Binary({ - operator : '+', - left : new Cola.AST_SymbolRef({ name : '$_cola_i' }), - right : new Cola.AST_Number({ value : aftersplated }) - }) - }), + consequent : Cola.Constructions.ValueWithOffset('arguments', '_', aftersplated == -1, pos, aftersplated), alternative : defval }) }); }; +/* + {{name}} = arguments.{{key}} !== undefined ? arguments.{{key}} : {{defval}} + +*/ Cola.Constructions.NamedVarDef = function(name, type, defval, key){ if(Cola.$_cola_is(name, String)) name = { name : name }; return new Cola.AST_VarDef({ @@ -779,8 +814,8 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ } else - if(val.defval instanceof Cola.AST_Noop) props.definitions.push(Cola.Constructions.PosedVarDef(val.name, val.type, pos, aftersplated)), aftersplated++; - else props.definitions.push(Cola.Constructions.PosedWithDefsVarDef(val.name, val.type, val.defval, pos, aftersplated)), aftersplated++; + if(val.defval instanceof Cola.AST_Noop) props.definitions.push(Cola.Constructions.PosedVarDef(val.name, val.type, pos, aftersplated++)); + else props.definitions.push(Cola.Constructions.PosedWithDefsVarDef(val.name, val.type, val.defval, pos, aftersplated++)); }); named.forEach(function(val, i){ @@ -1094,7 +1129,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ } else*/ /* - { String name, age : ages.age } = pro; + { String name, age : ages.age } = pro; to @@ -1149,31 +1184,13 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ })); } 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++ }) - }) - }); + el.value = Cola.Constructions.ValueWithOffset(symbol, uid, !skiped, j, 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 : node.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++ }) - }) - }) + right : Cola.Constructions.ValueWithOffset(symbol, uid, !skiped, j, k++) })); else if(el instanceof Cola.AST_Noop){ skiped = true; @@ -1193,16 +1210,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ 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 + "_"); + _rec(el, Cola.Constructions.ValueWithOffset(symbol, uid, !skiped, j, 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({ @@ -1210,38 +1218,14 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ 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 }) - }) + value : Cola.Constructions.ValueWithKey(el.start.type == "name" || el.start.type == "keyword", symbol, 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 : node.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 }) - }) + right : Cola.Constructions.ValueWithKey(el.start.type == "name" || el.start.type == "keyword", symbol, 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 + "_"); + _rec(el.value, Cola.Constructions.ValueWithKey(el.start.type == "name" || el.start.type == "keyword", symbol, el.key), uid + "_"); }); })(node.left, Symbol, "_"); @@ -1317,64 +1301,13 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ defs.push(new Cola.AST_Assign({ operator : node.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 : [] }) - }) - }) + right : Cola.Constructions.SplatedConditional(symbol, uid, j, _.length - j - 1, _.length) })); } else if(el instanceof Cola.AST_SymbolRef || el instanceof Cola.AST_Sub || el instanceof Cola.AST_Dot) defs.push(new Cola.AST_Assign({ operator : node.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++ }) - }) - }) + right : Cola.Constructions.ValueWithOffset(symbol, uid, !skiped, j, k++) })); else if(el instanceof Cola.AST_Noop){ skiped = true; @@ -1394,40 +1327,15 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ 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 + "_"); + _rec(el, Cola.Constructions.ValueWithOffset(symbol, uid, !skiped, j, 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 : node.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 }) - }) + right : Cola.Constructions.ValueWithKey(el.start.type == "name" || el.start.type == "keyword", symbol, 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 + "_"); + _rec(el.value, Cola.Constructions.ValueWithKey(el.start.type == "name" || el.start.type == "keyword", symbol, el.key), uid + "_"); }); })(node.left, Symbol, "_"); @@ -1444,7 +1352,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ 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() }) + name : new Cola.AST_SymbolFunarg({ name : "arguments" }) })] }; @@ -1479,9 +1387,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ if(i == defs.length - 1) _(false); }); - props.body.push(new Cola.AST_Return({ - value : new Cola.AST_SymbolRef({ name : "$_cola_expr" }) - })); + props.body.push(new Cola.AST_Return({ value : new Cola.AST_SymbolRef({ name : "$_cola_expr" }) })); props = { expression : new Cola.AST_Function(props), @@ -1537,6 +1443,8 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ } node = new Cola.AST_Call({ + start : node.start, + end : node.end, args : [new Cola.AST_SymbolRef({ name : "this" }), new Cola.AST_SymbolRef({ name : "arguments" })], expression : new Cola.AST_Dot(props) }); @@ -1576,6 +1484,8 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ }; node = new Cola.AST_Call({ + start : node.start, + end : node.end, args : [new Cola.AST_SymbolRef({ name : "this" }), new Cola.AST_SymbolRef({ name : "arguments" })], expression : new Cola.AST_Dot(props) });