changeset 649:37f0cf43f191

UnaryExpr now compiled
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 30 Mar 2016 22:42:27 -0600
parents e387e4021afe
children d658eab7bf4c
files core/src/luan/impl/$Luan.java core/src/luan/impl/AndExpr.java core/src/luan/impl/Expr.java core/src/luan/impl/FnCall.java core/src/luan/impl/LuanCompiler.java core/src/luan/impl/LuanParser.java core/src/luan/impl/OrExpr.java core/src/luan/impl/StmtExp.java
diffstat 8 files changed, 101 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/impl/$Luan.java	Wed Mar 30 19:40:48 2016 -0600
+++ b/core/src/luan/impl/$Luan.java	Wed Mar 30 22:42:27 2016 -0600
@@ -3,7 +3,9 @@
 import java.util.List;
 import java.util.ArrayList;
 import luan.Luan;
+import luan.LuanState;
 import luan.LuanTable;
+import luan.LuanFunction;
 import luan.LuanException;
 
 
@@ -28,7 +30,7 @@
 		return Luan.first(obj);
 	}
 
-	public static int len(LuanStateImpl luan,Object o) throws LuanException {
+	public static int len(LuanState luan,Object o) throws LuanException {
 		if( o instanceof String ) {
 			String s = (String)o;
 			return s.length();
@@ -43,4 +45,21 @@
 		}
 		throw new LuanException( "attempt to get length of a " + Luan.type(o) + " value" );
 	}
+
+	public static Object unm(LuanState luan,Object o) throws LuanException {
+		if( o instanceof Number )
+			return -((Number)o).doubleValue();
+		if( o instanceof LuanTable ) {
+			LuanFunction fn = Luan.getHandlerFunction("__unm",(LuanTable)o);
+			if( fn != null ) {
+				return Luan.first(fn.call(luan,new Object[]{o}));
+			}
+		}
+		throw new LuanException("attempt to perform arithmetic on a "+Luan.type(o)+" value");
+	}
+
+	public static Boolean not(Object o) throws LuanException {
+		return !Luan.checkBoolean(o);
+	}
+
 }
--- a/core/src/luan/impl/AndExpr.java	Wed Mar 30 19:40:48 2016 -0600
+++ b/core/src/luan/impl/AndExpr.java	Wed Mar 30 22:42:27 2016 -0600
@@ -4,7 +4,7 @@
 import luan.LuanException;
 
 
