From ad70d58e83263f6d05925e8d38fde63a434e8538 Mon Sep 17 00:00:00 2001 From: Onoshko Dan Date: Sun, 17 Aug 2014 16:39:57 +0700 Subject: [PATCH] Class translation still in progress. --- lib/ast.js | 4 ++ lib/transform.js | 2 +- lib/translate.js | 101 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 97 insertions(+), 10 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index 08416672..89703352 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -379,6 +379,7 @@ Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals language", { }, Cola.AST_Scope); Cola.AST_Class = Cola.DEFNODE("Class", "name extends", { + $iscola: true, $documentation: "Base class for classes", $propdoc: { name: "[AST_SymbolClass] the name of this class", @@ -424,10 +425,12 @@ Cola.AST_Defun = Cola.DEFNODE("Defun", "type mods", { }, Cola.AST_Lambda); Cola.AST_Getter = Cola.DEFNODE("Getter", "type mods", { + $iscola: true, $documentation: "A function definition" }, Cola.AST_Lambda); Cola.AST_Setter = Cola.DEFNODE("Setter", "type mods", { + $iscola: true, $documentation: "A function definition" }, Cola.AST_Lambda); @@ -944,6 +947,7 @@ Cola.AST_SymbolConst = Cola.DEFNODE("SymbolConst", null, { }, Cola.AST_SymbolDeclaration); Cola.AST_SymbolClass = Cola.DEFNODE("SymbolClass", null, { + $iscola: true, $documentation: "Symbol defining a class", }, Cola.AST_SymbolDeclaration); diff --git a/lib/transform.js b/lib/transform.js index ab4b4e80..cae558a5 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -80,7 +80,7 @@ Cola.TreeTransformer.prototype.__proto__ = new Cola.TreeWalker; function do_list(list, tw) { return Cola.MAP(list, function(node){ - + if(!node.transform) return node; var r = node.transform(tw, true); if (!r) r = Cola.MAP.continue(); diff --git a/lib/translate.js b/lib/translate.js index 3bb6305d..f47788bb 100644 --- a/lib/translate.js +++ b/lib/translate.js @@ -508,13 +508,13 @@ Cola.DefFunWithMods = function(func, mods){ }) ] }; - if(!(sname.expression instanceof Cola.AST_Symbol && sname.expression.name == "this" || sname instanceof Cola.AST_Proto)) + if(!(sname instanceof Cola.AST_Proto || mods.indexOf("method") != -1)) dp.properties.push(new Cola.AST_ObjectKeyVal({ key : "configurable", value : new Cola.AST_True })); - if(!(func instanceof Cola.AST_Getter || func instanceof Cola.AST_Setter)) + if(!(func instanceof Cola.AST_Getter || func instanceof Cola.AST_Setter || mods.indexOf("method") != -1)) dp.properties.push(new Cola.AST_ObjectKeyVal({ key : "writable", value : new Cola.AST_True @@ -1143,13 +1143,12 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ var texpr = def.name; while(!(texpr.expression instanceof Cola.AST_Symbol || texpr.expression instanceof Cola.AST_Constant)) texpr = texpr.expression; - texpr.expression = new Cola.AST_SymbolRef(texpr.expression); + if(texpr.expression instanceof Cola.AST_Symbol && !(texpr.expression instanceof Cola.AST_This)) texpr.expression = new Cola.AST_SymbolRef(texpr.expression); newNode.push(Cola.DefPropWithMods(def, node.mods)); newNode[newNode.length - 1] = new Cola.AST_SimpleStatement({ body : newNode[newNode.length - 1] }); - } }); @@ -1179,7 +1178,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ if(node instanceof Cola.AST_Lambda && node.name && !(node.name instanceof Cola.AST_Symbol)){ var texpr = node.name, notst = node instanceof Cola.AST_Function; while(!(texpr.expression instanceof Cola.AST_Symbol || texpr.expression instanceof Cola.AST_Constant)) texpr = texpr.expression; - texpr.expression = new Cola.AST_SymbolRef(texpr.expression); + if(texpr.expression instanceof Cola.AST_Symbol && !(texpr.expression instanceof Cola.AST_This)) texpr.expression = new Cola.AST_SymbolRef(texpr.expression); node = Cola.DefFunWithMods(node, node.mods); @@ -1312,9 +1311,9 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ */ if(node instanceof Cola.AST_Class){ var pre_constructor, post_constructor, main_constructors = [], - is_pre = true; + is_pre = true, members = ["super"], binder; + newNode = []; - node.name = new Cola.AST_SymbolRef(node.name); pre_constructor = new Cola.AST_Defun({ @@ -1349,7 +1348,6 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ main_constructors.push(member); newNode.push(member); - console.log(member); if(node.extends){ _ColaRuntime$$hash[Cola._ColaRuntime$$proto.i] = true; @@ -1396,14 +1394,29 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ } else if(member instanceof Cola.AST_Lambda && member.name instanceof Cola.AST_SymbolDefun){ + if(members.indexOf(member.name.name) == -1) members.push(member.name.name); member.name = new Cola.AST_Proto({ expression : node.name, property : member.name.name }); newNode.push(member); - } else + } else { + if(member instanceof Cola.AST_Var) + member.definitions.forEach(function(def){ + var texpr = def.name; + + if(!(texpr instanceof Cola.AST_Symbol)){ + while(!(texpr.expression instanceof Cola.AST_Symbol || texpr.expression instanceof Cola.AST_Constant)) texpr = texpr.expression; + texpr = texpr.expression; + } + + if(texpr instanceof Cola.AST_Symbol && !(texpr instanceof Cola.AST_This) && members.indexOf(texpr.name) == -1) + members.push(texpr.name); + }); + if(is_pre) pre_constructor.body.push(member); else post_constructor.body.push(member); + } }); if(pre_constructor.body.length != 0){ @@ -1431,6 +1444,76 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ }); }); } + + var scope, lvl = 0, hmembers, with_self = false, flvl_this = []; + binder = new Cola.TreeTransformer(function(member){ + var tmembers, tscope, tlvl; + member = member.clone(); + + if(lvl > 1 && member instanceof Cola.AST_Var) + member.definitions.forEach(function(def){ + if(def.name instanceof Cola.AST_Symbol && hmembers.indexOf(def.name.name) != -1) + hmembers.splice(hmembers.indexOf(def.name.name), 1); + }); + else + if(lvl > 1 && (member instanceof Cola.AST_Defun || member instanceof Cola.AST_Getter || member instanceof Cola.AST_Setter) + && member.name instanceof Cola.AST_Symbol && hmembers.indexOf(member.name.name) != -1) + hmembers.splice(hmembers.indexOf(member.name.name), 1); + else if(member instanceof Cola.AST_Scope) scope = (lvl++, member); + else if(member instanceof Cola.AST_SymbolRef && hmembers.indexOf(member.name) != -1){ + member = new Cola.AST_Dot({ + expression : lvl > 1 + ? (with_self = true, new Cola.AST_SymbolRef({ name: "self" })) + : new Cola.AST_This, + property : member.name + }); + if(lvl == 1) flvl_this.push(member); + } else + if(member instanceof Cola.AST_SymbolVar && scope.name instanceof Cola.AST_Proto && (scope.name.property == "pre_constructor" || scope.name.property == "post_constructor") + && hmembers.indexOf(member.name) != -1){ + member = new Cola.AST_Dot({ + expression : lvl > 1 + ? (with_self = true, new Cola.AST_SymbolVar({ name: "self" })) + : new Cola.AST_This, + property : member.name + }); + if(lvl == 1) flvl_this.push(member); + } + + tscope = scope; tlvl = lvl; tmembers = hmembers.slice(); + member._descend(member, this); + scope = tscope; lvl = tlvl; hmembers = tmembers; + + return member; + }); + + newNode.forEach(function(member, i){ + lvl = 0; + flvl_this = []; + with_self = false; + hmembers = members.slice(); + + if(member instanceof Cola.AST_Lambda){ + newNode[i] = member.transform(binder); + newNode[i].mods ? newNode[i].mods.push("method") : (newNode[i].mods = ["method"]); + + if(with_self) { + newNode[i].body.unshift(new Cola.AST_Var({ + mods : [], + type : "dynamic", + definitions : [new Cola.AST_VarDef({ + type : "dynamic", + name : new Cola.AST_SymbolVar({ name: "self" }), + value : new Cola.AST_This + })] + })); + + flvl_this.forEach(function(th){ + th.expression = new Cola.AST_SymbolRef({ name: "self" }); + }); + } + } + }); node = new Cola.AST_BlockStatement({ body: newNode }); } else