added += and other assign-ops

added EInvalidAccess when null object
added ?: expression
This commit is contained in:
Nicolas Cannasse
2008-07-07 17:15:10 +00:00
parent 50c88eaffe
commit 4eb6486600
5 changed files with 61 additions and 4 deletions
+3 -3
View File
@@ -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
View File
@@ -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>
+1
View File
@@ -58,4 +58,5 @@ enum Error {
EUnknownVariable( v : String );
EInvalidIterator( v : String );
EInvalidOp( op : String );
EInvalidAccess( f : String );
}
+44
View File
@@ -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;
}
+12
View File
@@ -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: ":";
}
}