diff core/src/luan/impl/LuanParser.java @ 649:37f0cf43f191

UnaryExpr now compiled
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 30 Mar 2016 22:42:27 -0600
parents e387e4021afe
children d658eab7bf4c
line wrap: on
line diff
--- 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);
+			}
 		}
 	}