new syntax added

`some?? || isset some`, `Type some, some2`, `a ? b`
This commit is contained in:
Onoshko Dan 2014-04-19 01:27:47 +07:00
parent 1f50f97757
commit e1a702e9a1
5 changed files with 70 additions and 22 deletions

View File

@ -9,9 +9,10 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
## Operators: ## Operators:
### Unary ### Unary
- `varname?` - `varname??` and alternative `isset varname` - which is better? status: done
bool exist = SOME?; bool exist = SOME??;
bool exist2 = isset SOME;
### Binary ### Binary
@ -31,13 +32,13 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
undef = 6; undef = 6;
def ?= undef; // def == 6 def ?= undef; // def == 6
- `a ? b` - `a ? b`, status: done
int a = 5, b = 3; var a = undefined, b = 3;
a = a > 10 ? b; // a == 5 a ? b == 3;
a = 11; a = 11;
a = a > 10 ? b; // a == 3 a ? b == 1;
- `is`, status: done - `is`, status: done
@ -116,7 +117,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
## Vars ## Vars
- declaration with type - declaration with type, status: done, only declaration
int b = 584; int b = 584;
Array arr = []; Array arr = [];

View File

@ -108,6 +108,8 @@ Cola.AST_Node = Cola.DEFNODE("Node", "start end", {
} }
}, null); }, null);
Cola.AST_Noop = Cola.DEFNODE("Noop", null, null, Cola.AST_Node);
Cola.AST_Node.warn_function = null; Cola.AST_Node.warn_function = null;
Cola.AST_Node.warn = function(txt, props) { Cola.AST_Node.warn = function(txt, props) {
if (Cola.AST_Node.warn_function) if (Cola.AST_Node.warn_function)
@ -535,7 +537,7 @@ Cola.AST_Definitions = Cola.DEFNODE("Definitions", "definitions", {
} }
}, Cola.AST_Statement); }, Cola.AST_Statement);
Cola.AST_Var = Cola.DEFNODE("Var", null, { Cola.AST_Var = Cola.DEFNODE("Var", "type", {
$documentation: "A `var` statement" $documentation: "A `var` statement"
}, Cola.AST_Definitions); }, Cola.AST_Definitions);

View File

