Cascade operator added, function arguments fixed.

This commit is contained in:
Onoshko Dan 2014-05-03 18:40:47 +07:00
parent ff64dec3f7
commit af6f8ebf7b
6 changed files with 228 additions and 37 deletions

View File

@ -61,7 +61,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
### Multiple ### Multiple
- `..:` - `..:`, status: done
Object profile = { Object profile = {
name : "dan", name : "dan",
@ -104,7 +104,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
## Expressions ## Expressions
- `switch` assigmention - `switch` assignment
String weather = switch(temperature){ String weather = switch(temperature){
case -10: 'cold'; case -10: 'cold';
@ -133,7 +133,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
Object obj = {}; Object obj = {};
String str = ""; String str = "";
- multiple assigment - multiple assignment
[a, b, c] = [b, c, a]; [a, b, c] = [b, c, a];
{poet: {String name, address: [street, city]}} = futurists; {poet: {String name, address: [street, city]}} = futurists;
@ -190,7 +190,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
arr[] = 4; // [3, 5, 6, 7, 4] arr[] = 4; // [3, 5, 6, 7, 4]
console.log(arr[]); // 4 console.log(arr[]); // 4
- part assigment, status: done - part assignment, status: done
arr[0..2] = [0,1]; // [0, 1, 7, 4] arr[0..2] = [0,1]; // [0, 1, 7, 4]
arr[0..2] = []; // [7, 4] arr[0..2] = []; // [7, 4]
@ -325,5 +325,5 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
### Statistic ### Statistic
- 34 feature ( without classes ) - 34 features ( without classes )
- 26 done - 27 done

View File

@ -20,7 +20,7 @@ main(){
// `modulo` operator // `modulo` operator
console.log("10 %% 4 = ", 10 %% 4); console.log("10 %% 4 = ", 10 %% 4);
// `isset` conditional assigment // `isset` conditional assignment
int a, b = 4; int a, b = 4;
console.log("`a` is", a, ", now `a` is", a ?= b); console.log("`a` is", a, ", now `a` is", a ?= b);
console.log("`a` is", a, ", now `a` still", a ?= 584); console.log("`a` is", a, ", now `a` still", a ?= 584);
@ -65,25 +65,36 @@ main(){
console.log("@email {{ isEmail.test(email) ? "is" : "isnt" }} valid email adress"); console.log("@email {{ isEmail.test(email) ? "is" : "isnt" }} valid email adress");
// Arrays // Arrays
// Empty getter and setter ( pushig ) // Empty getter and setter ( pushing )
Array arr = [2, 4, 8, 16, 32]; Array arr = [2, 4, 8, 16, 32];
console.log("Last element of `arr` is", arr[]), arr[] = 64; console.log("Last element of `arr` is", arr[]), arr[] = 64;
console.log("Now last element of `arr` is", arr[]); console.log("Now last element of `arr` is", arr[]);
// Splice assigment // Splice assignment
arr[2..4] = [3, 2, 1]; arr[2..4] = [3, 2, 1];
console.log("`arr` is", arr); console.log("`arr` is", arr);
// Range // Range
console.log("`[0..10]` is", [0..10]); console.log("`[0..10]` is", [0..10]);
// Calling function // Calling function
console.log(Profile( Object pro;
"Dan", "Green", console.log(pro = Profile(
"Dan", "Green", "Russia",
"HTML5", "JavaScript", "Dart", "PHP", "CSS3", "LESS", "Qt", "HTML5", "JavaScript", "Dart", "PHP", "CSS3", "LESS", "Qt",
age : 19, age : 19,
petName : "Felix" petName : "Felix"
)); ));
// Cascade operator
pro
..firstName += "iil"
..secondName = "Onoshko"
..skills:
..[1] = "JS";
;
console.log(pro);
} }
// Functions // Functions
@ -100,3 +111,5 @@ Object Profile(String firstName, String secondName, String country = "Russia", A
petName : petName petName : petName
}; };
} }
main();

View File

@ -675,6 +675,22 @@ Cola.AST_Dot = Cola.DEFNODE("Dot", null, {
} }
}, Cola.AST_PropAccess); }, Cola.AST_PropAccess);
Cola.AST_Cascade = Cola.DEFNODE("Cascade", "expression subexpressions", {
$documentation: "Base class for properties access expressions, i.e. `a..foo..bar`",
$propdoc: {
expression: "[AST_Node] the “container” expression",
subexpressions: "[AST_Node*] actions with properties"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
this.expression._walk(visitor);
this.subexpressions.forEach(function(el){
el._walk(visitor);
});
});
}
});
Cola.AST_Sub = Cola.DEFNODE("Sub", null, { Cola.AST_Sub = Cola.DEFNODE("Sub", null, {
$documentation: "Index-style property access, i.e. `a[\"foo\"]`", $documentation: "Index-style property access, i.e. `a[\"foo\"]`",
_walk: function(visitor) { _walk: function(visitor) {

View File

@ -31,10 +31,12 @@
box-sizing: border-box; box-sizing: border-box;
width: 33.333%; width: 33.333%;
height: 100%; height: 100%;
font-size: 12px; font-size: 15px;
float: left; float: left;
font-family: "Andale Mono"; font-family: "Andale Mono";
padding: 0 5px 26px 5px; padding: 0 5px 26px 5px;
background-color: #272A32;
color: #D6D7D9;
} }
#controls { #controls {
@ -51,6 +53,9 @@
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 2px 0 0 2px;
} }
#controls .bg { #controls .bg {
@ -60,12 +65,12 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: white; background-color: white;
opacity: 0.5; opacity: 0.8;
} }
#lenstat { #lenstat {
float: right; float: right;
margin: 5px 8px 0 0; margin: 2px 10px;
} }
</style> </style>
@ -93,7 +98,7 @@ main(){
// `modulo` operator // `modulo` operator
console.log("10 %% 4 = ", 10 %% 4); console.log("10 %% 4 = ", 10 %% 4);
// `isset` conditional assigment // `isset` conditional assignment
int a, b = 4; int a, b = 4;
console.log("`a` is", a, ", now `a` is", a ?= b); console.log("`a` is", a, ", now `a` is", a ?= b);
console.log("`a` is", a, ", now `a` still", a ?= 584); console.log("`a` is", a, ", now `a` still", a ?= 584);
@ -138,25 +143,36 @@ main(){
console.log("@email {{ isEmail.test(email) ? "is" : "isnt" }} valid email adress"); console.log("@email {{ isEmail.test(email) ? "is" : "isnt" }} valid email adress");
// Arrays // Arrays
// Empty getter and setter ( pushig ) // Empty getter and setter ( pushing )
Array arr = [2, 4, 8, 16, 32]; Array arr = [2, 4, 8, 16, 32];
console.log("Last element of `arr` is", arr[]), arr[] = 64; console.log("Last element of `arr` is", arr[]), arr[] = 64;
console.log("Now last element of `arr` is", arr[]); console.log("Now last element of `arr` is", arr[]);
// Splice assigment // Splice assignment
arr[2..4] = [3, 2, 1]; arr[2..4] = [3, 2, 1];
console.log("`arr` is", arr); console.log("`arr` is", arr);
// Range // Range
console.log("`[0..10]` is", [0..10]); console.log("`[0..10]` is", [0..10]);
// Calling function // Calling function
console.log(Profile( Object pro;
"Dan", "Green", console.log(pro = Profile(
"Dan", "Green", "Russia",
"HTML5", "JavaScript", "Dart", "PHP", "CSS3", "LESS", "Qt", "HTML5", "JavaScript", "Dart", "PHP", "CSS3", "LESS", "Qt",
age : 19, age : 19,
petName : "Felix" petName : "Felix"
)); ));
// Cascade operator
pro
..firstName += "iil"
..secondName = "Onoshko"
..skills:
..[1] = "JS";
;
console.log(pro);
} }
// Functions // Functions
@ -173,14 +189,16 @@ Object Profile(String firstName, String secondName, String country = "Russia", A
petName : petName petName : petName
}; };
} }
</textarea>
main();</textarea>
<textarea id="translation"></textarea> <textarea id="translation"></textarea>
<textarea id="result"></textarea> <textarea id="result"></textarea>
<div id="controls"> <div id="controls">
<div class="bg">&nbsp;</div> <div class="bg">&nbsp;</div>
<div class="m"> <div class="m">
<button id="exec" onclick="exec()">Execute</button> <button id="exec" onclick="exec()">Execute</button>
<button id="benchmark" onclick="benchmark()">Benchmark</button> <button onclick="benchmarkTranslate()">Benchmark Translation</button>
<button onclick="benchmarkResult()">Benchmark Result</button>
<input type="checkbox" id="is_js" onclick="compile()"> <input type="checkbox" id="is_js" onclick="compile()">
<label for="is_js">js parser</label> <label for="is_js">js parser</label>
<input type="checkbox" id="main_binding" onclick="compile()"> <input type="checkbox" id="main_binding" onclick="compile()">
@ -239,10 +257,16 @@ Object Profile(String firstName, String secondName, String country = "Russia", A
document.querySelector('#lenstat').innerHTML = sourceArea.value.length+" : "+translationArea.value.length+" : "+resultArea.value.length; document.querySelector('#lenstat').innerHTML = sourceArea.value.length+" : "+translationArea.value.length+" : "+resultArea.value.length;
} }
function benchmark(){ function benchmarkResult(){
console.time("ColaScript"); console.time("Result");
eval(resultArea.result); eval(resultArea.value);
console.timeEnd("ColaScript"); console.timeEnd("Result");
}
function benchmarkTranslate(){
console.time("Translation");
eval(translationArea.value);
console.timeEnd("Translation");
} }
function exec(){ function exec(){

View File

@ -1648,12 +1648,12 @@ Cola.Parser.prototype.array_ = Cola.Parser.embed_tokens(function() {
if(!this.is_js && !this.is("punc","]")){ if(!this.is_js && !this.is("punc","]")){
this.dumpS(); this.dumpS();
var tmp, from = this.expression(true); var tmp, from = this.expression(true, false, true);
if(this.is("punc","..")){ if(this.is("punc","..")){
this.next(); this.next();
return new Cola.AST_ArrayRange({ return new Cola.AST_ArrayRange({
from : from, from : from,
to : (tmp = this.expression(true), this.expect("]"), tmp), to : (tmp = this.expression(true, false, true), this.expect("]"), tmp),
start : from.start, start : from.start,
end : this.prev() end : this.prev()
}); });
@ -1776,13 +1776,13 @@ Cola.Parser.prototype.subscripts = function(expr, allow_calls) {
if(this.is_js) prop = this.expression(true); if(this.is_js) prop = this.expression(true);
else if(this.is("punc","]")) prop = new Cola.AST_Noop(); else if(this.is("punc","]")) prop = new Cola.AST_Noop();
else { else {
prop = this.expression(true); prop = this.expression(true, false, true);
this.dumpS(); this.dumpS();
if(this.is("punc","..")){ if(this.is("punc","..")){
this.next(); this.next();
prop = new Cola.AST_ArrayRange({ prop = new Cola.AST_ArrayRange({
from : prop, from : prop,
to : this.expression(true), to : this.expression(true, false, true),
start : prop.start, start : prop.start,
end : this.prev() end : this.prev()
}); });
@ -1900,9 +1900,39 @@ Cola.Parser.prototype.maybe_assign = function(no_in) {
return left; return left;
}; };
Cola.Parser.prototype.expression = function(commas, no_in) { Cola.Parser.prototype.cascade = function(expr, start) {
var last, props = {
start : start,
expression : expr,
subexpressions : []
};
while (this.next()) {
if (this.is("name") || this.is("punc","[")) {
last = this.expression(false, false, true);
if (this.is("punc", ":")) {
last = this.cascade(last, last.start);
this.next();
}
props.subexpressions.push(last);
if (!( last instanceof Cola.AST_SymbolRef
|| last instanceof Cola.AST_Binary
|| last instanceof Cola.AST_Call
|| last instanceof Cola.AST_Sub
|| last instanceof Cola.AST_Dot
|| last instanceof Cola.AST_Array
|| last instanceof Cola.AST_Cascade
)) this.unexpected();
}
if (!this.is("punc", "..")) break;
}
props.end = this.S.token;
return new Cola.AST_Cascade(props);
};
Cola.Parser.prototype.expression = function(commas, no_in, in_dd) {
var start = this.S.token; var start = this.S.token;
var expr = this.maybe_assign(no_in); var expr = this.maybe_assign(no_in);
if (!in_dd && !this.is_js && this.is("punc", "..")) return this.cascade(expr, start);
if (commas && this.is("punc", ",")) { if (commas && this.is("punc", ",")) {
this.next(); this.next();
return new Cola.AST_Seq({ return new Cola.AST_Seq({

View File

@ -571,7 +571,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
} else if(val.argtype == "splated"){ } else if(val.argtype == "splated"){
onfront = false; onfront = false;
delQueue.push(i); delQueue.push(i);
splated = { pos : pos++, after : 0, val : val }; posed.push(splated = { pos : pos++, after : 0, val : val });
} }
}); });
@ -587,8 +587,8 @@ 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;
if(splated && (pos - 1 == splated.pos || pos + 1 == splated.pos)){ if(val.argtype == "splated"){
aftersplated = 0; aftersplated = 0;
props.definitions.push(new Cola.AST_VarDef({ props.definitions.push(new Cola.AST_VarDef({
name : new Cola.AST_SymbolRef({ name : '$_cola_i' }), name : new Cola.AST_SymbolRef({ name : '$_cola_i' }),
@ -641,9 +641,8 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
}) })
}) })
})); }));
splated = false;
} }
else
if(val.defval instanceof Cola.AST_Noop) props.definitions.push(new Cola.AST_VarDef({ if(val.defval instanceof Cola.AST_Noop) props.definitions.push(new Cola.AST_VarDef({
name : val.name, name : val.name,
@ -732,6 +731,115 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
} }
} else } else
/*
obj
..[0] = yes
..foo = bar
..baz()
..sub:
..subfoo = no
..subaz();
;
to
(function($_cola_ml_expr){
$_cola_ml_expr[0] = yes;
$_cola_ml_expr.foo = bar;
$_cola_ml_expr.baz();
(function($_cola_ml_expr){
$_cola_ml_expr.subfoo = no;
$_cola_ml_expr.subaz();
return $_cola_ml_expr;
})($_cola_ml_expr.sub);
return $_cola_ml_expr;
})(obj);
*/
if(node instanceof Cola.AST_Cascade){
props = {
type : "dynamic",
body : [],
argnames : [new Cola.AST_Defarg({
argtype : "positional",
type : "dynamic",
defval : new Cola.AST_Noop(),
name : new Cola.AST_SymbolFunarg({ name : "$_cola_ml_expr" })
})]
};
var Expr, Parent = false;
node.subexpressions.forEach(function(expr){
Expr = expr, Parent = false;
while(true)
if( expr instanceof Cola.AST_Call || expr instanceof Cola.AST_Dot ||
expr instanceof Cola.AST_Sub || expr instanceof Cola.AST_Cascade){
Parent = expr;
expr = expr.expression;
} else
if(expr instanceof Cola.AST_Binary){
Parent = expr;
expr = expr.left;
} else
if(expr instanceof Cola.AST_Array || expr instanceof Cola.AST_ArrayRange || expr instanceof Cola.AST_SymbolRef) break;
if(!Parent){
if(expr instanceof Cola.AST_Array || expr instanceof Cola.AST_ArrayRange) Expr = new Cola.AST_Sub({
start : Expr.start,
end : Expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }),
property : expr instanceof Cola.AST_ArrayRange ? expr : ( expr.elements.length == 0 ? new Cola.AST_Noop() : expr.elements[0] )
}); else
if(expr instanceof Cola.AST_SymbolRef) Expr = new Cola.AST_Dot({
start : Expr.start,
end : Expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }),
property : Expr.name
});
} else {
if(expr instanceof Cola.AST_Array || expr instanceof Cola.AST_ArrayRange)
expr = new Cola.AST_Sub({
start : expr.start,
end : expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }),
property : expr instanceof Cola.AST_ArrayRange ? expr : ( expr.elements.length == 0 ? new Cola.AST_Noop() : expr.elements[0] )
});
else
expr = new Cola.AST_Dot({
start : expr.start,
end : expr.end,
expression : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" }),
property : expr.name
});
if( Parent instanceof Cola.AST_Call || Parent instanceof Cola.AST_Dot ||
Parent instanceof Cola.AST_Sub || Parent instanceof Cola.AST_Cascade) Parent.expression = expr;
else
if(Parent instanceof Cola.AST_Binary) Parent.left = expr;
}
props.body.push(new Cola.AST_SimpleStatement({
start : Expr.start,
end : Expr.end,
body : Expr
}));
});
props.body.push(new Cola.AST_Return({
value : new Cola.AST_SymbolRef({ name : "$_cola_ml_expr" })
}));
node = new Cola.AST_Call({
start : node.start,
end : node.end,
args : [node.expression],
expression : new Cola.AST_Function(props)
});
} else
/* /*
"test @a @{b} {{c}}" "test @a @{b} {{c}}"