Mercurial Hosting > luan
changeset 107:dbf459397217
change OutputStatement to JspExpressions;
fix multiple results handling;
git-svn-id: https://luan-java.googlecode.com/svn/trunk@108 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Mon, 19 May 2014 09:17:57 +0000 |
parents | 1a29dd3888f6 |
children | 3c404a296995 |
files | src/luan/interp/ExpList.java src/luan/interp/LuanParser.java src/luan/interp/OutputStmt.java |
diffstat | 3 files changed, 139 insertions(+), 134 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/interp/ExpList.java Mon May 19 06:23:18 2014 +0000 +++ b/src/luan/interp/ExpList.java Mon May 19 09:17:57 2014 +0000 @@ -63,10 +63,19 @@ adders.add( new ExpressionsAdder(expressions) ); } + void add(Code code) { + if( code instanceof Expr ) { + add((Expr)code); + } else { + add((Expressions)code); + } + } + Expressions build() { - if( adders.isEmpty() ) + int size = adders.size(); + if( size == 0 ) return emptyExpList; - if( adders.size() == 1 ) { + if( size == 1 ) { Adder adder = adders.get(0); if( adder instanceof ExpressionsAdder ) { ExpressionsAdder ea = (ExpressionsAdder)adder; @@ -75,7 +84,14 @@ ExprAdder ea = (ExprAdder)adder; return new SingleExpList(ea.expr); } - return new ExpList( adders.toArray(new Adder[0]) ); + 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); } }
--- a/src/luan/interp/LuanParser.java Mon May 19 06:23:18 2014 +0000 +++ b/src/luan/interp/LuanParser.java Mon May 19 09:17:57 2014 +0000 @@ -143,6 +143,12 @@ return t; } + private static Expr expr(Code code) { + if( code instanceof Expressions ) + return new ExpressionsExpr((Expressions)code); + return (Expr)code; + } + private FnDef newFnDef(int start,Stmt stmt) { return new FnDef( se(start), stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); } @@ -186,18 +192,8 @@ return parser.success(); if( parser.match( "--" ) ) { while( parser.noneOf("\r\n") ); - EndOfLine(); - return parser.success(); } - if( EndOfLine() ) - return parser.success(); - parser.rollback(); - Stmt stmt = OutputStmt(); - if( stmt != null ) { - stmts.add(stmt); - return parser.success(); - } - return parser.failure(); + return EndOfLine() ? parser.success() : parser.failure(); } private boolean EndOfLine() { @@ -227,7 +223,7 @@ } } - private Stmt OutputStmt() throws ParseException { + private Expressions JspExpressions() throws ParseException { int start = parser.begin(); if( !parser.match( "%>" ) ) return parser.failure(null); @@ -240,14 +236,14 @@ RequiredMatch( "%>" ); } else if( parser.match( "<%" ) ) { Spaces(); - return parser.success(new OutputStmt( se(start), builder.build() )); + return parser.success(builder.build()); } else { int i = parser.currentIndex(); do { if( parser.match( "%>" ) ) throw parser.exception("'%>' unexpected"); if( !parser.anyChar() ) - throw parser.exception("Unclosed output statement"); + throw parser.exception("Unclosed JSP expressions"); } while( !parser.test( "<%" ) ); String match = parser.textFrom(i); builder.add( new ConstExpr(match) ); @@ -274,7 +270,7 @@ Var var = nameVar(start,RequiredName()); while( parser.match( '.' ) ) { Spaces(); - var = indexVar( start, var.expr(), NameExpr(false) ); + var = indexVar( start, expr(var.expr()), NameExpr(false) ); } Settable fnName = var.settable(); @@ -309,7 +305,7 @@ List<String> names = RequiredNameList(false); if( !Keyword("in") ) return parser.failure(null); - Expr expr = RequiredExpr(); + Expr expr = expr(RequiredExpr()); RequiredKeyword("do"); addSymbols(names); Stmt loop = RequiredLoopBlock(); @@ -326,22 +322,22 @@ String name = RequiredName(); RequiredMatch( "=" ); Spaces(); - Expr from = RequiredExpr(); + Expr from = expr(RequiredExpr()); Expr to; Expr step; if( parser.match(',') ) { Spaces(); - to = RequiredExpr(); + to = expr(RequiredExpr()); if( parser.match(',') ) { Spaces(); - step = RequiredExpr(); + step = expr(RequiredExpr()); } else { step = new ConstExpr(1); } } else { RequiredKeyword("to"); - to = RequiredExpr(); - step = Keyword("step") ? RequiredExpr() : new ConstExpr(1); + to = expr(RequiredExpr()); + step = Keyword("step") ? expr(RequiredExpr()) : new ConstExpr(1); } addSymbol(name); // add "for" var to symbols RequiredKeyword("do"); @@ -425,7 +421,7 @@ parser.begin(); if( !Keyword("while") ) return parser.failure(null); - Expr cnd = RequiredExpr(); + Expr cnd = expr(RequiredExpr()); RequiredKeyword("do"); Stmt loop = RequiredLoopBlock(); RequiredKeyword("end"); @@ -438,7 +434,7 @@ return parser.failure(null); Stmt loop = RequiredLoopBlock(); RequiredKeyword("until"); - Expr cnd = RequiredExpr(); + Expr cnd = expr(RequiredExpr()); return parser.success( new RepeatStmt(loop,cnd) ); } @@ -457,7 +453,7 @@ } private Stmt IfStmt2() throws ParseException { - Expr cnd = RequiredExpr(); + Expr cnd = expr(RequiredExpr()); RequiredKeyword("then"); Stmt thenBlock = RequiredBlock(); Stmt elseBlock; @@ -509,106 +505,106 @@ return var.settable(); } - private Expr RequiredExpr() throws ParseException { + private Code RequiredExpr() throws ParseException { return RequiredExpr(false); } - private Expr Expr() throws ParseException { + private Code Expr() throws ParseException { return Expr(false); } - private Expr RequiredExpr(boolean inParens) throws ParseException { + private Code RequiredExpr(boolean inParens) throws ParseException { parser.begin(); return parser.success(required(Expr(inParens),"Bad expression")); } - private Expr Expr(boolean inParens) throws ParseException { + private Code Expr(boolean inParens) throws ParseException { parser.begin(); - Expressions exps = VarArgs(inParens); - if( exps != null ) - return parser.success( new ExpressionsExpr(exps) ); - Expr exp = OrExpr(inParens); - if( exp==null ) - return parser.failure(null); - return parser.success(exp); + Code exp; + return (exp = VarArgs(inParens)) != null + || (exp = JspExpressions()) != null + || (exp = OrExpr(inParens)) != null + ? parser.success(exp) + : parser.failure((Code)null) + ; } - private Expr OrExpr(boolean inParens) throws ParseException { + private Code OrExpr(boolean inParens) throws ParseException { int start = parser.begin(); - Expr exp = AndExpr(inParens); + Code exp = AndExpr(inParens); if( exp==null ) return parser.failure(null); while( Keyword("or",inParens) ) { - exp = new OrExpr( se(start), exp, required(AndExpr(inParens)) ); + exp = new OrExpr( se(start), expr(exp), required(expr(AndExpr(inParens))) ); } return parser.success(exp); } - private Expr AndExpr(boolean inParens) throws ParseException { + private Code AndExpr(boolean inParens) throws ParseException { int start = parser.begin(); - Expr exp = RelExpr(inParens); + Code exp = RelExpr(inParens); if( exp==null ) return parser.failure(null); while( Keyword("and",inParens) ) { - exp = new AndExpr( se(start), exp, required(RelExpr(inParens)) ); + exp = new AndExpr( se(start), expr(exp), required(expr(RelExpr(inParens))) ); } return parser.success(exp); } - private Expr RelExpr(boolean inParens) throws ParseException { + private Code RelExpr(boolean inParens) throws ParseException { int start = parser.begin(); - Expr exp = ConcatExpr(inParens); + Code exp = ConcatExpr(inParens); if( exp==null ) return parser.failure(null); while(true) { if( parser.match("==") ) { Spaces(inParens); - exp = new EqExpr( se(start), exp, required(ConcatExpr(inParens)) ); + exp = new EqExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); } else if( parser.match("~=") ) { Spaces(inParens); - exp = new NotExpr( se(start), new EqExpr( se(start), exp, required(ConcatExpr(inParens)) ) ); + exp = new NotExpr( se(start), new EqExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ) ); } else if( parser.match("<=") ) { Spaces(inParens); - exp = new LeExpr( se(start), exp, required(ConcatExpr(inParens)) ); + exp = new LeExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); } else if( parser.match(">=") ) { Spaces(inParens); - exp = new LeExpr( se(start), required(ConcatExpr(inParens)), exp ); + exp = new LeExpr( se(start), required(expr(ConcatExpr(inParens))), expr(exp) ); } else if( parser.match("<") ) { Spaces(inParens); - exp = new LtExpr( se(start), exp, required(ConcatExpr(inParens)) ); + exp = new LtExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); } else if( parser.match(">") ) { Spaces(inParens); - exp = new LtExpr( se(start), required(ConcatExpr(inParens)), exp ); + exp = new LtExpr( se(start), required(expr(ConcatExpr(inParens))), expr(exp) ); } else break; } return parser.success(exp); } - private Expr ConcatExpr(boolean inParens) throws ParseException { + private Code ConcatExpr(boolean inParens) throws ParseException { int start = parser.begin(); - Expr exp = SumExpr(inParens); + Code exp = SumExpr(inParens); if( exp==null ) return parser.failure(null); if( parser.match("..") ) { Spaces(inParens); - exp = new ConcatExpr( se(start), exp, required(ConcatExpr(inParens)) ); + exp = new ConcatExpr( se(start), expr(exp), required(expr(ConcatExpr(inParens))) ); } return parser.success(exp); } - private Expr SumExpr(boolean inParens) throws ParseException { + private Code SumExpr(boolean inParens) throws ParseException { int start = parser.begin(); - Expr exp = TermExpr(inParens); + Code exp = TermExpr(inParens); if( exp==null ) return parser.failure(null); while(true) { if( parser.match('+') ) { Spaces(inParens); - exp = new AddExpr( se(start), exp, required(TermExpr(inParens)) ); + exp = new AddExpr( se(start), expr(exp), required(expr(TermExpr(inParens))) ); } else if( Minus() ) { Spaces(inParens); - exp = new SubExpr( se(start), exp, required(TermExpr(inParens)) ); + exp = new SubExpr( se(start), expr(exp), required(expr(TermExpr(inParens))) ); } else break; } @@ -620,62 +616,67 @@ return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); } - private Expr TermExpr(boolean inParens) throws ParseException { + private Code TermExpr(boolean inParens) throws ParseException { int start = parser.begin(); - Expr exp = UnaryExpr(inParens); + Code exp = UnaryExpr(inParens); if( exp==null ) return parser.failure(null); while(true) { if( parser.match('*') ) { Spaces(inParens); - exp = new MulExpr( se(start), exp, required(UnaryExpr(inParens)) ); + exp = new MulExpr( se(start), expr(exp), required(expr(UnaryExpr(inParens))) ); } else if( parser.match('/') ) { Spaces(inParens); - exp = new DivExpr( se(start), exp, required(UnaryExpr(inParens)) ); - } else if( parser.match('%') ) { + exp = new DivExpr( se(start), expr(exp), required(expr(UnaryExpr(inParens))) ); + } else if( Mod() ) { Spaces(inParens); - exp = new ModExpr( se(start), exp, required(UnaryExpr(inParens)) ); + exp = new ModExpr( se(start), expr(exp), required(expr(UnaryExpr(inParens))) ); } else break; } return parser.success(exp); } - private Expr UnaryExpr(boolean inParens) throws ParseException { + private boolean Mod() { + parser.begin(); + return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); + } + + private Code UnaryExpr(boolean inParens) throws ParseException { int start = parser.begin(); if( parser.match('#') ) { Spaces(inParens); - return parser.success( new LenExpr( se(start), required(UnaryExpr(inParens)) ) ); + return parser.success( new LenExpr( se(start), required(expr(UnaryExpr(inParens))) ) ); } if( Minus() ) { Spaces(inParens); - return parser.success( new UnmExpr( se(start), required(UnaryExpr(inParens)) ) ); + return parser.success( new UnmExpr( se(start), required(expr(UnaryExpr(inParens))) ) ); } if( Keyword("not",inParens) ) { Spaces(inParens); - return parser.success( new NotExpr( se(start), required(UnaryExpr(inParens)) ) ); + return parser.success( new NotExpr( se(start), required(expr(UnaryExpr(inParens))) ) ); } - Expr exp = PowExpr(inParens); + Code exp = PowExpr(inParens); if( exp==null ) return parser.failure(null); return parser.success(exp); } - private Expr PowExpr(boolean inParens) throws ParseException { + private Code PowExpr(boolean inParens) throws ParseException { int start = parser.begin(); - Expr exp = SingleExpr(inParens); + Code exp = SingleExpr(inParens); if( exp==null ) return parser.failure(null); if( parser.match('^') ) { Spaces(inParens); - exp = new ConcatExpr( se(start), exp, required(PowExpr(inParens)) ); + exp = new ConcatExpr( se(start), expr(exp), required(expr(PowExpr(inParens))) ); } return parser.success(exp); } - private Expr SingleExpr(boolean inParens) throws ParseException { + private Code SingleExpr(boolean inParens) throws ParseException { parser.begin(); - Expr exp; + Code exp; exp = FunctionExpr(inParens); if( exp != null ) return parser.success(exp); @@ -740,7 +741,8 @@ List<TableExpr.Field> fields = new ArrayList<TableExpr.Field>(); ExpList.Builder builder = new ExpList.Builder(); while( Field(fields,builder) && FieldSep() ); - RequiredMatch('}'); + 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() ) ); } @@ -757,19 +759,19 @@ if( exp==null ) exp = NameExpr(true); if( exp!=null && parser.match('=') ) { - fields.add( new TableExpr.Field( exp, required(Expr(true)) ) ); + fields.add( new TableExpr.Field( exp, required(expr(Expr(true))) ) ); return parser.success(); } parser.rollback(); - exp = Expr(true); - if( exp != null ) { - builder.add(exp); + Code code = Expr(true); + if( code != null ) { + builder.add(code); return parser.success(); } return parser.failure(); } - private Expr VarExp(boolean inParens) throws ParseException { + private Code VarExp(boolean inParens) throws ParseException { Var var = VarZ(inParens); return var==null ? null : var.expr(); } @@ -786,7 +788,7 @@ return parser.success(var); } - private Var Var2(boolean inParens,int start,Expr exp1) throws ParseException { + private Var Var2(boolean inParens,int start,Code exp1) throws ParseException { Var var = VarExt(inParens,start,exp1); if( var != null ) return var; @@ -794,17 +796,17 @@ Spaces(inParens); ExpList.Builder builder = new ExpList.Builder(); builder.add(exp1); - Expr exp2 = RequiredVarExpB(inParens); + Expr exp2 = expr(RequiredVarExpB(inParens)); FnCall fnCall = required(Args( inParens, start, exp2, builder )); - return exprVar( new ExpressionsExpr(fnCall) ); + return exprVar(fnCall); } - FnCall fnCall = Args( inParens, start, exp1, new ExpList.Builder() ); + FnCall fnCall = Args( inParens, start, expr(exp1), new ExpList.Builder() ); if( fnCall != null ) - return exprVar( new ExpressionsExpr(fnCall) ); + return exprVar(fnCall); return null; } - private Expr RequiredVarExpB(boolean inParens) throws ParseException { + private Code RequiredVarExpB(boolean inParens) throws ParseException { int start = parser.begin(); Var var = required(VarStart(inParens)); Var var2; @@ -814,17 +816,17 @@ return parser.success(var.expr()); } - private Var VarExt(boolean inParens,int start,Expr exp1) throws ParseException { + private Var VarExt(boolean inParens,int start,Code exp1) throws ParseException { parser.begin(); Expr exp2 = SubExpr(inParens); exp2 = SubExpr(inParens); if( exp2 != null ) - return parser.success(indexVar(start,exp1,exp2)); + return parser.success(indexVar(start,expr(exp1),exp2)); if( parser.match('.') ) { Spaces(inParens); exp2 = NameExpr(inParens); if( exp2!=null ) - return parser.success(indexVar(start,exp1,exp2)); + return parser.success(indexVar(start,expr(exp1),exp2)); } return parser.failure(null); } @@ -833,7 +835,7 @@ int start = parser.begin(); if( parser.match('(') ) { Spaces(true); - Expr exp = Expr(true); + Expr exp = expr(Expr(true)); RequiredMatch(')'); Spaces(inParens); return parser.success(exprVar(exp)); @@ -855,7 +857,7 @@ } private interface Var { - public Expr expr(); + public Code expr(); public Settable settable(); } @@ -884,10 +886,10 @@ }; } - private Var exprVar(final Expr expr) { + private Var exprVar(final Code expr) { return new Var() { - public Expr expr() { + public Code expr() { return expr; } @@ -912,25 +914,36 @@ private FnCall Args(boolean inParens,int start,Expr fn,ExpList.Builder builder) throws ParseException { parser.begin(); + return args(inParens,builder) + ? parser.success( new FnCall( se(start), fn, builder.build() ) ) + : parser.failure((FnCall)null); + } + + private boolean args(boolean inParens,ExpList.Builder builder) throws ParseException { if( parser.match('(') ) { Spaces(true); ExpList(true,builder); // optional - RequiredMatch(')'); + if( !parser.match(')') ) + throw parser.exception("Expression or ')' expected"); Spaces(inParens); - } else { - Expr exp = TableExpr(inParens); - if( exp != null ) { - builder.add(exp); - } else { - String s = StringLiteral(inParens); - if( s != null ) { - builder.add( new ConstExpr(s) ); - } else { - return parser.failure(null); - } - } + return true; + } + Expr exp = TableExpr(inParens); + if( exp != null ) { + builder.add(exp); + return true; } - return parser.success( new FnCall( se(start), fn, builder.build() ) ); + String s = StringLiteral(inParens); + if( s != null ) { + builder.add( new ConstExpr(s) ); + return true; + } + Expressions exps = JspExpressions(); + if( exps != null ) { + builder.add(exps); + return true; + } + return false; } private Expressions ExpList() throws ParseException { @@ -944,7 +957,7 @@ private boolean ExpList(boolean inParens,ExpList.Builder builder) throws ParseException { parser.begin(); - Expr exp = Expr(inParens); + Code exp = Expr(inParens); if( exp==null ) return parser.failure(); builder.add(exp); @@ -960,7 +973,7 @@ if( !parser.match('[') ) return parser.failure(null); Spaces(true); - Expr exp = RequiredExpr(true); + Expr exp = expr(RequiredExpr(true)); RequiredMatch(']'); Spaces(inParens); return parser.success(exp);
--- a/src/luan/interp/OutputStmt.java Mon May 19 06:23:18 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -package luan.interp; - -import luan.Luan; -import luan.LuanSource; -import luan.LuanException; -import luan.LuanBit; - - -final class OutputStmt extends CodeImpl implements Stmt { - private final Expressions expressions; - - OutputStmt(LuanSource.Element se,Expressions expressions) { - super(se); - this.expressions = expressions; - } - - @Override public void eval(LuanStateImpl luan) throws LuanException { - LuanBit bit = luan.bit(se); - for( Object obj : expressions.eval(luan) ) { - luan.out.print( bit.toString(obj) ); - } - } - -}