Mercurial Hosting > luan
changeset 154:c2e5101682ae
Expr extends Expressions
git-svn-id: https://luan-java.googlecode.com/svn/trunk@155 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Tue, 17 Jun 2014 09:55:43 +0000 |
parents | fa03671f59a0 |
children | db7b3902e01c |
files | src/luan/interp/ExpList.java src/luan/interp/Expr.java src/luan/interp/LuanParser.java src/luan/interp/SetStmt.java |
diffstat | 4 files changed, 118 insertions(+), 185 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/interp/ExpList.java Tue Jun 17 02:57:14 2014 +0000 +++ b/src/luan/interp/ExpList.java Tue Jun 17 09:55:43 2014 +0000 @@ -2,110 +2,19 @@ import java.util.List; import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import luan.LuanException; import luan.LuanSource; +import luan.LuanFunction; +import luan.Luan; -final class ExpList implements Expressions { - - private interface Adder { - public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException; - public Code code(); - } - - private static class ExprAdder implements Adder { - private final Expr expr; - - ExprAdder(Expr expr) { - this.expr = expr; - } - - public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException { - list.add( expr.eval(luan) ); - } - - public Code code() { - return expr; - } - - } - - private static class ExpressionsAdder implements Adder { - private final Expressions expressions; - - ExpressionsAdder(Expressions expressions) { - this.expressions = expressions; - } - - public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException { - Object obj = expressions.eval(luan); - if( obj instanceof Object[] ) { - for( Object val : (Object[])obj ) { - list.add( val ); - } - } else { - list.add(obj); - } - } - - public Code code() { - return expressions; - } - - } - - static class Builder { - private final List<Adder> adders = new ArrayList<Adder>(); - - void add(Expr expr) { - if( expr==null ) - throw new NullPointerException(); - adders.add( new ExprAdder(expr) ); - } - - void add(Expressions expressions) { - adders.add( new ExpressionsAdder(expressions) ); - } - - void add(Code code) { - if( code instanceof Expr ) { - add((Expr)code); - } else { - add((Expressions)code); - } - } - - Expressions build() { - int size = adders.size(); - if( size == 0 ) - return emptyExpList; - if( size == 1 ) { - Adder adder = adders.get(0); - if( adder instanceof ExpressionsAdder ) { - ExpressionsAdder ea = (ExpressionsAdder)adder; - return ea.expressions; - } - ExprAdder ea = (ExprAdder)adder; - return new SingleExpList(ea.expr); - } - Adder[] a = adders.toArray(new Adder[size]); - for( int i=0; i<size-1; i++ ) { - Adder adder = a[i]; - if( adder instanceof ExpressionsAdder ) { - a[i] = new ExprAdder(new ExpressionsExpr(((ExpressionsAdder)adder).expressions)); - } - } - return new ExpList(a); - } - } - - private static final Object[] EMPTY = new Object[0]; +final class ExpList { static final Expressions emptyExpList = new Expressions() { @Override public Object[] eval(LuanStateImpl luan) { - return EMPTY; + return LuanFunction.NOTHING; } @Override public LuanSource.Element se() { @@ -113,49 +22,75 @@ } }; - static class SingleExpList implements Expressions { - private final Expr expr; - - SingleExpList(Expr expr) { - this.expr = expr; + static Expr[] toArray(List<Expressions> list) { + Expr[] a = new Expr[list.size()]; + for( int i=0; i<a.length; i++ ) { + Expressions exprs = list.get(i); + if( exprs instanceof Expr ) { + a[i] = (Expr)exprs; + } else { + a[i] = new ExpressionsExpr(exprs); + } } + return a; + } - @Override public Object eval(LuanStateImpl luan) throws LuanException { -//System.out.println("SingleExpList "+expr); - return expr.eval(luan); - } - - @Override public LuanSource.Element se() { - return expr.se(); - } - - @Override public String toString() { - return "(SingleExpList "+expr+")"; + static Expressions build(List<Expressions> list) { + switch(list.size()) { + case 0: + return emptyExpList; + case 1: + return list.get(0); + default: + if( list.get(list.size()-1) instanceof Expr ) { + return new ExprList1( toArray(list) ); + } else { + Expressions last = list.remove(list.size()-1); + return new ExprList2( toArray(list), last ); + } } } - private final Adder[] adders; - - private ExpList(Adder[] adders) { - this.adders = adders; - } + private static class ExprList1 implements Expressions { + private final Expr[] exprs; - @Override public Object eval(LuanStateImpl luan) throws LuanException { - List<Object> list = new ArrayList<Object>(); - for( Adder adder : adders ) { - adder.addTo(luan,list); + private ExprList1(Expr[] exprs) { + this.exprs = exprs; } - switch( list.size() ) { - case 0: - return EMPTY; - case 1: - return list.get(0); - default: - return list.toArray(); + + @Override public Object eval(LuanStateImpl luan) throws LuanException { + Object[] a = new Object[exprs.length]; + for( int i=0; i<exprs.length; i++ ) { + a[i] = exprs[i].eval(luan); + } + return a; + } + + @Override public LuanSource.Element se() { + return new LuanSource.Element(exprs[0].se().source,exprs[0].se().start,exprs[exprs.length-1].se().end); } } - @Override public LuanSource.Element se() { - return new LuanSource.Element(adders[0].code().se().source,adders[0].code().se().start,adders[adders.length-1].code().se().end); + private static class ExprList2 implements Expressions { + private final Expr[] exprs; + private final Expressions last; + + private ExprList2(Expr[] exprs,Expressions last) { + this.exprs = exprs; + this.last = last; + } + + @Override public Object eval(LuanStateImpl luan) throws LuanException { + List<Object> list = new ArrayList<Object>(); + for( Expr expr : exprs ) { + list.add( expr.eval(luan) ); + } + list.addAll( Arrays.asList(Luan.array( last.eval(luan) )) ); + return list.toArray(); + } + + @Override public LuanSource.Element se() { + return new LuanSource.Element(exprs[0].se().source,exprs[0].se().start,last.se().end); + } } }
--- a/src/luan/interp/Expr.java Tue Jun 17 02:57:14 2014 +0000 +++ b/src/luan/interp/Expr.java Tue Jun 17 09:55:43 2014 +0000 @@ -3,6 +3,4 @@ import luan.LuanException; -interface Expr extends Code { - public Object eval(LuanStateImpl luan) throws LuanException; -} +interface Expr extends Expressions {}
--- a/src/luan/interp/LuanParser.java Tue Jun 17 02:57:14 2014 +0000 +++ b/src/luan/interp/LuanParser.java Tue Jun 17 09:55:43 2014 +0000 @@ -170,10 +170,10 @@ return t; } - private static Expr expr(Code code) { - if( code instanceof Expressions ) - return new ExpressionsExpr((Expressions)code); - return (Expr)code; + private static Expr expr(Expressions exprs) { + if( exprs instanceof Expr ) + return (Expr)exprs; + return new ExpressionsExpr(exprs); } private FnDef newFnDef(int start,Stmt stmt) { @@ -263,7 +263,7 @@ return parser.failure(null); EndOfLine(); In inJsp = in.jsp(); - ExpList.Builder builder = new ExpList.Builder(); + List<Expressions> builder = new ArrayList<Expressions>(); while(true) { if( parser.match( "<%=" ) ) { Spaces(inJsp); @@ -271,7 +271,7 @@ RequiredMatch( "%>" ); } else if( parser.match( "<%" ) ) { Spaces(inJsp); - return parser.success(builder.build()); + return parser.success(ExpList.build(builder)); } else { int i = parser.currentIndex(); do { @@ -333,7 +333,7 @@ return parser.failure(null); String varName = modName.substring(modName.lastIndexOf('.')+1); LuanSource.Element se = se(start); - FnCall require = new FnCall( se, importExpr, new ExpList.SingleExpList(new ConstExpr(modName)) ); + FnCall require = new FnCall( se, importExpr, new ConstExpr(modName) ); Settable settable; if( interactive ) { settable = new SetTableEntry( se(start), env(), new ConstExpr(varName) ); @@ -540,25 +540,25 @@ return var.settable(); } - private Code RequiredExpr(In in) throws ParseException { + private Expressions RequiredExpr(In in) throws ParseException { parser.begin(); return parser.success(required(Expr(in),"Bad expression")); } - private Code Expr(In in) throws ParseException { + private Expressions Expr(In in) throws ParseException { parser.begin(); - Code exp; + Expressions exp; return (exp = VarArgs(in)) != null || (exp = JspExpressions(in)) != null || (exp = OrExpr(in)) != null ? parser.success(exp) - : parser.failure((Code)null) + : parser.failure((Expressions)null) ; } - private Code OrExpr(In in) throws ParseException { + private Expressions OrExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = AndExpr(in); + Expressions exp = AndExpr(in); if( exp==null ) return parser.failure(null); while( Keyword("or",in) ) { @@ -567,9 +567,9 @@ return parser.success(exp); } - private Code AndExpr(In in) throws ParseException { + private Expressions AndExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = RelExpr(in); + Expressions exp = RelExpr(in); if( exp==null ) return parser.failure(null); while( Keyword("and",in) ) { @@ -578,9 +578,9 @@ return parser.success(exp); } - private Code RelExpr(In in) throws ParseException { + private Expressions RelExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = ConcatExpr(in); + Expressions exp = ConcatExpr(in); if( exp==null ) return parser.failure(null); while(true) { @@ -608,9 +608,9 @@ return parser.success(exp); } - private Code ConcatExpr(In in) throws ParseException { + private Expressions ConcatExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = SumExpr(in); + Expressions exp = SumExpr(in); if( exp==null ) return parser.failure(null); if( parser.match("..") ) { @@ -620,9 +620,9 @@ return parser.success(exp); } - private Code SumExpr(In in) throws ParseException { + private Expressions SumExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = TermExpr(in); + Expressions exp = TermExpr(in); if( exp==null ) return parser.failure(null); while(true) { @@ -643,9 +643,9 @@ return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); } - private Code TermExpr(In in) throws ParseException { + private Expressions TermExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = UnaryExpr(in); + Expressions exp = UnaryExpr(in); if( exp==null ) return parser.failure(null); while(true) { @@ -669,7 +669,7 @@ return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); } - private Code UnaryExpr(In in) throws ParseException { + private Expressions UnaryExpr(In in) throws ParseException { int start = parser.begin(); if( parser.match('#') ) { Spaces(in); @@ -683,15 +683,15 @@ Spaces(in); return parser.success( new NotExpr( se(start), required(expr(UnaryExpr(in))) ) ); } - Code exp = PowExpr(in); + Expressions exp = PowExpr(in); if( exp==null ) return parser.failure(null); return parser.success(exp); } - private Code PowExpr(In in) throws ParseException { + private Expressions PowExpr(In in) throws ParseException { int start = parser.begin(); - Code exp = SingleExpr(in); + Expressions exp = SingleExpr(in); if( exp==null ) return parser.failure(null); if( parser.match('^') ) { @@ -701,9 +701,9 @@ return parser.success(exp); } - private Code SingleExpr(In in) throws ParseException { + private Expressions SingleExpr(In in) throws ParseException { parser.begin(); - Code exp; + Expressions exp; exp = FunctionExpr(in); if( exp != null ) return parser.success(exp); @@ -768,12 +768,12 @@ In inParens = in.parens(); Spaces(inParens); List<TableExpr.Field> fields = new ArrayList<TableExpr.Field>(); - ExpList.Builder builder = new ExpList.Builder(); + List<Expressions> builder = new ArrayList<Expressions>(); while( Field(fields,builder,in) && FieldSep(inParens) ); Spaces(inParens); if( !parser.match('}') ) throw parser.exception("Expected table element or '}'"); - return parser.success( new TableExpr( se(start), fields.toArray(new TableExpr.Field[0]), builder.build() ) ); + return parser.success( new TableExpr( se(start), fields.toArray(new TableExpr.Field[0]), ExpList.build(builder) ) ); } private boolean FieldSep(In in) throws ParseException { @@ -783,7 +783,7 @@ return true; } - private boolean Field(List<TableExpr.Field> fields,ExpList.Builder builder,In in) throws ParseException { + private boolean Field(List<TableExpr.Field> fields,List<Expressions> builder,In in) throws ParseException { parser.begin(); Expr exp = SubExpr(in); if( exp==null ) @@ -794,15 +794,15 @@ return parser.success(); } parser.rollback(); - Code code = Expr(in); - if( code != null ) { - builder.add(code); + Expressions exprs = Expr(in); + if( exprs != null ) { + builder.add(exprs); return parser.success(); } return parser.failure(); } - private Code VarExp(In in) throws ParseException { + private Expressions VarExp(In in) throws ParseException { Var var = VarZ(in); return var==null ? null : var.expr(); } @@ -819,25 +819,25 @@ return parser.success(var); } - private Var Var2(In in,int start,Code exp1) throws ParseException { + private Var Var2(In in,int start,Expressions exp1) throws ParseException { Var var = VarExt(in,start,exp1); if( var != null ) return var; if( parser.match("->") ) { Spaces(in); - ExpList.Builder builder = new ExpList.Builder(); + List<Expressions> builder = new ArrayList<Expressions>(); builder.add(exp1); Expr exp2 = expr(RequiredVarExpB(in)); FnCall fnCall = required(Args( in, start, exp2, builder )); return exprVar(fnCall); } - FnCall fnCall = Args( in, start, expr(exp1), new ExpList.Builder() ); + FnCall fnCall = Args( in, start, expr(exp1), new ArrayList<Expressions>() ); if( fnCall != null ) return exprVar(fnCall); return null; } - private Code RequiredVarExpB(In in) throws ParseException { + private Expressions RequiredVarExpB(In in) throws ParseException { int start = parser.begin(); Var var = required(VarStart(in)); Var var2; @@ -847,7 +847,7 @@ return parser.success(var.expr()); } - private Var VarExt(In in,int start,Code exp1) throws ParseException { + private Var VarExt(In in,int start,Expressions exp1) throws ParseException { parser.begin(); Expr exp2 = SubExpr(in); if( exp2 != null ) @@ -888,7 +888,7 @@ } private interface Var { - public Code expr(); + public Expressions expr(); public Settable settable(); } @@ -917,10 +917,10 @@ }; } - private Var exprVar(final Code expr) { + private Var exprVar(final Expressions expr) { return new Var() { - public Code expr() { + public Expressions expr() { return expr; } @@ -943,14 +943,14 @@ }; } - private FnCall Args(In in,int start,Expr fn,ExpList.Builder builder) throws ParseException { + private FnCall Args(In in,int start,Expr fn,List<Expressions> builder) throws ParseException { parser.begin(); return args(in,builder) - ? parser.success( new FnCall( se(start), fn, builder.build() ) ) + ? parser.success( new FnCall( se(start), fn, ExpList.build(builder) ) ) : parser.failure((FnCall)null); } - private boolean args(In in,ExpList.Builder builder) throws ParseException { + private boolean args(In in,List<Expressions> builder) throws ParseException { if( parser.match('(') ) { In inParens = in.parens(); Spaces(inParens); @@ -979,13 +979,13 @@ } private Expressions ExpList(In in) throws ParseException { - ExpList.Builder builder = new ExpList.Builder(); - return ExpList(in,builder) ? builder.build() : null; + List<Expressions> builder = new ArrayList<Expressions>(); + return ExpList(in,builder) ? ExpList.build(builder) : null; } - private boolean ExpList(In in,ExpList.Builder builder) throws ParseException { + private boolean ExpList(In in,List<Expressions> builder) throws ParseException { parser.begin(); - Code exp = Expr(in); + Expressions exp = Expr(in); if( exp==null ) return parser.failure(); builder.add(exp);
--- a/src/luan/interp/SetStmt.java Tue Jun 17 02:57:14 2014 +0000 +++ b/src/luan/interp/SetStmt.java Tue Jun 17 09:55:43 2014 +0000 @@ -9,7 +9,7 @@ private final Expressions expressions; SetStmt(Settable var,Expr expr) { - this( new Settable[]{var}, new ExpList.SingleExpList(expr) ); + this( new Settable[]{var}, expr ); } SetStmt(Settable[] vars,Expressions expressions) {