diff core/src/luan/impl/LuanParser.java @ 650:d658eab7bf4c

finish compiling operators
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 31 Mar 2016 22:43:51 -0600
parents 37f0cf43f191
children 140cc5191b7a
line wrap: on
line diff
--- a/core/src/luan/impl/LuanParser.java	Wed Mar 30 22:42:27 2016 -0600
+++ b/core/src/luan/impl/LuanParser.java	Thu Mar 31 22:43:51 2016 -0600
@@ -181,7 +181,7 @@
 	FnDef Expression() throws ParseException {
 		Spaces(In.NOTHING);
 		int start = parser.begin();
-		Expressions expr = ExprZ(In.NOTHING);
+		Expressions expr = exp(ExprZ(In.NOTHING));
 		if( expr != null && parser.endOfInput() ) {
 			Stmt stmt = new ReturnStmt( expr );
 			return parser.success(newFnDef(start,stmt));
@@ -279,7 +279,7 @@
 		while(true) {
 			if( parser.match( "<%=" ) ) {
 				Spaces(inTemplate);
-				builder.add( RequiredExpr(inTemplate) );
+				builder.add( exp(RequiredExpr(inTemplate)) );
 				RequiredMatch( "%>" );
 			} else if( parser.match( "<%" ) ) {
 				Spaces(inTemplate);
@@ -355,7 +355,7 @@
 		List<String> names = RequiredNameList(In.NOTHING);
 		if( !Keyword("in",In.NOTHING) )
 			return parser.failure(null);
-		Expr expr = expr(RequiredExpr(In.NOTHING));
+		Expr expr = expr(exp(RequiredExpr(In.NOTHING)));
 		RequiredKeyword("do",In.NOTHING);
 		addSymbols(names);
 		Stmt loop = RequiredLoopBlock();
@@ -435,7 +435,7 @@
 		parser.begin();
 		if( !Keyword("while",In.NOTHING) )
 			return parser.failure(null);
-		Expr cnd = expr(RequiredExpr(In.NOTHING));
+		Expr cnd = expr(exp(RequiredExpr(In.NOTHING)));
 		RequiredKeyword("do",In.NOTHING);
 		Stmt loop = RequiredLoopBlock();
 		RequiredKeyword("end",In.NOTHING);
@@ -448,7 +448,7 @@
 			return parser.failure(null);
 		Stmt loop = RequiredLoopBlock();
 		RequiredKeyword("until",In.NOTHING);
-		Expr cnd = expr(RequiredExpr(In.NOTHING));
+		Expr cnd = expr(exp(RequiredExpr(In.NOTHING)));
 		return parser.success( new RepeatStmt(loop,cnd) );
 	}
 
@@ -468,7 +468,7 @@
 
 	private Stmt IfStmt2() throws ParseException {
 		parser.currentIndex();
-		Expr cnd = expr(RequiredExpr(In.NOTHING));
+		Expr cnd = expr(exp(RequiredExpr(In.NOTHING)));
 		RequiredKeyword("then",In.NOTHING);
 		Stmt thenBlock = RequiredBlock();
 		Stmt elseBlock;
@@ -507,7 +507,7 @@
 
 	private Stmt ExpressionsStmt() throws ParseException {
 		parser.begin();
-		Expressions exp = ExprZ(In.NOTHING);
+		Expressions exp = exp(ExprZ(In.NOTHING));
 		if( exp instanceof StmtExp )
 			return parser.success( new ExpressionsStmt(exp) );
 		return parser.failure(null);
@@ -521,102 +521,124 @@
 		return parser.success( var.settable() );
 	}
 
-	private Expressions RequiredExpr(In in) throws ParseException {
+	private ExpString RequiredExpr(In in) throws ParseException {
 		parser.begin();
 		return parser.success(required(ExprZ(in),"Bad expression"));
 	}
 
-	private Expressions ExprZ(In in) throws ParseException {
+	private ExpString ExprZ(In in) throws ParseException {
 		return OrExpr(in);
 	}
 
-	private Expressions OrExpr(In in) throws ParseException {
+	private ExpString OrExpr(In in) throws ParseException {
 		parser.begin();
-		Expressions exp = AndExpr(in);
+		ExpString exp = AndExpr(in);
 		if( exp==null )
 			return parser.failure(null);
 		while( Keyword("or",in) ) {
-			Expressions exp2 = AndExpr(in);
-			exp = new OrExpr( expr(exp), required(expr(exp2)) );
+			exp = exp.expr();
+			ExpString exp2 = required(RelExpr(in)).expr();
+			String code = "($Luan.cnd($cnd = " + exp.code + ") ? $cnd : (" + exp2.code + "))";
+			exp = new ExpString(code,true,true);
 		}
 		return parser.success(exp);
 	}
 
-	private Expressions AndExpr(In in) throws ParseException {
+	private ExpString AndExpr(In in) throws ParseException {
 		parser.begin();
-		Expressions exp = RelExpr(in);
+		ExpString exp = RelExpr(in);
 		if( exp==null )
 			return parser.failure(null);
 		while( Keyword("and",in) ) {
-			Expressions exp2 = RelExpr(in);
-			exp = new AndExpr( expr(exp), required(expr(exp2)) );
+			exp = exp.expr();
+			ExpString exp2 = required(RelExpr(in)).expr();
+			String code = "($Luan.cnd($cnd = " + exp.code + ") ? (" + exp2.code + ") : $cnd)";
+			exp = new ExpString(code,true,true);
 		}
 		return parser.success(exp);
 	}
 
-	private Expressions RelExpr(In in) throws ParseException {
+	private ExpString RelExpr(In in) throws ParseException {
 		parser.begin();
-		Expressions exp = ConcatExpr(in);
+		ExpString exp = ConcatExpr(in);
 		if( exp==null )
 			return parser.failure(null);
 		while(true) {
 			if( parser.match("==") ) {
 				Spaces(in);
-				Expressions exp2 = ConcatExpr(in);
-				exp = new EqExpr( expr(exp), required(expr(exp2)) );
+				exp = exp.expr();
+				ExpString exp2 = required(ConcatExpr(in)).expr();
+				String code = "$Luan.eq($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else if( parser.match("~=") ) {
 				Spaces(in);
-				Expressions exp2 = ConcatExpr(in);
-				exp = new NotExpr( new EqExpr( expr(exp), required(expr(exp2)) ) );
+				exp = exp.expr();
+				ExpString exp2 = required(ConcatExpr(in)).expr();
+				String code = "!$Luan.eq($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else if( parser.match("<=") ) {
 				Spaces(in);
-				Expressions exp2 = ConcatExpr(in);
-				exp = new LeExpr( expr(exp), required(expr(exp2)) );
+				exp = exp.expr();
+				ExpString exp2 = required(ConcatExpr(in)).expr();
+				String code = "$Luan.le($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else if( parser.match(">=") ) {
 				Spaces(in);
-				Expressions exp2 = ConcatExpr(in);
-				exp = new LeExpr( required(expr(exp2)), expr(exp) );
+				exp = exp.expr();
+				ExpString exp2 = required(ConcatExpr(in)).expr();
+				String code = "$Luan.le($luan," + exp2.code + "," + exp.code + ")";
+				exp = new ExpString(code,true,false);
 			} else if( parser.match("<") ) {
 				Spaces(in);
-				Expressions exp2 = ConcatExpr(in);
-				exp = new LtExpr( expr(exp), required(expr(exp2)) );
-			} else if( parser.match(">") ) {
+				exp = exp.expr();
+				ExpString exp2 = required(ConcatExpr(in)).expr();
+				String code = "$Luan.lt($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
+		} else if( parser.match(">") ) {
 				Spaces(in);
-				Expressions exp2 = ConcatExpr(in);
-				exp = new LtExpr( required(expr(exp2)), expr(exp) );
+				exp = exp.expr();
+				ExpString exp2 = required(ConcatExpr(in)).expr();
+				String code = "$Luan.lt($luan," + exp2.code + "," + exp.code + ")";
+				exp = new ExpString(code,true,false);
 			} else
 				break;
 		}
 		return parser.success(exp);
 	}
 
-	private Expressions ConcatExpr(In in) throws ParseException {
+	private ExpString ConcatExpr(In in) throws ParseException {
 		parser.begin();
-		Expressions exp = SumExpr(in);
+		ExpString exp = SumExpr(in);
 		if( exp==null )
 			return parser.failure(null);
 		if( parser.match("..") ) {
 			Spaces(in);
-			Expressions exp2 = ConcatExpr(in);
-			exp = new ConcatExpr( expr(exp), required(expr(exp2)) );
+			exp = exp.expr();
+			ExpString exp2 = required(ConcatExpr(in)).expr();
+			String code = "$Luan.concat($luan," + exp.code + "," + exp2.code + ")";
+			exp = new ExpString(code,true,false);
 		}
 		return parser.success(exp);
 	}
 
-	private Expressions SumExpr(In in) throws ParseException {
+	private ExpString SumExpr(In in) throws ParseException {
 		parser.begin();
-		Expressions exp = TermExpr(in);
+		ExpString exp = TermExpr(in);
 		if( exp==null )
 			return parser.failure(null);
 		while(true) {
 			if( parser.match('+') ) {
 				Spaces(in);
-				Expressions exp2 = TermExpr(in);
-				exp = new AddExpr( expr(exp), required(expr(exp2)) );
+				exp = exp.expr();
+				ExpString exp2 = required(TermExpr(in)).expr();
+				String code = "$Luan.add($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else if( Minus() ) {
 				Spaces(in);
-				Expressions exp2 = TermExpr(in);
-				exp = new SubExpr( expr(exp), required(expr(exp2)) );
+				exp = exp.expr();
+				ExpString exp2 = required(TermExpr(in)).expr();
+				String code = "$Luan.sub($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else
 				break;
 		}
@@ -628,25 +650,30 @@
 		return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure();
 	}
 
-	private Expressions TermExpr(In in) throws ParseException {
+	private ExpString TermExpr(In in) throws ParseException {
 		parser.begin();
-		ExpString expStr = UnaryExpr(in);
-		if( expStr==null )
+		ExpString exp = UnaryExpr(in);
+		if( exp==null )
 			return parser.failure(null);
-		Expressions exp = expStr.toExpressions();
 		while(true) {
 			if( parser.match('*') ) {
 				Spaces(in);
-				Expressions exp2 = required(UnaryExpr(in)).toExpressions();
-				exp = new MulExpr( expr(exp), expr(exp2) );
+				exp = exp.expr();
+				ExpString exp2 = required(UnaryExpr(in)).expr();
+				String code = "$Luan.mul($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else if( parser.match('/') ) {
 				Spaces(in);
-				Expressions exp2 = required(UnaryExpr(in)).toExpressions();
-				exp = new DivExpr( expr(exp), expr(exp2) );
+				exp = exp.expr();
+				ExpString exp2 = required(UnaryExpr(in)).expr();
+				String code = "$Luan.div($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else if( Mod() ) {
 				Spaces(in);
-				Expressions exp2 = required(UnaryExpr(in)).toExpressions();
-				exp = new ModExpr( expr(exp), expr(exp2) );
+				exp = exp.expr();
+				ExpString exp2 = required(UnaryExpr(in)).expr();
+				String code = "$Luan.mod($luan," + exp.code + "," + exp2.code + ")";
+				exp = new ExpString(code,true,false);
 			} else
 				break;
 		}
@@ -681,23 +708,25 @@
 			exp = new ExpString(code,true,false);
 			return parser.success(exp);
 		}
-		Expressions exp = PowExpr(in);
+		ExpString exp = PowExpr(in);
 		if( exp==null )
 			return parser.failure(null);
-		return parser.success(new ExpString(exp));
+		return parser.success(exp);
 	}
 
-	private Expressions PowExpr(In in) throws ParseException {
+	private ExpString PowExpr(In in) throws ParseException {
 		parser.begin();
 		Expressions exp = SingleExpr(in);
 		if( exp==null )
 			return parser.failure(null);
+		ExpString exp1 = new ExpString(exp);
 		if( parser.match('^') ) {
 			Spaces(in);
-			Expressions exp2 = PowExpr(in);
-			exp = new PowExpr( expr(exp), required(expr(exp2)) );
+			ExpString exp2 = required(PowExpr(in));
+			String code = "$Luan.pow($luan," + exp1.code + "," + exp2.code + ")";
+			exp1 = new ExpString(code,true,false);
 		}
-		return parser.success(exp);
+		return parser.success(exp1);
 	}
 
 	private Expressions SingleExpr(In in) throws ParseException {
@@ -790,11 +819,11 @@
 			exp = NameExpr(In.NOTHING);
 		if( exp!=null && parser.match('=') ) {
 			Spaces(In.NOTHING);
-			fields.add( new TableExpr.Field( exp, required(expr(ExprZ(In.NOTHING))) ) );
+			fields.add( new TableExpr.Field( exp, required(expr(exp(ExprZ(In.NOTHING)))) ) );
 			return parser.success();
 		}
 		parser.rollback();
-		Expressions exprs = ExprZ(In.NOTHING);
+		Expressions exprs = exp(ExprZ(In.NOTHING));
 		if( exprs != null ) {
 			builder.add(exprs);
 			return parser.success();
@@ -823,7 +852,7 @@
 		if( parser.match('(') ) {
 			In inParens = in.parens();
 			Spaces(inParens);
-			Expr exp = expr(RequiredExpr(inParens));
+			Expr exp = expr(exp(RequiredExpr(inParens)));
 			RequiredMatch(')');
 			Spaces(in);
 			return exprVar(exp);
@@ -983,7 +1012,7 @@
 			builder.add(exp);
 			return parser.success();
 		}
-		exp = ExprZ(in);
+		exp = exp(ExprZ(in));
 		if( exp==null )
 			return parser.failure();
 		builder.add(exp);
@@ -994,7 +1023,7 @@
 				builder.add(exp);
 				return parser.success();
 			}
-			builder.add( RequiredExpr(in) );
+			builder.add( exp(RequiredExpr(in)) );
 		}
 		return parser.success();
 	}
@@ -1004,7 +1033,7 @@
 		if( !parser.match('[') || parser.test("[") || parser.test("=") )
 			return parser.failure(null);
 		Spaces(In.NOTHING);
-		Expr exp = expr(RequiredExpr(In.NOTHING));
+		Expr exp = expr(exp(RequiredExpr(In.NOTHING)));
 		RequiredMatch(']');
 		Spaces(in);
 		return parser.success(exp);
@@ -1379,7 +1408,7 @@
 		}
 
 		ExpString expr() {
-			return isExpr ? this : new ExpString( "$Luan.first(" + code + ")", true, false );
+			return isExpr ? this : new ExpString( "$Luan.first(" + code + ")", true, isStmt );
 		}
 
 		Expressions toExpressions() {
@@ -1391,6 +1420,7 @@
 				+"\n"
 				+"public class " + className +" implements " + superClass + " {\n"
 				+"	@Override public Object eval(LuanStateImpl $luan) throws LuanException {\n"
+				+"		Object $cnd;\n"
 				+"		return " + code + ";\n"
 				+"	}\n"
 				+"}\n"
@@ -1409,4 +1439,8 @@
 		}
 	}
 
+	private static Expressions exp(ExpString expStr) {
+		return expStr==null ? null : expStr.toExpressions();
+	}
+
 }