ES6 for ...of is added
This commit is contained in:
parent
2a31e4a52c
commit
4db28f7851
|
|
@ -547,7 +547,8 @@ Future plans
|
|||
console.log(name);
|
||||
}, this);
|
||||
|
||||
- `@use client` and `@use server` commands
|
||||
- `@use client` and `@use server` commands, status: done
|
||||
- control flows without braces, status: done
|
||||
- static typing
|
||||
- `@use` expressions
|
||||
|
||||
|
|
|
|||
17
lib/ast.js
17
lib/ast.js
|
|
@ -281,6 +281,23 @@ Cola.AST_ForIn = Cola.DEFNODE("ForIn", "init name object", {
|
|||
}
|
||||
}, Cola.AST_IterationStatement);
|
||||
|
||||
Cola.AST_ForOf = Cola.DEFNODE("ForOf", "init name object", {
|
||||
$iscola: true,
|
||||
$documentation: "A `for ... of` statement",
|
||||
$propdoc: {
|
||||
init: "[AST_Node] the `for/in` initialization code",
|
||||
name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var",
|
||||
object: "[AST_Node] the object that we're looping through"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.init._walk(visitor);
|
||||
this.object._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, Cola.AST_IterationStatement);
|
||||
|
||||
Cola.AST_With = Cola.DEFNODE("With", "expression", {
|
||||
$documentation: "A `with` statement",
|
||||
$propdoc: {
|
||||
|
|
|
|||
|
|
@ -2243,19 +2243,19 @@ Cola.Compressor.MathFuncs = {
|
|||
return self;
|
||||
});
|
||||
|
||||
OPT(AST_Infinity, function (self, compressor) {
|
||||
return make_node(AST_Binary, self, {
|
||||
OPT(Cola.AST_Infinity, function (self, compressor) {
|
||||
return make_node(Cola.AST_Binary, self, {
|
||||
operator : '/',
|
||||
left : make_node(AST_Number, null, {value: 1}),
|
||||
right : make_node(AST_Number, null, {value: 0})
|
||||
left : make_node(Cola.AST_Number, null, {value: 1}),
|
||||
right : make_node(Cola.AST_Number, null, {value: 0})
|
||||
});
|
||||
});
|
||||
|
||||
OPT(AST_NaN, function (self, compressor) {
|
||||
return make_node(AST_Binary, self, {
|
||||
OPT(Cola.AST_NaN, function (self, compressor) {
|
||||
return make_node(Cola.AST_Binary, self, {
|
||||
operator : '/',
|
||||
left : make_node(AST_Number, null, {value: 0}),
|
||||
right : make_node(AST_Number, null, {value: 0})
|
||||
left : make_node(Cola.AST_Number, null, {value: 0}),
|
||||
right : make_node(Cola.AST_Number, null, {value: 0})
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
50
lib/parse.js
50
lib/parse.js
|
|
@ -49,7 +49,7 @@
|
|||
!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.cKEYWORDS = Cola.KEYWORDS.replace(' void', '') + ' static covert export async get set when clone is isnt class extends singleton resolve reject await';
|
||||
Cola.cKEYWORDS = Cola.KEYWORDS.replace(' void', '') + ' static covert export async get set when clone of is isnt class extends singleton resolve reject await';
|
||||
|
||||
Cola.KEYWORDS_ATOM = 'false null true';
|
||||
Cola.cKEYWORDS_ATOM = Cola.KEYWORDS_ATOM + ' on yes off no';
|
||||
|
|
@ -127,6 +127,7 @@ Cola.OPERATORS = [ // d - different left and right types of vars, s - same
|
|||
// ColaScript
|
||||
"await",
|
||||
"clone",
|
||||
"of",
|
||||
"is",
|
||||
"isnt",
|
||||
"**",
|
||||
|
|
@ -813,7 +814,7 @@ Cola.cPRECEDENCE = Cola.mergeTokens(
|
|||
["^"],
|
||||
["&"],
|
||||
["==", "===", "!=", "!=="],
|
||||
["<", ">", "<=", ">=", "in", "instanceof", "is", "isnt"],
|
||||
["<", ">", "<=", ">=", "in", "of", "instanceof", "is", "isnt"],
|
||||
[">>", "<<", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%", "**", "%%"]
|
||||
|
|
@ -840,7 +841,8 @@ Cola.Parser = function ($TEXT, options) {
|
|||
toplevel : null,
|
||||
expression : false,
|
||||
html5_comments : true,
|
||||
is_js : false
|
||||
is_js : false,
|
||||
braces_free : true
|
||||
});
|
||||
|
||||
this.is_js = !!this.options.is_js;
|
||||
|
|
@ -972,14 +974,14 @@ Cola.Parser.prototype.unexpected = function (token) {
|
|||
this.token_error(token, "Unexpected token: " + token.type + " `" + token.value + "`");
|
||||
};
|
||||
|
||||
Cola.Parser.prototype.expect_token = function (type, val) {
|
||||
Cola.Parser.prototype.expect_token = function (type, val, stay) {
|
||||
if (this.is(type, val)) {
|
||||
return this.next();
|
||||
return stay ? undefined : this.next();
|
||||
}
|
||||
this.token_error(this.S.token, "Unexpected token " + this.S.token.type + " `" + this.S.token.value + "`" + ", expected " + type + " `" + val + "`");
|
||||
};
|
||||
|
||||
Cola.Parser.prototype.expect = function (punc) { return this.expect_token("punc", punc); };
|
||||
Cola.Parser.prototype.expect = function (punc, stay) { return this.expect_token("punc", punc, stay); };
|
||||
|
||||
Cola.Parser.prototype.can_insert_semicolon = function () {
|
||||
if(!this.is_js) return false;
|
||||
|
|
@ -994,9 +996,10 @@ Cola.Parser.prototype.semicolon = function () {
|
|||
};
|
||||
|
||||
Cola.Parser.prototype.parenthesised = function () {
|
||||
this.expect("(");
|
||||
if (this.is_js || !this.options.braces_free) this.expect("(");
|
||||
var exp = this.expression(true);
|
||||
this.expect(")");
|
||||
if (this.is_js || !this.options.braces_free) this.expect(")");
|
||||
else this.expect("{", true);
|
||||
return exp;
|
||||
};
|
||||
|
||||
|
|
@ -1519,17 +1522,24 @@ Cola.Parser.prototype.break_cont = function (type) {
|
|||
};
|
||||
|
||||
Cola.Parser.prototype.for_ = function () {
|
||||
this.expect("(");
|
||||
if (this.is_js || !this.options.braces_free) this.expect("(");
|
||||
var init = null;
|
||||
if (!this.is("punc", ";")) {
|
||||
init = this.is("keyword", "var") || !this.is_js && this.is("name") && this.next_is("name")
|
||||
? (this.next(), this.var_(true, this.prev().value))
|
||||
: this.expression(true, true);
|
||||
|
||||
if (this.is("operator", "in")) {
|
||||
if (init instanceof Cola.AST_Var && init.definitions.length > 1)
|
||||
this.croak("Only one variable declaration allowed in for..in loop");
|
||||
this.next();
|
||||
return this.for_in(init);
|
||||
} else
|
||||
if (!this.is_js && this.is("operator", "of")) {
|
||||
if (init instanceof Cola.AST_Var && init.definitions.length > 1)
|
||||
this.croak("Only one variable declaration allowed in for..of loop");
|
||||
this.next();
|
||||
return this.for_of(init);
|
||||
}
|
||||
}
|
||||
return this.regular_for(init);
|
||||
|
|
@ -1540,7 +1550,8 @@ Cola.Parser.prototype.regular_for = function (init) {
|
|||
var test = this.is("punc", ";") ? null : this.expression(true);
|
||||
this.expect(";");
|
||||
var step = this.is("punc", ")") ? null : this.expression(true);
|
||||
this.expect(")");
|
||||
if (this.is_js || !this.options.braces_free) this.expect(")");
|
||||
else this.expect("{", true);
|
||||
var _this = this;
|
||||
return new Cola.AST_For({
|
||||
init : init,
|
||||
|
|
@ -1553,7 +1564,8 @@ Cola.Parser.prototype.regular_for = function (init) {
|
|||
Cola.Parser.prototype.for_in = function (init) {
|
||||
var lhs = init instanceof Cola.AST_Var ? init.definitions[0].name : null;
|
||||
var obj = this.expression(true);
|
||||
this.expect(")");
|
||||
if (this.is_js || !this.options.braces_free) this.expect(")");
|
||||
else this.expect("{", true);
|
||||
var _this = this;
|
||||
return new Cola.AST_ForIn({
|
||||
init : init,
|
||||
|
|
@ -1563,6 +1575,20 @@ Cola.Parser.prototype.for_in = function (init) {
|
|||
});
|
||||
};
|
||||
|
||||
Cola.Parser.prototype.for_of = function (init) {
|
||||
var lhs = init instanceof Cola.AST_Var ? init.definitions[0].name : null;
|
||||
var obj = this.expression(true);
|
||||
if (!this.options.braces_free) this.expect(")");
|
||||
else this.expect("{", true);
|
||||
var _this = this;
|
||||
return new Cola.AST_ForOf({
|
||||
init : init,
|
||||
name : lhs,
|
||||
object : obj,
|
||||
body : this.in_loop(function(){ return this.statement() })
|
||||
});
|
||||
};
|
||||
|
||||
Cola.Parser.prototype.class_ = function(mods){
|
||||
if(this.S.in_class)
|
||||
this.token_error(this.prev(), "You can define class or singleton only in root scope.");
|
||||
|
|
@ -2579,7 +2605,7 @@ Cola.Parser.prototype.make_unary = function (ctor, op, expr) {
|
|||
*/
|
||||
Cola.Parser.prototype.expr_op = function(left, min_prec, no_in, is_comp, rightest) {
|
||||
var op = this.is("operator") ? this.S.token.value : null, cop = Cola.COMPARISON(op);
|
||||
if (op == "in" && no_in) op = null;
|
||||
if ((op == "in" || op == "of") && no_in) op = null;
|
||||
var prec = op != null ? this.PRECEDENCE[op] : null;
|
||||
if (!this.is_js && is_comp && cop) {
|
||||
this.next();
|
||||
|
|
|
|||
|
|
@ -2991,6 +2991,46 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
|
|||
node = branches;
|
||||
} else
|
||||
|
||||
/*
|
||||
for _ of [0...9] {
|
||||
|
||||
}
|
||||
|
||||
to
|
||||
|
||||
var _ColaRuntime$$forOfHolder;
|
||||
for (_ in [0...9]) {
|
||||
_ = _ColaRuntime$$forOfHolder[_];
|
||||
}
|
||||
|
||||
*/
|
||||
if(node instanceof Cola.AST_ForOf){
|
||||
node = new Cola.AST_ForIn(node);
|
||||
newNode = [new Cola.AST_Var({
|
||||
type : "dynamic",
|
||||
definitions : [new Cola.AST_VarDef({
|
||||
type : "dynamic",
|
||||
name : new Cola.AST_SymbolVar({ name: '_ColaRuntime$$forOfHolder' })
|
||||
})]}), node];
|
||||
|
||||
node.object = new Cola.AST_Assign({
|
||||
operator : '=',
|
||||
left : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$forOfHolder" }),
|
||||
right : node.object
|
||||
});
|
||||
|
||||
node.body.body.unshift(new Cola.AST_SimpleStatement({ body : new Cola.AST_Assign({
|
||||
operator : '=',
|
||||
left : new Cola.AST_SymbolRef(node.name || node.init),
|
||||
right : new Cola.AST_Sub({
|
||||
expression : new Cola.AST_SymbolRef({ name : "_ColaRuntime$$forOfHolder" }),
|
||||
property : new Cola.AST_SymbolRef(node.name || node.init)
|
||||
})
|
||||
})}));
|
||||
|
||||
node = newNode;
|
||||
} else
|
||||
|
||||
/*
|
||||
MyClass::prop = (){
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user