diff --git a/README.md b/README.md
index c95cd583..25e2ddf7 100644
--- a/README.md
+++ b/README.md
@@ -61,7 +61,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
### Multiple
-- `..:`
+- `..:`, status: done
Object profile = {
name : "dan",
@@ -104,7 +104,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
## Expressions
-- `switch` assigmention
+- `switch` assignment
String weather = switch(temperature){
case -10: 'cold';
@@ -133,7 +133,7 @@ ColaScript is a language that compiles in JavaScript. This language is similar t
Object obj = {};
String str = "";
-- multiple assigment
+- multiple assignment
[a, b, c] = [b, c, a];
{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]
console.log(arr[]); // 4
-- part assigment, status: done
+- part assignment, status: done
arr[0..2] = [0,1]; // [0, 1, 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
-- 34 feature ( without classes )
-- 26 done
+- 34 features ( without classes )
+- 27 done
diff --git a/demo.cola b/demo.cola
index d1ab38e6..5a6bbaa2 100644
--- a/demo.cola
+++ b/demo.cola
@@ -20,7 +20,7 @@ main(){
// `modulo` operator
console.log("10 %% 4 = ", 10 %% 4);
- // `isset` conditional assigment
+ // `isset` conditional assignment
int a, b = 4;
console.log("`a` is", a, ", now `a` is", a ?= b);
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");
// Arrays
- // Empty getter and setter ( pushig )
+ // Empty getter and setter ( pushing )
Array arr = [2, 4, 8, 16, 32];
console.log("Last element of `arr` is", arr[]), arr[] = 64;
console.log("Now last element of `arr` is", arr[]);
- // Splice assigment
+ // Splice assignment
arr[2..4] = [3, 2, 1];
console.log("`arr` is", arr);
// Range
console.log("`[0..10]` is", [0..10]);
- // Calling function
- console.log(Profile(
- "Dan", "Green",
+ // Calling function
+ Object pro;
+ console.log(pro = Profile(
+ "Dan", "Green", "Russia",
"HTML5", "JavaScript", "Dart", "PHP", "CSS3", "LESS", "Qt",
age : 19,
petName : "Felix"
));
+
+ // Cascade operator
+ pro
+ ..firstName += "iil"
+ ..secondName = "Onoshko"
+ ..skills:
+ ..[1] = "JS";
+ ;
+
+ console.log(pro);
}
// Functions
@@ -100,3 +111,5 @@ Object Profile(String firstName, String secondName, String country = "Russia", A
petName : petName
};
}
+
+main();
\ No newline at end of file
diff --git a/lib/ast.js b/lib/ast.js
index fa35cef8..af5f0475 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -675,6 +675,22 @@ Cola.AST_Dot = Cola.DEFNODE("Dot", null, {
}
}, 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, {
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
_walk: function(visitor) {
diff --git a/lib/index.html b/lib/index.html
index c3a3ebac..7d889dd7 100644
--- a/lib/index.html
+++ b/lib/index.html
@@ -31,10 +31,12 @@
box-sizing: border-box;
width: 33.333%;
height: 100%;
- font-size: 12px;
+ font-size: 15px;
float: left;
font-family: "Andale Mono";
padding: 0 5px 26px 5px;
+ background-color: #272A32;
+ color: #D6D7D9;
}
#controls {
@@ -51,6 +53,9 @@
left: 0;
width: 100%;
height: 100%;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 2px 0 0 2px;
}
#controls .bg {
@@ -60,12 +65,12 @@
width: 100%;
height: 100%;
background-color: white;
- opacity: 0.5;
+ opacity: 0.8;
}
#lenstat {
float: right;
- margin: 5px 8px 0 0;
+ margin: 2px 10px;
}
@@ -93,7 +98,7 @@ main(){
// `modulo` operator
console.log("10 %% 4 = ", 10 %% 4);
- // `isset` conditional assigment
+ // `isset` conditional assignment
int a, b = 4;
console.log("`a` is", a, ", now `a` is", a ?= b);
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");
// Arrays
- // Empty getter and setter ( pushig )
+ // Empty getter and setter ( pushing )
Array arr = [2, 4, 8, 16, 32];
console.log("Last element of `arr` is", arr[]), arr[] = 64;
console.log("Now last element of `arr` is", arr[]);
- // Splice assigment
+ // Splice assignment
arr[2..4] = [3, 2, 1];
console.log("`arr` is", arr);
// Range
console.log("`[0..10]` is", [0..10]);
- // Calling function
- console.log(Profile(
- "Dan", "Green",
+ // Calling function
+ Object pro;
+ console.log(pro = Profile(
+ "Dan", "Green", "Russia",
"HTML5", "JavaScript", "Dart", "PHP", "CSS3", "LESS", "Qt",
age : 19,
petName : "Felix"
));
+
+ // Cascade operator
+ pro
+ ..firstName += "iil"
+ ..secondName = "Onoshko"
+ ..skills:
+ ..[1] = "JS";
+ ;
+
+ console.log(pro);
}
// Functions
@@ -173,14 +189,16 @@ Object Profile(String firstName, String secondName, String country = "Russia", A
petName : petName
};
}
-
+
+main();
-
+
+
@@ -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;
}
- function benchmark(){
- console.time("ColaScript");
- eval(resultArea.result);
- console.timeEnd("ColaScript");
+ function benchmarkResult(){
+ console.time("Result");
+ eval(resultArea.value);
+ console.timeEnd("Result");
+ }
+
+ function benchmarkTranslate(){
+ console.time("Translation");
+ eval(translationArea.value);
+ console.timeEnd("Translation");
}
function exec(){
diff --git a/lib/parse.js b/lib/parse.js
index 546abbb5..3b2d370c 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -1648,12 +1648,12 @@ Cola.Parser.prototype.array_ = Cola.Parser.embed_tokens(function() {
if(!this.is_js && !this.is("punc","]")){
this.dumpS();
- var tmp, from = this.expression(true);
+ var tmp, from = this.expression(true, false, true);
if(this.is("punc","..")){
this.next();
return new Cola.AST_ArrayRange({
from : from,
- to : (tmp = this.expression(true), this.expect("]"), tmp),
+ to : (tmp = this.expression(true, false, true), this.expect("]"), tmp),
start : from.start,
end : this.prev()
});
@@ -1776,13 +1776,13 @@ Cola.Parser.prototype.subscripts = function(expr, allow_calls) {
if(this.is_js) prop = this.expression(true);
else if(this.is("punc","]")) prop = new Cola.AST_Noop();
else {
- prop = this.expression(true);
+ prop = this.expression(true, false, true);
this.dumpS();
if(this.is("punc","..")){
this.next();
prop = new Cola.AST_ArrayRange({
from : prop,
- to : this.expression(true),
+ to : this.expression(true, false, true),
start : prop.start,
end : this.prev()
});
@@ -1900,9 +1900,39 @@ Cola.Parser.prototype.maybe_assign = function(no_in) {
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 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", ",")) {
this.next();
return new Cola.AST_Seq({
diff --git a/lib/translate.js b/lib/translate.js
index ad6a5e60..62df4fe7 100644
--- a/lib/translate.js
+++ b/lib/translate.js
@@ -571,7 +571,7 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
} else if(val.argtype == "splated"){
onfront = false;
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){
var pos = val.pos; val = val.val;
-
- if(splated && (pos - 1 == splated.pos || pos + 1 == splated.pos)){
+
+ if(val.argtype == "splated"){
aftersplated = 0;
props.definitions.push(new Cola.AST_VarDef({
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({
name : val.name,
@@ -732,6 +731,115 @@ Cola.AST_Toplevel.prototype.toJavaScript = function(options){
}
} 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}}"