Var and func def modificators.

covert int Math.some() => 123;

to

Object.defineProperty(Math, "some", {
    value: function some() {
        return 123;
    },
    writable: true
});
This commit is contained in:
Onoshko Dan 2014-08-16 13:21:45 +07:00
parent 1d297d9248
commit 8e3914de57
4 changed files with 215 additions and 50 deletions

View File

@ -397,6 +397,15 @@ Future plans
int index = -10; int index = -10;
arr[%index] = 34; // arr[index %% arr.length]; arr[%index] = 34; // arr[index %% arr.length];
- var modificators. status: done
readonly int Math.Pi = 3.14;
list of modificators
* static: vars, funcs, getters and setters in class
* const: vars
* covert: vars, funcs, getters and setters in class and objects
- classes - classes
class A { class A {

View File

@ -404,7 +404,15 @@ Cola.AST_Function = Cola.DEFNODE("Function", "type", {
$documentation: "A function expression" $documentation: "A function expression"
}, Cola.AST_Lambda); }, Cola.AST_Lambda);
Cola.AST_Defun = Cola.DEFNODE("Defun", "type", { Cola.AST_Defun = Cola.DEFNODE("Defun", "type mods", {
$documentation: "A function definition"
}, Cola.AST_Lambda);
Cola.AST_Getter = Cola.DEFNODE("Getter", "type mods", {
$documentation: "A function definition"
}, Cola.AST_Lambda);
Cola.AST_Setter = Cola.DEFNODE("Setter", "type mods", {
$documentation: "A function definition" $documentation: "A function definition"
}, Cola.AST_Lambda); }, Cola.AST_Lambda);
@ -589,7 +597,7 @@ Cola.AST_Definitions = Cola.DEFNODE("Definitions", "definitions", {
} }
}, Cola.AST_Statement); }, Cola.AST_Statement);
Cola.AST_Var = Cola.DEFNODE("Var", "type", { Cola.AST_Var = Cola.DEFNODE("Var", "type mods", {
$documentation: "A `var` statement" $documentation: "A `var` statement"
}, Cola.AST_Definitions); }, Cola.AST_Definitions);

View File

