changeset 8:8896068e0a4b

finish operators git-svn-id: https://luan-java.googlecode.com/svn/trunk@9 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Wed, 21 Nov 2012 06:57:09 +0000
parents bca8fc5d928b
children 600676034a1a
files src/luan/LuaNumber.java src/luan/interp/ConcatExpr.java src/luan/interp/LeExpr.java src/luan/interp/LtExpr.java src/luan/interp/LuaParser.java src/luan/interp/PowExpr.java
diffstat 6 files changed, 137 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/LuaNumber.java	Tue Nov 20 10:06:27 2012 +0000
+++ b/src/luan/LuaNumber.java	Wed Nov 21 06:57:09 2012 +0000
@@ -1,7 +1,7 @@
 package luan;
 
 
-public final class LuaNumber {
+public final class LuaNumber implements Comparable<LuaNumber> {
 	final double n;
 
 	public LuaNumber(double n) {
@@ -39,4 +39,8 @@
 		return Double.valueOf(n).hashCode();
 	}
 
+	@Override public int compareTo(LuaNumber ln) {
+		return Double.compare(n,ln.n);
+	}
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/interp/ConcatExpr.java	Wed Nov 21 06:57:09 2012 +0000
@@ -0,0 +1,27 @@
+package luan.interp;
+
+import luan.Lua;
+import luan.LuaNumber;
+import luan.LuaException;
+import luan.LuaState;
+
+
+final class ConcatExpr extends BinaryOpExpr {
+
+	ConcatExpr(Expr op1,Expr op2) {
+		super(op1,op2);
+	}
+
+	@Override Object eval(LuaState lua) throws LuaException {
+		Object v1 = op1.eval(lua);
+		Object v2 = op2.eval(lua);
+		check(v1);
+		check(v2);
+		return Lua.toString(v1) + Lua.toString(v2);
+	}
+
+	private static void check(Object v) throws LuaException {
+		if( !(v instanceof String || v instanceof LuaNumber) )
+			throw new LuaException( "attempt to concatenate a " + Lua.type(v) + " value" );
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/interp/LeExpr.java	Wed Nov 21 06:57:09 2012 +0000
@@ -0,0 +1,30 @@
+package luan.interp;
+
+import luan.Lua;
+import luan.LuaNumber;
+import luan.LuaException;
+import luan.LuaState;
+
+
+final class LeExpr extends BinaryOpExpr {
+
+	LeExpr(Expr op1,Expr op2) {
+		super(op1,op2);
+	}
+
+	@Override Object eval(LuaState lua) throws LuaException {
+		Object v1 = op1.eval(lua);
+		Object v2 = op2.eval(lua);
+		if( v1 instanceof LuaNumber && v2 instanceof LuaNumber ) {
+			LuaNumber n1 = (LuaNumber)v1;
+			LuaNumber n2 = (LuaNumber)v2;
+			return n1.compareTo(n2) <= 0;
+		}
+		if( v1 instanceof String && v2 instanceof String ) {
+			String s1 = (String)v1;
+			String s2 = (String)v2;
+			return s1.compareTo(s2) <= 0;
+		}
+		throw new LuaException( "attempt to compare " + Lua.type(v1) + " with " + Lua.type(v2) );
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/interp/LtExpr.java	Wed Nov 21 06:57:09 2012 +0000
@@ -0,0 +1,30 @@
+package luan.interp;
+
+import luan.Lua;
+import luan.LuaNumber;
+import luan.LuaException;
+import luan.LuaState;
+
+
+final class LtExpr extends BinaryOpExpr {
+
+	LtExpr(Expr op1,Expr op2) {
+		super(op1,op2);
+	}
+
+	@Override Object eval(LuaState lua) throws LuaException {
+		Object v1 = op1.eval(lua);
+		Object v2 = op2.eval(lua);
+		if( v1 instanceof LuaNumber && v2 instanceof LuaNumber ) {
+			LuaNumber n1 = (LuaNumber)v1;
+			LuaNumber n2 = (LuaNumber)v2;
+			return n1.compareTo(n2) < 0;
+		}
+		if( v1 instanceof String && v2 instanceof String ) {
+			String s1 = (String)v1;
+			String s2 = (String)v2;
+			return s1.compareTo(s2) < 0;
+		}
+		throw new LuaException( "attempt to compare " + Lua.type(v1) + " with " + Lua.type(v2) );
+	}
+}
--- a/src/luan/interp/LuaParser.java	Tue Nov 20 10:06:27 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Wed Nov 21 06:57:09 2012 +0000
@@ -38,16 +38,27 @@
 
 	Rule RelExpr() {
 		return Sequence(
-			SumExpr(),
+			ConcatExpr(),
 			ZeroOrMore(
 				FirstOf(
-					Sequence( "==", Spaces(), SumExpr(), push( new EqExpr((Expr)pop(1),(Expr)pop()) ) ),
-					Sequence( "~=", Spaces(), SumExpr(), push( new NotExpr(new EqExpr((Expr)pop(1),(Expr)pop())) ) )
+					Sequence( "==", Spaces(), ConcatExpr(), push( new EqExpr((Expr)pop(1),(Expr)pop()) ) ),
+					Sequence( "~=", Spaces(), ConcatExpr(), push( new NotExpr(new EqExpr((Expr)pop(1),(Expr)pop())) ) ),
+					Sequence( "<=", Spaces(), ConcatExpr(), push( new LeExpr((Expr)pop(1),(Expr)pop()) ) ),
+					Sequence( ">=", Spaces(), ConcatExpr(), push( new LeExpr((Expr)pop(),(Expr)pop()) ) ),
+					Sequence( "<", Spaces(), ConcatExpr(), push( new LtExpr((Expr)pop(1),(Expr)pop()) ) ),
+					Sequence( ">", Spaces(), ConcatExpr(), push( new LtExpr((Expr)pop(),(Expr)pop()) ) )
 				)
 			)
 		);
 	}
 
+	Rule ConcatExpr() {
+		return Sequence(
+			SumExpr(),
+			Optional( "..", Spaces(), ConcatExpr(), push( new ConcatExpr((Expr)pop(1),(Expr)pop()) ) )
+		);
+	}
+
 	Rule SumExpr() {
 		return Sequence(
 			TermExpr(),
@@ -75,10 +86,17 @@
 
 	Rule UnaryExpr() {
 		return FirstOf(
-			Sequence( '#', Spaces(), SingleExpr(), push( new LenExpr((Expr)pop()) ) ),
-			Sequence( '-', Spaces(), SingleExpr(), push( new UnmExpr((Expr)pop()) ) ),
-			Sequence( "not", Spaces(), SingleExpr(), push( new NotExpr((Expr)pop()) ) ),
-			SingleExpr()
+			Sequence( '#', Spaces(), PowExpr(), push( new LenExpr((Expr)pop()) ) ),
+			Sequence( '-', Spaces(), PowExpr(), push( new UnmExpr((Expr)pop()) ) ),
+			Sequence( "not", Spaces(), PowExpr(), push( new NotExpr((Expr)pop()) ) ),
+			PowExpr()
+		);
+	}
+
+	Rule PowExpr() {
+		return Sequence(
+			SingleExpr(),
+			Optional( '^', Spaces(), PowExpr(), push( new PowExpr((Expr)pop(1),(Expr)pop()) ) )
 		);
 	}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/interp/PowExpr.java	Wed Nov 21 06:57:09 2012 +0000
@@ -0,0 +1,20 @@
+package luan.interp;
+
+import luan.Lua;
+import luan.LuaNumber;
+import luan.LuaException;
+import luan.LuaState;
+
+
+final class PowExpr extends BinaryOpExpr {
+
+	PowExpr(Expr op1,Expr op2) {
+		super(op1,op2);
+	}
+
+	@Override Object eval(LuaState lua) throws LuaException {
+		double n1 = Lua.checkNumber(op1.eval(lua)).value();
+		double n2 = Lua.checkNumber(op2.eval(lua)).value();
+		return new LuaNumber( Math.pow(n1,n2) );
+	}
+}