diff --git a/jsvar.d b/jsvar.d index 32f62a2..c60a76e 100644 --- a/jsvar.d +++ b/jsvar.d @@ -391,7 +391,7 @@ private var _op(alias _this, alias this2, string op, T)(T t) if(op != "~") { return _op!(_this, this2, op)(t._payload._floating); if(t.payloadType() == var.Type.String) return _op!(_this, this2, op)(t._payload._string); - assert(0, to!string(t.payloadType())); + throw new Exception("Attempted invalid operator `" ~ op ~ "` on variable of type " ~ to!string(t.payloadType())); } else { if(this2.payloadType() == var.Type.Integral) { auto l = this2._payload._integral; diff --git a/script.d b/script.d index 7a38ee4..d362f08 100644 --- a/script.d +++ b/script.d @@ -10,6 +10,8 @@ state consists of all variables and source to functions Steal Ruby's [regex, capture] maybe + + and the => operator too */ /++ A small script interpreter that builds on [arsd.jsvar] to be easily embedded inside and to have has easy @@ -99,6 +101,7 @@ Variable names that start with __ are reserved and you shouldn't use them. * int, float, string, array, bool, and json!q{} literals * var.prototype, var.typeof. prototype works more like Mozilla's __proto__ than standard javascript prototype. + * the |> pipeline operator * classes: // inheritance works class Foo : bar { @@ -347,6 +350,9 @@ private enum string[] symbols = [ "+=", "-=", "*=", "/=", "~=", "==", "<=", ">=","!=", "%=", "&=", "|=", "^=", "..", + "<<", ">>", // FIXME + "|>", + "=>", // FIXME "?", ".",",",";",":", "[", "]", "{", "}", "(", ")", "&", "|", "^", @@ -1126,10 +1132,15 @@ class BinaryExpression : Expression { //writeln(left, " "~op~" ", right); var n; - foreach(ctOp; CtList!("+", "-", "*", "/", "==", "!=", "<=", ">=", ">", "<", "~", "&&", "||", "&", "|", "^", "%")) - if(ctOp == op) { + sw: switch(op) { + static foreach(ctOp; CtList!("+", "-", "*", "/", "==", "!=", "<=", ">=", ">", "<", "~", "&&", "||", "&", "|", "^", "%")) + case ctOp: { n = mixin("left "~ctOp~" right"); + break sw; } + default: + assert(0, op); + } return InterpretResult(n, sc); } @@ -1172,6 +1183,31 @@ class OpAssignExpression : Expression { } } +class PipelineExpression : Expression { + Expression e1; + Expression e2; + CallExpression ce; + + this(Expression e1, Expression e2) { + this.e1 = e1; + this.e2 = e2; + + if(auto ce = cast(CallExpression) e2) { + this.ce = new CallExpression(ce.func); + this.ce.arguments = [e1] ~ ce.arguments; + } else { + this.ce = new CallExpression(e2); + this.ce.arguments ~= e1; + } + } + + override string toString() { return e1.toString() ~ " |> " ~ e2.toString(); } + + override InterpretResult interpret(PrototypeObject sc) { + return ce.interpret(sc); + } +} + class AssignExpression : Expression { Expression e1; Expression e2; @@ -2122,6 +2158,10 @@ Expression parseAddend(MyTokenStreamHere)(ref MyTokenStreamHere tokens) { case ":": // idk return e1; + case "|>": + tokens.popFront(); + e1 = new PipelineExpression(e1, parseFactor(tokens)); + break; case ".": tokens.popFront(); e1 = new DotVarExpression(e1, parseVariableName(tokens));