added += and other assign-ops
added EInvalidAccess when null object added ?: expression
This commit is contained in:
@@ -4,7 +4,7 @@ class Test {
|
||||
var script = "
|
||||
var sum = 0;
|
||||
for( a in angles )
|
||||
sum = sum + Math.cos(a);
|
||||
sum += Math.cos(a);
|
||||
sum;
|
||||
";
|
||||
var p = new hscript.Parser();
|
||||
@@ -20,7 +20,7 @@ class Test {
|
||||
return Math.cos(a);
|
||||
}
|
||||
function bar(x) {
|
||||
sum = sum + foo(x);
|
||||
sum += foo(x);
|
||||
}
|
||||
for( x in angles )
|
||||
bar(x);
|
||||
@@ -34,7 +34,7 @@ class Test {
|
||||
var i = 0;
|
||||
var sum = 0;
|
||||
while( i < angles.length )
|
||||
sum = sum + Math.cos(angles[i++]);
|
||||
sum += Math.cos(angles[i++]);
|
||||
sum;
|
||||
";
|
||||
var program = p.parseString(script);
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<project name="hscript" url="http://haxe.org/com/libs/hscript" license="GPL">
|
||||
<user name="ncannasse"/>
|
||||
<description>haXe Script is a scripting engine for a subset of the haXe language</description>
|
||||
<version name="1.1">Added functions, return, arrays</version>
|
||||
<version name="1.2">Added += and ?:</version>
|
||||
</project>
|
||||
@@ -58,4 +58,5 @@ enum Error {
|
||||
EUnknownVariable( v : String );
|
||||
EInvalidIterator( v : String );
|
||||
EInvalidOp( op : String );
|
||||
EInvalidAccess( f : String );
|
||||
}
|
||||
|
||||
@@ -70,6 +70,17 @@ class Interp {
|
||||
binops.set("||",function(e1,e2) return me.expr(e1) == true || me.expr(e2) == true);
|
||||
binops.set("&&",function(e1,e2) return me.expr(e1) == true && me.expr(e2) == true);
|
||||
binops.set("=",assign);
|
||||
assignOp("+=",function(v1:Dynamic,v2:Dynamic) return v1 + v2);
|
||||
assignOp("-=",function(v1:Float,v2:Float) return v1 - v2);
|
||||
assignOp("*=",function(v1:Float,v2:Float) return v1 * v2);
|
||||
assignOp("/=",function(v1:Float,v2:Float) return v1 / v2);
|
||||
assignOp("%=",function(v1:Float,v2:Float) return v1 % v2);
|
||||
assignOp("&=",function(v1,v2) return v1 & v2);
|
||||
assignOp("|=",function(v1,v2) return v1 | v2);
|
||||
assignOp("^=",function(v1,v2) return v1 ^ v2);
|
||||
assignOp("<<=",function(v1,v2) return v1 << v2);
|
||||
assignOp(">>=",function(v1,v2) return v1 >> v2);
|
||||
assignOp(">>>=",function(v1,v2) return v1 >>> v2);
|
||||
}
|
||||
|
||||
function assign( e1 : Expr, e2 : Expr ) {
|
||||
@@ -90,6 +101,36 @@ class Interp {
|
||||
return v;
|
||||
}
|
||||
|
||||
function assignOp( op, fop ) {
|
||||
var me = this;
|
||||
binops.set(op,function(e1,e2) return me.evalAssignOp(op,fop,e1,e2));
|
||||
}
|
||||
|
||||
function evalAssignOp(op,fop,e1,e2) : Dynamic {
|
||||
var v;
|
||||
switch( e1 ) {
|
||||
case EIdent(id):
|
||||
var l = locals.get(id);
|
||||
v = fop(expr(e1),expr(e2));
|
||||
if( l == null )
|
||||
variables.set(id,v)
|
||||
else
|
||||
l.r = v;
|
||||
case EField(e,f):
|
||||
var obj = expr(e);
|
||||
v = fop(get(obj,f),expr(e2));
|
||||
v = set(obj,f,v);
|
||||
case EArray(e,index):
|
||||
var arr = expr(e);
|
||||
var index = expr(index);
|
||||
v = fop(arr[index],expr(e2));
|
||||
arr[index] = v;
|
||||
default:
|
||||
throw Error.EInvalidOp(op);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
function increment( e : Expr, prefix : Bool, delta : Int ) : Dynamic {
|
||||
switch(e) {
|
||||
case EIdent(id):
|
||||
@@ -212,6 +253,7 @@ class Interp {
|
||||
switch(e) {
|
||||
case EField(e,f):
|
||||
var obj = expr(e);
|
||||
if( obj == null ) throw Error.EInvalidAccess(f);
|
||||
return call(obj,Reflect.field(obj,f),args);
|
||||
default:
|
||||
return call(null,expr(e),args);
|
||||
@@ -293,10 +335,12 @@ class Interp {
|
||||
}
|
||||
|
||||
function get( o : Dynamic, f : String ) {
|
||||
if( o == null ) throw Error.EInvalidAccess(f);
|
||||
return Reflect.field(o,f);
|
||||
}
|
||||
|
||||
function set( o : Dynamic, f : String, v : Dynamic ) {
|
||||
if( o == null ) throw Error.EInvalidAccess(f);
|
||||
Reflect.setField(o,f,v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ enum Token {
|
||||
TSemicolon;
|
||||
TBkOpen;
|
||||
TBkClose;
|
||||
TQuestion;
|
||||
TDoubleDot;
|
||||
}
|
||||
|
||||
class Parser {
|
||||
@@ -283,6 +285,12 @@ class Parser {
|
||||
tk = token(s);
|
||||
if( tk != TBkClose ) unexpected(tk);
|
||||
return parseExprNext(s,EArray(e1,e2));
|
||||
case TQuestion:
|
||||
var e2 = parseExpr(s);
|
||||
tk = token(s);
|
||||
if( tk != TDoubleDot ) unexpected(tk);
|
||||
var e3 = parseExpr(s);
|
||||
return EIf(e1,e2,e3);
|
||||
default:
|
||||
tokens.add(tk);
|
||||
return e1;
|
||||
@@ -387,6 +395,8 @@ class Parser {
|
||||
case 93: return TBkClose;
|
||||
case 39: return TConst( CString(readString(s,39)) );
|
||||
case 34: return TConst( CString(readString(s,34)) );
|
||||
case 63: return TQuestion;
|
||||
case 58: return TDoubleDot;
|
||||
default:
|
||||
if( ops[char] ) {
|
||||
var op = Std.chr(char);
|
||||
@@ -440,6 +450,8 @@ class Parser {
|
||||
case TSemicolon: ";";
|
||||
case TBkOpen: "[";
|
||||
case TBkClose: "]";
|
||||
case TQuestion: "?";
|
||||
case TDoubleDot: ":";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user