diff --git a/lib/translate.js b/lib/translate.js index 0e9b29a2..3bb6305d 100644 --- a/lib/translate.js +++ b/lib/translate.js @@ -567,7 +567,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ tt = new Cola.TreeTransformer(function(node, descend, in_list){ var newNode, props = {}, parent = this.parent(); node = node.clone(); - + /* main(){ console.log("hello world"); @@ -1176,8 +1176,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ Math.rand = function rand(){} */ - if((node instanceof Cola.AST_Defun || node instanceof Cola.AST_Function || node instanceof Cola.AST_Setter || node instanceof Cola.AST_Getter) - && node.name && !(node.name instanceof Cola.AST_SymbolDefun) && !(node.name instanceof Cola.AST_SymbolLambda)){ + 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); @@ -1311,6 +1310,130 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){ } */ + if(node instanceof Cola.AST_Class){ + var pre_constructor, post_constructor, main_constructors = [], + is_pre = true; + newNode = []; + + node.name = new Cola.AST_SymbolRef(node.name); + + pre_constructor = new Cola.AST_Defun({ + mods : ["covert"], + type : "dynamic", + name : new Cola.AST_Proto({ + expression : new Cola.AST_SymbolDefun(node.name), + property : "pre_constructor" + }), + argnames : [], + body : [] + }); + + post_constructor = new Cola.AST_Defun({ + mods : ["covert"], + type : "dynamic", + name : new Cola.AST_Proto({ + expression : new Cola.AST_SymbolDefun(node.name), + property : "post_constructor" + }), + argnames : [], + body : [] + }); + + node.body.forEach(function(member){ + if(member instanceof Cola.AST_Defun && member.name instanceof Cola.AST_SymbolDefun && member.name.name == node.name.name){ + if(main_constructors.some(function(constr){ return constr.name instanceof Cola.AST_Dot; })) + Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, member.start, "Main constructor must be defined before named constructors"); + + if(main_constructors.some(function(constr){ return constr.name instanceof Cola.AST_SymbolDefun && constr.name.name == node.name.name; })) + Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, member.start, "Constructor can be defined only one time"); + + main_constructors.push(member); + newNode.push(member); + console.log(member); + + if(node.extends){ + _ColaRuntime$$hash[Cola._ColaRuntime$$proto.i] = true; + newNode.push(new Cola.AST_Assign({ + left : new Cola.AST_Dot({ expression: node.name, property: "prototype" }), + operator : "=", + right : new Cola.AST_Call({ + expression : new Cola.AST_SymbolRef({ name: "_ColaRuntime$$proto" }), + args : [node.extends] + }) + })); + newNode[newNode.length - 1] = new Cola.AST_SimpleStatement({ + body : newNode[newNode.length - 1] + }); + } + + is_pre = false; + } else + + if(member instanceof Cola.AST_Defun && member.name instanceof Cola.AST_Dot && + member.name.expression instanceof Cola.AST_SymbolDefun && member.name.expression.name == node.name.name){ + if(main_constructors.some(function(constr){ return constr.name instanceof Cola.AST_Dot && constr.name.property == member.name.property; })) + Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, member.start, "Constructor can be defined only one time"); + + main_constructors.push(member); + newNode.push(member); + + newNode.push(new Cola.AST_Assign({ + left : new Cola.AST_Dot({ + expression : (function(name){ + name.expression = new Cola.AST_SymbolRef(name.expression); + return name; + })(member.name), + property : "prototype" + }), + operator : "=", + right : new Cola.AST_Dot({ expression: node.name, property: "prototype" }) + })); + newNode[newNode.length - 1] = new Cola.AST_SimpleStatement({ + body : newNode[newNode.length - 1] + }); + + is_pre = false; + } else + + if(member instanceof Cola.AST_Lambda && member.name instanceof Cola.AST_SymbolDefun){ + member.name = new Cola.AST_Proto({ + expression : node.name, + property : member.name.name + }); + newNode.push(member); + } else + if(is_pre) pre_constructor.body.push(member); + else post_constructor.body.push(member); + }); + + if(pre_constructor.body.length != 0){ + newNode.push(pre_constructor); + main_constructors.forEach(function(constr){ + constr.body.unshift(new Cola.AST_Call({ + expression : new Cola.AST_Dot({ expression: new Cola.AST_This, property: "pre_constructor" }), + args : [] + })); + constr.body[0] = new Cola.AST_SimpleStatement({ + body : constr.body[0] + }); + }); + } + + if(post_constructor.body.length != 0){ + newNode.push(post_constructor); + main_constructors.forEach(function(constr){ + constr.body.push(new Cola.AST_Call({ + expression : new Cola.AST_Dot({ expression: new Cola.AST_This, property: "post_constructor" }), + args : [] + })); + constr.body[constr.body.length - 1] = new Cola.AST_SimpleStatement({ + body : constr.body[constr.body.length - 1] + }); + }); + } + + node = new Cola.AST_BlockStatement({ body: newNode }); + } else /* func(String s, Number n:, Array list..., Boolean b = false, h: 123){