|
|
(One intermediate revision by the same user not shown) |
Line 1: |
Line 1: |
− | { | + | {{Special:Prefixindex/{{FULLPAGENAME}}}} |
− | function OP(h,t,opc,valc) {
| |
− | if (!t.length) return h;
| |
− | opc = opc || 1;
| |
− | valc = valc || 3;
| |
− | var ret = [h];
| |
− | t.forEach(function(n) {
| |
− | ret.push(n[opc]);
| |
− | ret.push(n[valc]);
| |
− | })
| |
− | return ret;
| |
− | }
| |
− | function EVAL(nodes,ctx) {
| |
− | if (!Array.isArray(nodes)) return nodes;
| |
− | var acc = EVAL(nodes[0],ctx);
| |
− | for (var i = 1; i<nodes.length;) {
| |
− | var op = nodes[i++];
| |
− | console.log(acc,op);
| |
− | switch (op) {
| |
− | case '+': acc+=EVAL(nodes[i++],ctx); break;
| |
− | case '-': acc-=EVAL(nodes[i++],ctx); break;
| |
− | case '*': acc*=EVAL(nodes[i++],ctx); break;
| |
− | case '/': acc/=EVAL(nodes[i++],ctx); break;
| |
− | case '%': acc%=EVAL(nodes[i++],ctx); break;
| |
− | case '$': acc=ctx[acc]; break;
| |
− | case '=': acc = ctx[acc] = EVAL(nodes[i++],ctx);; break;
| |
− | case ';':
| |
− | case ',': acc=EVAL(nodes[i++],ctx); break;
| |
− |
| |
− | }
| |
− | }
| |
− | return acc;
| |
− | }
| |
− | }
| |
− | program = e:statements { return [EVAL(e,{a:3}),!e];}
| |
− | statements = h:statement t:(_ ';' _ statement)* ';'? { return OP(h,t)}
| |
− | statement = assign/expr
| |
− | assign = n:ident _ "=" _ e:expr { return [n,'=',e] }
| |
− | expr = addsub
| |
− | addsub = h:muldiv t:( _ [+-] _ muldiv)* { return OP(h,t)}
| |
− | muldiv = h:atom t:( _ [*/%] _ atom)* { return OP(h,t)}
| |
− | atom = path/number/brackets
| |
− | brackets = _ "(" _ e:expr _ ")" _ { return e}
| |
− | path = h:head t:( _ [.] _ key)* { return OP(h,t)}
| |
− | head = i:ident { return [i,'$']; }/brackets
| |
− | key = ident/digits/brackets
| |
− | number = n:$( d:digits ('.' digits)? ([Ee] digits)?) { return Number(n);}
| |
− | digits = [0-9]+
| |
− | ident = $([A-Z_]i [A-Z0-9_]i*)
| |
− | _ = [ \n\r\t]*
| |
− | __ = [ \n\r\t]+
| |