-final class AndExpr extends BinaryOpExpr {
+final class AndExpr extends BinaryOpExpr implements StmtExp {
 
 	AndExpr(Expr op1,Expr op2) {
 		super(op1,op2);
--- a/core/src/luan/impl/Expr.java	Wed Mar 30 19:40:48 2016 -0600
+++ b/core/src/luan/impl/Expr.java	Wed Mar 30 22:42:27 2016 -0600
@@ -3,4 +3,4 @@
 import luan.LuanException;
 
 
-interface Expr extends Expressions {}
+public interface Expr extends Expressions {}
--- a/core/src/luan/impl/FnCall.java	Wed Mar 30 19:40:48 2016 -0600
+++ b/core/src/luan/impl/FnCall.java	Wed Mar 30 22:42:27 2016 -0600
@@ -6,7 +6,7 @@
 import luan.LuanTable;
 
 
-final class FnCall extends CodeImpl implements Expressions {
+final class FnCall extends CodeImpl implements StmtExp {
 	final Expr fnExpr;
 	final Expressions args;
 
--- a/core/src/luan/impl/LuanCompiler.java	Wed Mar 30 19:40:48 2016 -0600
+++ b/core/src/luan/impl/LuanCompiler.java	Wed Mar 30 22:42:27 2016 -0600
@@ -30,7 +30,7 @@
 			}
 			return parser.RequiredModule();
 		} catch(ParseException e) {
-//e.printStackTrace();
+e.printStackTrace();
 			throw new LuanException( e.getFancyMessage() );
 		}
 	}
--- a/core/src/luan/impl/LuanParser.java	Wed Mar 30 19:40:48 2016 -0600
+++ b/core/src/luan/impl/LuanParser.java	Wed Mar 30 22:42:27 2016 -0600
@@ -508,7 +508,7 @@
 	private Stmt ExpressionsStmt() throws ParseException {
 		parser.begin();
 		Expressions exp = ExprZ(In.NOTHING);
-		if( exp instanceof FnCall || exp instanceof AndExpr || exp instanceof OrExpr )
+		if( exp instanceof StmtExp )
 			return parser.success( new ExpressionsStmt(exp) );
 		return parser.failure(null);
 	}
@@ -630,22 +630,23 @@
 
 	private Expressions TermExpr(In in) throws ParseException {
 		parser.begin();
-		Expressions exp = UnaryExpr(in);
-		if( exp==null )
+		ExpString expStr = UnaryExpr(in);
+		if( expStr==null )
 			return parser.failure(null);
+		Expressions exp = expStr.toExpressions();
 		while(true) {
 			if( parser.match('*') ) {
 				Spaces(in);
-				Expressions exp2 = UnaryExpr(in);
-				exp = new MulExpr( expr(exp), required(expr(exp2)) );
+				Expressions exp2 = required(UnaryExpr(in)).toExpressions();
+				exp = new MulExpr( expr(exp), expr(exp2) );
 			} else if( parser.match('/') ) {
 				Spaces(in);
-				Expressions exp2 = UnaryExpr(in);
-				exp = new DivExpr( expr(exp), required(expr(exp2)) );
+				Expressions exp2 = required(UnaryExpr(in)).toExpressions();
+				exp = new DivExpr( expr(exp), expr(exp2) );
 			} else if( Mod() ) {
 				Spaces(in);
-				Expressions exp2 = UnaryExpr(in);
-				exp = new ModExpr( expr(exp), required(expr(exp2)) );
+				Expressions exp2 = required(UnaryExpr(in)).toExpressions();
+				exp = new ModExpr( expr(exp), expr(exp2) );
 			} else
 				break;
 		}
@@ -657,29 +658,33 @@
 		return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure();
 	}
 
-	private Expressions UnaryExpr(In in) throws ParseException {
+	private ExpString UnaryExpr(In in) throws ParseException {
 		parser.begin();
 		if( parser.match('#') ) {
 			Spaces(in);
-			Expressions exp = required(UnaryExpr(in));
-			String code = "$Luan.len($luan," + expressionsToExprString(exp) + ")";
-			exp = stringToExpressions(code);
+			ExpString exp = required(UnaryExpr(in)).expr();
+			String code = "$Luan.len($luan," + exp.code + ")";
+			exp = new ExpString(code,true,false);
 			return parser.success(exp);
 		}
 		if( Minus() ) {
 			Spaces(in);
-			Expressions exp = UnaryExpr(in);
-			return parser.success( new UnmExpr( required(expr(exp)) ) );
+			ExpString exp = required(UnaryExpr(in)).expr();
+			String code = "$Luan.unm($luan," + exp.code + ")";
+			exp = new ExpString(code,true,false);
+			return parser.success(exp);
 		}
 		if( Keyword("not",in) ) {
 			Spaces(in);
-			Expressions exp = UnaryExpr(in);
-			return parser.success( new NotExpr( required(expr(exp)) ) );
+			ExpString exp = required(UnaryExpr(in)).expr();
+			String code = "$Luan.not(" + exp.code + ")";
+			exp = new ExpString(code,true,false);
+			return parser.success(exp);
 		}
 		Expressions exp = PowExpr(in);
 		if( exp==null )
 			return parser.failure(null);
-		return parser.success(exp);
+		return parser.success(new ExpString(exp));
 	}
 
 	private Expressions PowExpr(In in) throws ParseException {
@@ -1352,39 +1357,55 @@
 
 
 
-	private static String expressionsToExprString(Expressions exp) {
-		int i = $Luan.addExpressions(exp);
-		String s = "$Luan.getExpressions(" + i + ").eval($luan)";
-		if( !(exp instanceof Expr) )
-			s = "$Luan.first(" + s + ")";
-		return s;
-	}
-
 	private static int classCounter = 0;
 
-	private static Expressions stringToExpressions(String code) {
-		String className = "EXP" + ++classCounter;
-		String classCode = ""
-			+"package luan.impl;\n"
-//			+"import luan.impl.$Luan;\n"
-//			+"import luan.impl.Expressions;\n"
-			+"import luan.LuanException;\n"
-			+"\n"
-			+"public class " + className +" implements Expressions {\n"
-			+"	@Override public Object eval(LuanStateImpl $luan) throws LuanException {\n"
-			+"		return " + code + ";\n"
-			+"	}\n"
-			+"}\n"
-		;
-		try {
-			Class cls = LuanJavaCompiler.compile("luan.impl."+className,code,classCode);
-			return (Expressions)cls.newInstance();
-		} catch(ClassNotFoundException e) {
-			throw new RuntimeException(e);
-		} catch(InstantiationException e) {
-			throw new RuntimeException(e);
-		} catch(IllegalAccessException e) {
-			throw new RuntimeException(e);
+	private class ExpString {
+		final String code;
+		final boolean isExpr;
+		final boolean isStmt;
+
+		ExpString(Expressions exp) {
+			if( exp==null )  throw new NullPointerException();
+			int i = $Luan.addExpressions(exp);
+			code = "$Luan.getExpressions(" + i + ").eval($luan)";
+			isExpr = exp instanceof Expr;
+			isStmt = exp instanceof StmtExp;
+		}
+
+		ExpString(String code,boolean isExpr,boolean isStmt) {
+			this.code = code;
+			this.isExpr = isExpr;
+			this.isStmt = isStmt;
+		}
+
+		ExpString expr() {
+			return isExpr ? this : new ExpString( "$Luan.first(" + code + ")", true, false );
+		}
+
+		Expressions toExpressions() {
+			String superClass = isStmt ? "StmtExp" : "Expressions";
+			String className = "EXP" + ++classCounter;
+			String classCode = ""
+				+"package luan.impl;\n"
+				+"import luan.LuanException;\n"
+				+"\n"
+				+"public class " + className +" implements " + superClass + " {\n"
+				+"	@Override public Object eval(LuanStateImpl $luan) throws LuanException {\n"
+				+"		return " + code + ";\n"
+				+"	}\n"
+				+"}\n"
+			;
+//System.out.println(code);
+			try {
+				Class cls = LuanJavaCompiler.compile("luan.impl."+className,code,classCode);
+				return (Expressions)cls.newInstance();
+			} catch(ClassNotFoundException e) {
+				throw new RuntimeException(e);
+			} catch(InstantiationException e) {
+				throw new RuntimeException(e);
+			} catch(IllegalAccessException e) {
+				throw new RuntimeException(e);
+			}
 		}
 	}
 
--- a/core/src/luan/impl/OrExpr.java	Wed Mar 30 19:40:48 2016 -0600
+++ b/core/src/luan/impl/OrExpr.java	Wed Mar 30 22:42:27 2016 -0600
@@ -4,7 +4,7 @@
 import luan.LuanException;
 
 
-final class OrExpr extends BinaryOpExpr {
+final class OrExpr extends BinaryOpExpr implements StmtExp {
 
 	OrExpr(Expr op1,Expr op2) {
 		super(op1,op2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/src/luan/impl/StmtExp.java	Wed Mar 30 22:42:27 2016 -0600
@@ -0,0 +1,6 @@
+package luan.impl;
+
+import luan.LuanException;
+
+
+public interface StmtExp extends Expressions {}