@ -49,13 +49,13 @@
!this.Cola && (this.Cola = {}); !this.Cola && (this.Cola = {});
Cola.KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with'; Cola.KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with';
Cola.cKEYWORDS = Cola.KEYWORDS.replace(' void', '') + ' when clone is isnt class singleton injector'; Cola.cKEYWORDS = Cola.KEYWORDS.replace(' void', '') + ' static covert get set when clone is isnt class singleton injector';
Cola.KEYWORDS_ATOM = 'false null true'; Cola.KEYWORDS_ATOM = 'false null true';
Cola.cKEYWORDS_ATOM = Cola.KEYWORDS_ATOM + ' on yes off no'; Cola.cKEYWORDS_ATOM = Cola.KEYWORDS_ATOM + ' on yes off no';
Cola.RESERVED_WORDS = 'abstract boolean byte char double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield'; Cola.RESERVED_WORDS = 'abstract boolean byte char double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield';
Cola.cRESERVED_WORDS = Cola.RESERVED_WORDS.replace(' class', '') + " " + Cola.cKEYWORDS_ATOM + " " + Cola.cKEYWORDS; Cola.cRESERVED_WORDS = Cola.RESERVED_WORDS.replace(' class', '').replace(' static', '') + " " + Cola.cKEYWORDS_ATOM + " " + Cola.cKEYWORDS;
Cola.RESERVED_WORDS += " " + Cola.KEYWORDS_ATOM + " " + Cola.KEYWORDS; Cola.RESERVED_WORDS += " " + Cola.KEYWORDS_ATOM + " " + Cola.KEYWORDS;
Cola.KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case'; Cola.KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case';
@ -768,6 +768,8 @@ Cola.cUNARY_PREFIX = Cola.makePredicate([
"+" "+"
]); ]);
Cola.cVARS_MODIFICATORS = Cola.makePredicate([ "const", "covert", "static" ]);
Cola.UNARY_POSTFIX = Cola.makePredicate([ "--", "++" ]); Cola.UNARY_POSTFIX = Cola.makePredicate([ "--", "++" ]);
Cola.cUNARY_POSTFIX = Cola.makePredicate([ "--", "++", "?" ]); Cola.cUNARY_POSTFIX = Cola.makePredicate([ "--", "++", "?" ]);
@ -1024,21 +1026,46 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
case "atom": case "atom":
return this.simple_statement(); return this.simple_statement();
case "name": case "name": case "keyword":
if(!this.is_js && this.next_is("name")){ var mods = [];
if(!this.is_js && this.is("keyword") && Cola.cVARS_MODIFICATORS(this.S.token.value))
while(this.is("keyword") && Cola.cVARS_MODIFICATORS(this.S.token.value)){
mods.push(this.S.token.value);
this.next();
}
if(!this.is_js && this.is("keyword", "var")){
this.next();
return tmp = this.var_(false, false, mods), this.semicolon(), tmp;
}
if(!this.is_js && this.is("name") && (this.next_is("name") || this.next_is("keyword", "function") || this.next_is("keyword", "get") || this.next_is("keyword", "set"))){
type = this.S.token.value, this.next(); type = this.S.token.value, this.next();
var isfun = false; var isfun = false, ctor = Cola.AST_Defun;
if(this.is("keyword", "get")){
ctor = Cola.AST_Getter;
this.next();
} else if(this.is("keyword", "set")){
cotr = Cola.AST_Setter;
this.next();
} else if(this.is("keyword", "function"))
this.next();
this.dumpS(); this.dumpS();
this.subscripts(this.as_symbol(Cola.AST_SymbolDefun), false); this.subscripts(this.as_symbol(Cola.AST_SymbolDefun), false);
isfun = this.is("punc", "("); isfun = this.is("punc", "(");
this.restoreS(); this.restoreS();
if(isfun) return this.function_(Cola.AST_Defun, type); if(isfun){
return tmp = this.var_(false, type), this.semicolon(), tmp; if(mods.indexOf("const") != -1) this.token_error(this.S.token, "Function can't have `const` modifer");
return this.function_(ctor, type, mods);
} else return tmp = this.var_(false, type, mods), this.semicolon(), tmp;
} }
if(!this.is_js){ if(!this.is_js && this.is("name")){
var _this = this, balance = 1, isfun = false; var _this = this, balance = 1, isfun = false;
this.dumpS(); this.dumpS();
@ -1055,10 +1082,16 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
} }
this.restoreS(); this.restoreS();
if(isfun) return this.function_(Cola.AST_Defun); if(isfun) {
if(mods.indexOf("const") != -1) this.token_error(this.S.token, "Function can't have `const` modifer");
return this.function_(Cola.AST_Defun, false, mods);
}
} }
return this.next_is("punc", ":") if(!this.is_js && mods.length != 0 && this.is("name"))
return tmp = this.var_(false, false, mods), this.semicolon(), tmp;
if(this.is("name")) return this.next_is("punc", ":")
? this.labeled_statement() ? this.labeled_statement()
: this.simple_statement(); : this.simple_statement();
@ -1132,7 +1165,7 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
this.next(); this.next();
return new Cola.AST_EmptyStatement(); return new Cola.AST_EmptyStatement();
default: default:
this.unexpected(); if(!this.is_js && !this.is("keyword")) this.unexpected();
} }
case "keyword": case "keyword":
@ -1165,6 +1198,12 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
case "function": case "function":
return this.function_(Cola.AST_Defun); return this.function_(Cola.AST_Defun);
case "get":
if(!this.is_js) return this.function_(Cola.AST_Getter);
case "set":
if(!this.is_js) return this.function_(Cola.AST_Setter);
case "if": case "if":
return this.if_(); return this.if_();
@ -1347,7 +1386,7 @@ Cola.Parser.prototype.as_funcarg = function(splatedexist) {
}); });
}; };
Cola.Parser.prototype.function_ = function(ctor, type) { Cola.Parser.prototype.function_ = function(ctor, type, mods) {
!type && (type = "dynamic"); !type && (type = "dynamic");
var in_statement = ctor === Cola.AST_Defun, _this = this, splatedexist = false; var in_statement = ctor === Cola.AST_Defun, _this = this, splatedexist = false;
@ -1357,6 +1396,7 @@ Cola.Parser.prototype.function_ = function(ctor, type) {
this.unexpected(); this.unexpected();
this.expect("("); this.expect("(");
return new ctor({ return new ctor({
mods: mods,
type: type, type: type,
name: name, name: name,
argnames: (function(first, a){ argnames: (function(first, a){
@ -1523,11 +1563,12 @@ Cola.Parser.prototype.vardefs = function (no_in, in_const, type) {
return a; return a;
}; };
Cola.Parser.prototype.var_ = function(no_in, type) { Cola.Parser.prototype.var_ = function(no_in, type, mods) {
(!type || type == "var") && (type = "dynamic"); (!type || type == "var") && (type = "dynamic");
return new Cola.AST_Var({ return new Cola.AST_Var({
start : this.prev(), start : this.prev(),
definitions : this.vardefs(no_in, false, type), definitions : this.vardefs(no_in, false, type),
mods : mods,
type : type, type : type,
end : this.prev() end : this.prev()
}); });
@ -1907,7 +1948,7 @@ Cola.Parser.prototype.object_ = Cola.Parser.embed_tokens(function(is_template, i
ptype = name == "var" ? "dynamic" : name; ptype = name == "var" ? "dynamic" : name;
name = this.as_name(); name = this.as_name();
} else ptype = false; } else ptype = false;
if (type == "name" && !this.is("punc", ":")) { if ((type == "name" || !this.is_js && type == "keyword") && !this.is("punc", ":")) {
if (name == "get") { if (name == "get") {
if (!this.is_js && is_object === false) this.unexpected(); if (!this.is_js && is_object === false) this.unexpected();
is_object = true; is_object = true;
@ -2253,7 +2294,7 @@ Cola.Parser.prototype.cascade = function(expr, start) {
|| last instanceof Cola.AST_Call || last instanceof Cola.AST_Call
|| last instanceof Cola.AST_PropAccess || last instanceof Cola.AST_PropAccess
|| last instanceof Cola.AST_Array || last instanceof Cola.AST_Array
)) this.unexpected(); )) this.unexpected(last.start);
} }
if (!this.is("punc", "..")) break; if (!this.is("punc", "..")) break;
} }

View File

@ -374,6 +374,111 @@ Cola.ContainCondAccess = function(node){
return false; return false;
}; };
Cola.DefPropWithMods = function(def, mods){
if(mods.length == 0) return new Cola.AST_Assign({
start : def.start,
end : def.end,
operator : '=',
left : def.name,
right : def.value
});
if(mods.indexOf("static") != -1)
Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, def.start, "Prop definition outside of class can't contain `static` modifer");
if(mods.indexOf("const") != -1 && !def.value)
Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, def.start, "`const` prop can't have `undefined` value");
var dp = { properties : [
new Cola.AST_ObjectKeyVal({
key : "value",
value : def.value
})
] };
if(mods.indexOf("const") == -1)
dp.properties.push(new Cola.AST_ObjectKeyVal({
key : "writable",
value : new Cola.AST_True
}));
if(mods.indexOf("covert") == -1)
dp.properties.push(new Cola.AST_ObjectKeyVal({
key : "enumerable",
value : new Cola.AST_True
}));
return new Cola.AST_Call({
args : [
def.name.expression,
def.name instanceof Cola.AST_Sub
? def.name.property
: new Cola.AST_String({ value: def.name.property }),
new Cola.AST_Object(dp)],
expression : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name: "Object" }),
property : "defineProperty"
})
});
};
Cola.DefFunWithMods = function(func, mods){
if(mods.length == 0) return new Cola.AST_Assign({
start : func.start,
end : func.end,
operator : '=',
left : func.name,
right : (function(node){
node.name = new Cola.AST_SymbolLambda({
start : node.name.start,
end : node.name.end,
name : node.name.property
});
return new Cola.AST_Function(node);
})(func)
});
if(mods.indexOf("static") != -1)
Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, func.start, "Function definition outside of class can't contain `static` modifer");
var sname = func.name, dp = { properties : [
new Cola.AST_ObjectKeyVal({
key : "value",
value : (function(node){
node.name = new Cola.AST_SymbolLambda({
start : node.name.start,
end : node.name.end,
name : node.name.property
});
return new Cola.AST_Function(node);
})(func)
}),
new Cola.AST_ObjectKeyVal({
key : "writable",
value : new Cola.AST_True
})
] };
if(mods.indexOf("covert") == -1)
dp.properties.push(new Cola.AST_ObjectKeyVal({
key : "enumerable",
value : new Cola.AST_True
}));
return new Cola.AST_Call({
args : [
sname.expression,
sname instanceof Cola.AST_Sub
? sname.property
: new Cola.AST_String({ value: sname.property }),
new Cola.AST_Object(dp)],
expression : new Cola.AST_Dot({
expression : new Cola.AST_SymbolRef({ name: "Object" }),
property : "defineProperty"
})
});
};
Cola.AST_Toplevel.prototype.toJavaScript = function(options){ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if(this.language == 'js') return this; if(this.language == 'js') return this;
@ -941,43 +1046,53 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
} else } else
/* /*
int obj.num = 0 const int num = 1, obj.num = 0;
to to
obj.num = 0 const num - 1;
Object.defineProperty(obj, "num", { value: 0, enumerable: true });
*/ */
if(node instanceof Cola.AST_Var){ if(node instanceof Cola.AST_Var){
var defCache = []; newNode = []; var defCache = []; newNode = [];
node.definitions.forEach(function(def, i){ node.definitions.forEach(function(def, i){
if(!(def.name instanceof Cola.AST_SymbolVar)){ if(def.name instanceof Cola.AST_SymbolVar){
if(!def.value)
Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, def.start, "`const` var can't have `undefined` value");
defCache.push(def);
} else if(def.value){
if(defCache.length != 0){ if(defCache.length != 0){
newNode.push(node.clone()); if(!node.mods || node.mods.length == 0 || node.mods.indexOf("const") != -1 && node.mods.length == 1){
newNode.push(node.mods.length == 1 ? new Cola.AST_Const(node) : node.clone());
newNode[newNode.length - 1].definitions = defCache; newNode[newNode.length - 1].definitions = defCache;
defCache = []; defCache = [];
} else
Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, node.start, "Var definition can contain only `const` modifer");
} }
newNode.push(new Cola.AST_Assign({ var texpr = def.name;
start : def.start, while(!(texpr.expression instanceof Cola.AST_SymbolVar)) texpr = texpr.expression;
end : def.end, texpr.expression = new Cola.AST_SymbolRef(texpr.expression);
operator : '=',
left : def.name,
right : def.value
}));
newNode.push(Cola.DefPropWithMods(def, node.mods));
newNode[newNode.length - 1] = new Cola.AST_SimpleStatement({ newNode[newNode.length - 1] = new Cola.AST_SimpleStatement({
body : newNode[newNode.length - 1] body : newNode[newNode.length - 1]
}); });
} else defCache.push(def); }
}); });
if(defCache.length != 0){ if(defCache.length != 0){
newNode.push(node.clone()); if(!node.mods || node.mods.length == 0 || node.mods.indexOf("const") != -1 && node.mods.length == 1){
newNode.push(node.mods && node.mods.length == 1 ? new Cola.AST_Const(node) : node.clone());
newNode[newNode.length - 1].definitions = defCache; newNode[newNode.length - 1].definitions = defCache;
defCache = []; defCache = [];
} else
Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, node.start, "Var definition can contain only `const` modifer");
} }
node = newNode; node = newNode;
@ -988,26 +1103,15 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
to to
Math.rand = function(){} Math.rand = function rand(){}
*/ */
if(node instanceof Cola.AST_Defun && !(node.name instanceof Cola.AST_SymbolDefun)){ if(node instanceof Cola.AST_Defun && !(node.name instanceof Cola.AST_SymbolDefun)){
var texpr = node.name; var texpr = node.name;
while(!(texpr.expression instanceof Cola.AST_SymbolDefun)) texpr = texpr.expression; while(!(texpr.expression instanceof Cola.AST_SymbolDefun)) texpr = texpr.expression;
texpr.expression = new Cola.AST_SymbolRef(texpr.expression); texpr.expression = new Cola.AST_SymbolRef(texpr.expression);
node = new Cola.AST_Assign({
start : node.start, node = Cola.DefFunWithMods(node, node.mods);
end : node.end,
operator : '=',
left : node.name,
right : (function(node){
node.name = new Cola.AST_SymbolLambda({
start : node.name.start,
end : node.name.end,
name : node.name.property
});
return new Cola.AST_Function(node);
})(node)
});
node = new Cola.AST_SimpleStatement({ node = new Cola.AST_SimpleStatement({
body : node body : node
}); });
@ -1074,6 +1178,9 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
if((node instanceof Cola.AST_Function || node instanceof Cola.AST_Defun) && node.argnames.length != 0){ if((node instanceof Cola.AST_Function || node instanceof Cola.AST_Defun) && node.argnames.length != 0){
var posed = [], named = [], onfront = true, delQueue = [], pos = 0, splated, aftersplated = -1; var posed = [], named = [], onfront = true, delQueue = [], pos = 0, splated, aftersplated = -1;
if(node.mods && node.mods.length != 0)
Cola.Parser.prototype.token_error.call(Cola.Parser.prototype, node.start, "Function definition outside of class can't contain any modifer");
node.argnames.forEach(function(val, i){ node.argnames.forEach(function(val, i){
if(val.argtype == "positional"){ if(val.argtype == "positional"){
if(val.defval instanceof Cola.AST_Noop && onfront && !val.required) pos++, node.argnames[i] = val.name; if(val.defval instanceof Cola.AST_Noop && onfront && !val.required) pos++, node.argnames[i] = val.name;
@ -1105,7 +1212,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
posed.forEach(function(val, i){ posed.forEach(function(val, i){
var pos = val.pos; val = val.val; var pos = val.pos; val = val.val;
console.log(val);
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({