@ -1167,7 +1167,7 @@ Cola.OutputStream.prototype.parent = function(n) {
// innermost node in the current output) is lexically the first in // innermost node in the current output) is lexically the first in
// a statement. // a statement.
function first_in_statement(output) { function first_in_statement(output) {
var a = output.stack(), i = a.length, node = a[--i], p = a[--i]; var a = output.stack, i = a.length, node = a[--i], p = a[--i];
while (i > 0) { while (i > 0) {
if (p instanceof Cola.AST_Statement && p.body === node) if (p instanceof Cola.AST_Statement && p.body === node)
return true; return true;

View File

@ -49,7 +49,7 @@
!window.Cola && (window.Cola = {}); !window.Cola && (window.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', '') + ' is isnt class singleton injector'; Cola.cKEYWORDS = Cola.KEYWORDS.replace(' void', '') + ' isset 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';
@ -123,16 +123,18 @@ Cola.OPERATORS = [
"&&", "&&",
"||", "||",
// ColaScript // ColaScript
"isset",
"is", "is",
"isnt", "isnt",
"**", "**",
"%%", "%%",
"?=" "?=",
"??"
]; ];
Cola.cOPERATORS = Cola.makePredicate(Cola.OPERATORS); Cola.cOPERATORS = Cola.makePredicate(Cola.OPERATORS);
Cola.OPERATORS = Cola.OPERATORS.slice(0, Cola.OPERATORS.length - 5); Cola.OPERATORS = Cola.OPERATORS.slice(0, Cola.OPERATORS.length - 7);
Cola.OPERATORS.push('void'); Cola.OPERATORS.push('void');
Cola.OPERATORS = Cola.makePredicate(Cola.OPERATORS); Cola.OPERATORS = Cola.makePredicate(Cola.OPERATORS);
@ -263,10 +265,12 @@ Cola.Tokenizer = function ($TEXT, filename, is_js, html5_comments) {
this.KEYWORDS = Cola.KEYWORDS; this.KEYWORDS = Cola.KEYWORDS;
this.KEYWORDS_ATOM = Cola.KEYWORDS_ATOM; this.KEYWORDS_ATOM = Cola.KEYWORDS_ATOM;
this.OPERATORS = Cola.OPERATORS; this.OPERATORS = Cola.OPERATORS;
this.UNARY_POSTFIX = Cola.UNARY_POSTFIX;
} else { } else {
this.KEYWORDS = Cola.cKEYWORDS; this.KEYWORDS = Cola.cKEYWORDS;
this.KEYWORDS_ATOM = Cola.cKEYWORDS_ATOM; this.KEYWORDS_ATOM = Cola.cKEYWORDS_ATOM;
this.OPERATORS = Cola.cOPERATORS; this.OPERATORS = Cola.cOPERATORS;
this.UNARY_POSTFIX = Cola.cUNARY_POSTFIX;
} }
this.is_js = !!is_js; this.is_js = !!is_js;
@ -331,7 +335,7 @@ Cola.Tokenizer.prototype.start_token = function () {
}; };
Cola.Tokenizer.prototype.token = function (type, value, is_comment) { Cola.Tokenizer.prototype.token = function (type, value, is_comment) {
this.S.regex_allowed = ((type == "operator" && !Cola.UNARY_POSTFIX(value)) || this.S.regex_allowed = ((type == "operator" && !this.UNARY_POSTFIX(value)) ||
(type == "keyword" && Cola.KEYWORDS_BEFORE_EXPRESSION(value)) || (type == "keyword" && Cola.KEYWORDS_BEFORE_EXPRESSION(value)) ||
(type == "punc" && Cola.PUNC_BEFORE_EXPRESSION(value))); (type == "punc" && Cola.PUNC_BEFORE_EXPRESSION(value)));
this.prev_was_dot = (type == "punc" && value == "."); this.prev_was_dot = (type == "punc" && value == ".");
@ -717,6 +721,7 @@ Cola.UNARY_PREFIX = Cola.makePredicate([
"+" "+"
]); ]);
Cola.cUNARY_PREFIX = Cola.makePredicate([ Cola.cUNARY_PREFIX = Cola.makePredicate([
"isset",
"typeof", "typeof",
"delete", "delete",
"--", "--",
@ -728,9 +733,10 @@ Cola.cUNARY_PREFIX = Cola.makePredicate([
]); ]);
Cola.UNARY_POSTFIX = Cola.makePredicate([ "--", "++" ]); Cola.UNARY_POSTFIX = Cola.makePredicate([ "--", "++" ]);
Cola.cUNARY_POSTFIX = Cola.makePredicate([ "--", "++", "??" ]);
Cola.ASSIGNMENT = Cola.makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]); Cola.ASSIGNMENT = Cola.makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
Cola.cASSIGNMENT = Cola.makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="/* ColaScript */, "?=" ]); Cola.cASSIGNMENT = Cola.makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=", "?=" ]);
Cola.mergeTokens = function (a, ret) { Cola.mergeTokens = function (a, ret) {
for (var i = 0; i < a.length; ++i) { for (var i = 0; i < a.length; ++i) {
@ -787,8 +793,6 @@ Cola.parse = function ($TEXT, options) {
Cola.Parser = function ($TEXT, options) { Cola.Parser = function ($TEXT, options) {
var _this = this; var _this = this;
this.is_js = !!options.is_js;
this.options = Cola.defaults(options, { this.options = Cola.defaults(options, {
strict : false, strict : false,
filename : null, filename : null,
@ -798,6 +802,7 @@ Cola.Parser = function ($TEXT, options) {
is_js : false is_js : false
}); });
this.is_js = !!this.options.is_js;
this.tokenizer = typeof $TEXT == "string" ? new Cola.Tokenizer($TEXT, this.options.filename, this.is_js, this.options.html5_comments) : $TEXT; this.tokenizer = typeof $TEXT == "string" ? new Cola.Tokenizer($TEXT, this.options.filename, this.is_js, this.options.html5_comments) : $TEXT;
this.S = { this.S = {
@ -817,10 +822,12 @@ Cola.Parser = function ($TEXT, options) {
this.UNARY_PREFIX = Cola.UNARY_PREFIX; this.UNARY_PREFIX = Cola.UNARY_PREFIX;
this.PRECEDENCE = Cola.PRECEDENCE; this.PRECEDENCE = Cola.PRECEDENCE;
this.ASSIGNMENT = Cola.ASSIGNMENT; this.ASSIGNMENT = Cola.ASSIGNMENT;
this.UNARY_POSTFIX = Cola.UNARY_POSTFIX;
} else { } else {
this.UNARY_PREFIX = Cola.cUNARY_PREFIX; this.UNARY_PREFIX = Cola.cUNARY_PREFIX;
this.PRECEDENCE = Cola.cPRECEDENCE; this.PRECEDENCE = Cola.cPRECEDENCE;
this.ASSIGNMENT = Cola.cASSIGNMENT; this.ASSIGNMENT = Cola.cASSIGNMENT;
this.UNARY_POSTFIX = Cola.cUNARY_POSTFIX;
} }
}; };
@ -938,7 +945,7 @@ Cola.Parser.prototype.handle_regexp = function () {
}; };
Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() { Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
var tmp, _this = this; var tmp, type, _this = this;
this.handle_regexp(); this.handle_regexp();
switch (this.S.token.type) { switch (this.S.token.type) {
case "string": case "string":
@ -954,6 +961,7 @@ Cola.Parser.prototype.statement = Cola.Parser.embed_tokens(function() {
return this.simple_statement(); return this.simple_statement();
case "name": case "name":
if(Cola.is_token(this.peek(), "name")) return type = this.S.token.value, this.next(), tmp = this.var_(false, type), this.semicolon(), tmp;
return Cola.is_token(this.peek(), "punc", ":") return Cola.is_token(this.peek(), "punc", ":")
? this.labeled_statement() ? this.labeled_statement()
: this.simple_statement(); : this.simple_statement();
@ -1288,10 +1296,12 @@ Cola.Parser.prototype.vardefs = function (no_in, in_const) {
return a; return a;
}; };
Cola.Parser.prototype.var_ = function(no_in) { Cola.Parser.prototype.var_ = function(no_in, type) {
!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,
end : this.prev() end : this.prev()
}); });
}; };
@ -1609,7 +1619,7 @@ Cola.Parser.prototype.maybe_unary = function(allow_calls) {
return ex; return ex;
} }
var val = this.expr_atom(allow_calls); var val = this.expr_atom(allow_calls);
while (this.is("operator") && Cola.UNARY_POSTFIX(this.S.token.value) && !this.S.token.nlb) { while (this.is("operator") && this.UNARY_POSTFIX(this.S.token.value) && !this.S.token.nlb) {
val = this.make_unary(Cola.AST_UnaryPostfix, this.S.token.value, val); val = this.make_unary(Cola.AST_UnaryPostfix, this.S.token.value, val);
val.start = start; val.start = start;
val.end = this.S.token; val.end = this.S.token;
@ -1652,12 +1662,12 @@ Cola.Parser.prototype.maybe_conditional = function(no_in) {
if (this.is("operator", "?")) { if (this.is("operator", "?")) {
this.next(); this.next();
var yes = this.expression(false); var yes = this.expression(false);
this.expect(":");
return new Cola.AST_Conditional({ return new Cola.AST_Conditional({
start : start, start : start,
condition : expr, condition : expr,
consequent : yes, consequent : yes,
alternative : this.expression(false, no_in), alternative : this.is_js || this.is('punc',':') ? (this.expect(":"), this.expression(false, no_in)) : new Cola.AST_Noop(),
end : this.prev() end : this.prev()
}); });
} }

View File

@ -113,7 +113,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(){
name : '$_cola_isntset', name : '$_cola_isntset',
start : props.start, start : props.start,
end : props.start end : props.start
}); });
node = new Cola.AST_Conditional({ node = new Cola.AST_Conditional({
start : new Cola.AST_Token({ nlb : false, type : 'punc', value : '(' }), start : new Cola.AST_Token({ nlb : false, type : 'punc', value : '(' }),
@ -124,6 +124,25 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(){
}); });
} else } else
if(node instanceof Cola.AST_Conditional && node.alternative instanceof Cola.AST_Noop){
$_cola_hash[$_cola_isset.i] = true;
props = {
args : [node.condition],
start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isset' }),
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
};
props.expression = new Cola.AST_SymbolRef({
name : '$_cola_isset',
start : props.start,
end : props.start
});
node.alternative = node.consequent;
node.consequent = node.condition;
node.condition = new Cola.AST_Call(props);
} else
if(node instanceof Cola.AST_Binary && node.operator == 'is'){ if(node instanceof Cola.AST_Binary && node.operator == 'is'){
$_cola_hash[$_cola_is.i] = true; $_cola_hash[$_cola_is.i] = true;
props = { props = {
@ -156,6 +175,22 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(){
node = new Cola.AST_Call(props); node = new Cola.AST_Call(props);
} else } else
if(node instanceof Cola.AST_UnaryPostfix && node.operator == '??' || node instanceof Cola.AST_UnaryPrefix && node.operator == 'isset'){
$_cola_hash[$_cola_isset.i] = true;
props = {
args : [node.expression],
start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isset' }),
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
};
props.expression = new Cola.AST_SymbolRef({
name : '$_cola_isset',
start : props.start,
end : props.start
});
node = new Cola.AST_Call(props);
} else
if(node instanceof Cola.AST_StringTemplate){ if(node instanceof Cola.AST_StringTemplate){
newNode = new Cola.AST_Binary({ newNode = new Cola.AST_Binary({
operator : '+', operator : '+',