Mercurial Hosting > luan
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);