Mercurial Hosting > luan
changeset 679:43522473599d
make java line numbers match
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 14 Apr 2016 15:19:25 -0600 |
parents | 49f3d290bebd |
children | ecd436959855 |
files | core/src/luan/impl/LuanParser.java core/src/luan/impl/Parser.java |
diffstat | 2 files changed, 281 insertions(+), 229 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/impl/LuanParser.java Wed Apr 13 16:24:48 2016 -0600 +++ b/core/src/luan/impl/LuanParser.java Thu Apr 14 15:19:25 2016 -0600 @@ -1,5 +1,7 @@ package luan.impl; +//import java.io.StringWriter; +//import java.io.PrintWriter; import java.util.Set; import java.util.HashSet; import java.util.Arrays; @@ -36,9 +38,9 @@ stmt.add( new Object() { @Override public String toString() { if( !isPointer ) - return "Object " + javaName + ";\n"; + return "Object " + javaName + "; "; else - return "final Pointer " + javaName + " = new Pointer();\n"; + return "final Pointer " + javaName + " = new Pointer(); "; } } ); } else { @@ -55,9 +57,9 @@ stmt.add( new Object() { @Override public String toString() { if( !isPointer ) - return ";\n"; + return "; "; else - return ");\n"; + return "); "; } } ); } @@ -90,7 +92,7 @@ } String init() { - return "upValues[" + i + "] = " + value + ";\n"; + return "upValues[" + i + "] = " + value + "; "; } @Override public Expr exp() { @@ -164,34 +166,29 @@ } private static class In { - static final In NOTHING = new In(false,false); + static final In NOTHING = new In(false); - final boolean parens; final boolean template; - private In(boolean parens,boolean template) { - this.parens = parens; + private In(boolean template) { this.template = template; } - In parens() { - return parens ? this : new In(true,false); - } - In template() { - return template ? this : new In(false,true); + return template ? this : new In(true); } } // final LuanSource source; private Frame frame; private final Parser parser; - private final Stmts top = new Stmts(); + private final Stmts top; LuanParser(String sourceName,String sourceText) { // this.source = source; this.frame = new Frame(); this.parser = new Parser(sourceName,sourceText); + this.top = new Stmts(); } void addVar(String name) { @@ -199,7 +196,7 @@ if( name != null ) { LocalSym sym = frame.addLocalSym( name ); sym.isPointer = true; - top.add( "final Pointer " + sym.javaName + " = upValues[" + upSym.i + "];\n" ); + top.add( "final Pointer " + sym.javaName + " = upValues[" + upSym.i + "]; " ); } } @@ -252,13 +249,13 @@ } Class Expression() throws ParseException { - Spaces(In.NOTHING); + Spaces(); parser.begin(); Expr expr = ExprZ(In.NOTHING); if( expr != null && parser.endOfInput() ) { top.add( "return " ); top.addAll( expr ); - top.add( ";\n" ); + top.add( "; " ); top.hasReturn = true; return parser.success(newFnClass(top)); } @@ -276,10 +273,10 @@ } void GetRequiredModule() throws ParseException { - Spaces(In.NOTHING); + Spaces(); parser.begin(); frame.isVarArg = true; - top.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);\n" ); + top.add( "final Object[] varArgs = LuanImpl.varArgs(args,0); " ); Stmts block = RequiredBlock(); top.addAll( block ); top.hasReturn = block.hasReturn; @@ -292,37 +289,40 @@ Stmts stmts = new Stmts(); int stackStart = symbolsSize(); boolean isReturn = Stmt(stmts); - while( !isReturn && StmtSep(stmts) ) { - Spaces(In.NOTHING); + while( !isReturn && (StmtSep() || TemplateSep(stmts)) ) { + Spaces(); + stmts.addNewLines(); isReturn = Stmt(stmts); } - while( StmtSep(null) ) - Spaces(In.NOTHING); + while( StmtSep() ) + Spaces(); + stmts.addNewLines(); int stackEnd = symbolsSize(); popSymbols( stackEnd - stackStart ); stmts.hasReturn = isReturn; return stmts; } - private boolean StmtSep(Stmts stmts) throws ParseException { - parser.begin(); - if( parser.match( ';' ) ) - return parser.success(); - if( EndOfLine() ) - return parser.success(); - if( stmts != null ) { -// parser.rollback(); - Stmts stmt = TemplateStmt(); - if( stmt != null ) { - stmts.addAll(stmt); - return parser.success(); - } + private boolean StmtSep() throws ParseException { + return parser.match( ';' ) || EndOfLine(); + } + + private boolean TemplateSep(Stmts stmts) throws ParseException { + Stmts stmt = TemplateStmt(); + if( stmt != null ) { + stmts.addAll(stmt); + return true; } - return parser.failure(); + return false; } private boolean EndOfLine() { - return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); + if( parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ) ) { + parser.sb().append('\n'); + return true; + } else { + return false; + } } private boolean Stmt(Stmts stmts) throws ParseException { @@ -379,7 +379,7 @@ Expr writeCall = callExpStr( writeExp, exprs ); Stmts stmt = new Stmts(); stmt.addAll( writeCall ); - stmt.add( ";\n" ); + stmt.add( "; " ); return stmt; } @@ -394,11 +394,11 @@ List<Expr> builder = new ArrayList<Expr>(); while(true) { if( parser.match( "<%=" ) ) { - Spaces(inTemplate); + Spaces(); builder.add( RequiredExpr(inTemplate) ); RequiredMatch( "%>" ); } else if( parser.match( "<%" ) ) { - Spaces(inTemplate); + Spaces(); return parser.success(expString(builder)); } else { int i = parser.currentIndex(); @@ -416,7 +416,7 @@ private Stmts ReturnStmt() throws ParseException { parser.begin(); - if( !Keyword("return",In.NOTHING) ) + if( !Keyword("return") ) return parser.failure(null); Expr exprs = ExpStringList(In.NOTHING); Stmts stmt = new Stmts(); @@ -425,20 +425,20 @@ stmt.addAll( exprs ); else stmt.add( "LuanFunction.NOTHING" ); - stmt.add( ";\n" ); + stmt.add( "; " ); return parser.success( stmt ); } private Stmts FunctionStmt() throws ParseException { parser.begin(); - if( !Keyword("function",In.NOTHING) ) + if( !Keyword("function") ) return parser.failure(null); parser.currentIndex(); - Var var = nameVar(RequiredName(In.NOTHING)); + Var var = nameVar(RequiredName()); while( parser.match( '.' ) ) { - Spaces(In.NOTHING); - Expr exp = NameExpr(In.NOTHING); + Spaces(); + Expr exp = NameExpr(); if( exp==null ) return parser.failure(null); var = indexVar( var.exp(), exp ); @@ -450,10 +450,10 @@ private Stmts LocalFunctionStmt() throws ParseException { parser.begin(); - if( !(Keyword("local",In.NOTHING) && Keyword("function",In.NOTHING)) ) + if( !(Keyword("local") && Keyword("function")) ) return parser.failure(null); Stmts stmt = new Stmts(); - String name = RequiredName(In.NOTHING); + String name = RequiredName(); stmt.addAll( addSymbol(name,null) ); Expr fnDef = RequiredFunction(In.NOTHING); stmt.addAll( nameVar(name).set(fnDef) ); @@ -462,12 +462,12 @@ private Stmts BreakStmt() throws ParseException { parser.begin(); - if( !Keyword("break",In.NOTHING) ) + if( !Keyword("break") ) return parser.failure(null); if( frame.loops <= 0 ) throw parser.exception("'break' outside of loop"); Stmts stmt = new Stmts(); - stmt.add( "break;\n" ); + stmt.add( "break; " ); return parser.success( stmt ); } @@ -476,10 +476,10 @@ private Stmts ForStmt() throws ParseException { parser.begin(); int stackStart = symbolsSize(); - if( !Keyword("for",In.NOTHING) ) + if( !Keyword("for") ) return parser.failure(null); - List<String> names = RequiredNameList(In.NOTHING); - if( !Keyword("in",In.NOTHING) ) + List<String> names = RequiredNameList(); + if( !Keyword("in") ) return parser.failure(null); Expr expr = RequiredExpr(In.NOTHING).single(); RequiredKeyword("do",In.NOTHING); @@ -492,23 +492,23 @@ +"LuanFunction "+fnVar+" = Luan.checkFunction(" ); stmt.addAll( expr ); - stmt.add( ");\n" ); - stmt.add( "while(true) {\n" ); + stmt.add( "); " ); + stmt.add( "while(true) { " ); stmt.addAll( makeLocalSetStmt(names,fnExp) ); stmt.add( "if( " ); stmt.addAll( nameVar(names.get(0)).exp() ); - stmt.add( "==null ) break;\n" ); + stmt.add( "==null ) break; " ); Stmts loop = RequiredLoopBlock(); RequiredKeyword("end",In.NOTHING); stmt.addAll( loop ); - stmt.add( "}\n" ); + stmt.add( "} " ); popSymbols( symbolsSize() - stackStart ); return parser.success(stmt); } private Stmts DoStmt() throws ParseException { parser.begin(); - if( !Keyword("do",In.NOTHING) ) + if( !Keyword("do") ) return parser.failure(null); Stmts stmt = RequiredBlock(); RequiredKeyword("end",In.NOTHING); @@ -517,17 +517,17 @@ private Stmts LocalStmt() throws ParseException { parser.begin(); - if( !Keyword("local",In.NOTHING) ) + if( !Keyword("local") ) return parser.failure(null); - List<String> names = NameList(In.NOTHING); + List<String> names = NameList(); if( names==null ) { - if( Keyword("function",In.NOTHING) ) + if( Keyword("function") ) return parser.failure(null); // handled later throw parser.exception("Invalid local statement"); } Stmts stmt = new Stmts(); if( parser.match( '=' ) ) { - Spaces(In.NOTHING); + Spaces(); Expr values = ExpStringList(In.NOTHING); if( values==null ) throw parser.exception("Expressions expected"); @@ -542,32 +542,32 @@ return parser.success(stmt); } - private List<String> RequiredNameList(In in) throws ParseException { + private List<String> RequiredNameList() throws ParseException { parser.begin(); - List<String> names = NameList(in); + List<String> names = NameList(); if( names==null ) throw parser.exception("Name expected"); return parser.success(names); } - private List<String> NameList(In in) throws ParseException { - String name = Name(in); + private List<String> NameList() throws ParseException { + String name = Name(); if( name==null ) return null; List<String> names = new ArrayList<String>(); names.add(name); - while( (name=anotherName(in)) != null ) { + while( (name=anotherName()) != null ) { names.add(name); } return names; } - private String anotherName(In in) throws ParseException { + private String anotherName() throws ParseException { parser.begin(); if( !parser.match( ',' ) ) return parser.failure(null); - Spaces(in); - String name = Name(in); + Spaces(); + String name = Name(); if( name==null ) return parser.failure(null); return parser.success(name); @@ -575,7 +575,7 @@ private Stmts WhileStmt() throws ParseException { parser.begin(); - if( !Keyword("while",In.NOTHING) ) + if( !Keyword("while") ) return parser.failure(null); Expr cnd = RequiredExpr(In.NOTHING).single(); RequiredKeyword("do",In.NOTHING); @@ -584,25 +584,25 @@ Stmts stmt = new Stmts(); stmt.add( "while( Luan.checkBoolean(" ); stmt.addAll( cnd ); - stmt.add( ") ) {\n" ); + stmt.add( ") ) { " ); stmt.addAll( loop ); - stmt.add( "}\n" ); + stmt.add( "} " ); return parser.success( stmt ); } private Stmts RepeatStmt() throws ParseException { parser.begin(); - if( !Keyword("repeat",In.NOTHING) ) + if( !Keyword("repeat") ) return parser.failure(null); Stmts loop =RequiredLoopBlock(); RequiredKeyword("until",In.NOTHING); Expr cnd = RequiredExpr(In.NOTHING).single(); Stmts stmt = new Stmts(); - stmt.add( "do {\n" ); + stmt.add( "do { " ); stmt.addAll( loop ); stmt.add( "} while( !Luan.checkBoolean(" ); stmt.addAll( cnd ); - stmt.add( ") );\n" ); + stmt.add( ") ); " ); return parser.success( stmt ); } @@ -615,7 +615,7 @@ private Stmts IfStmt() throws ParseException { parser.begin(); - if( !Keyword("if",In.NOTHING) ) + if( !Keyword("if") ) return parser.failure(null); Stmts stmt = new Stmts(); Expr cnd; @@ -625,24 +625,24 @@ block = RequiredBlock(); stmt.add( "if( Luan.checkBoolean(" ); stmt.addAll( cnd ); - stmt.add( ") ) {\n" ); + stmt.add( ") ) { " ); stmt.addAll( block ); - while( Keyword("elseif",In.NOTHING) ) { + while( Keyword("elseif") ) { cnd = RequiredExpr(In.NOTHING).single(); RequiredKeyword("then",In.NOTHING); block = RequiredBlock(); stmt.add( "} else if( Luan.checkBoolean(" ); stmt.addAll( cnd ); - stmt.add( ") ) {\n" ); + stmt.add( ") ) { " ); stmt.addAll( block ); } - if( Keyword("else",In.NOTHING) ) { + if( Keyword("else") ) { block = RequiredBlock(); - stmt.add( "} else {\n" ); + stmt.add( "} else { " ); stmt.addAll( block ); } RequiredKeyword("end",In.NOTHING); - stmt.add( "}\n" ); + stmt.add( "} " ); return parser.success( stmt ); } @@ -654,7 +654,7 @@ return parser.failure(null); vars.add(v); while( parser.match( ',' ) ) { - Spaces(In.NOTHING); + Spaces(); v = SettableVar(); if( v == null ) return parser.failure(null); @@ -662,7 +662,7 @@ } if( !parser.match( '=' ) ) return parser.failure(null); - Spaces(In.NOTHING); + Spaces(); Expr values = ExpStringList(In.NOTHING); if( values==null ) // throw parser.exception("Expressions expected"); @@ -678,7 +678,7 @@ String varName = values.valType==Val.ARRAY ? "a" : "t"; stmt.add( varName + " = " ); stmt.addAll( values ); - stmt.add( ";\n" ); + stmt.add( "; " ); Expr t = new Expr(values.valType,false); t.add( varName ); t = t.single(); @@ -699,7 +699,7 @@ String varName = values.valType==Val.ARRAY ? "a" : "t"; stmt.add( varName + " = " ); stmt.addAll( values ); - stmt.add( ";\n" ); + stmt.add( "; " ); Expr t = new Expr(values.valType,false); t.add( varName ); t = t.single(); @@ -724,7 +724,7 @@ } else { stmt.addAll( exp ); } - stmt.add( ";\n" ); + stmt.add( "; " ); return parser.success( stmt ); } return parser.failure(null); @@ -752,7 +752,7 @@ Expr exp = AndExpr(in); if( exp==null ) return parser.failure(null); - while( Keyword("or",in) ) { + while( Keyword("or") ) { exp = exp.single(); Expr exp2 = required(RelExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,true); @@ -771,7 +771,7 @@ Expr exp = RelExpr(in); if( exp==null ) return parser.failure(null); - while( Keyword("and",in) ) { + while( Keyword("and") ) { exp = exp.single(); Expr exp2 = required(RelExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,true); @@ -792,7 +792,7 @@ return parser.failure(null); while(true) { if( parser.match("==") ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(ConcatExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -803,7 +803,7 @@ newExp.add( ")" ); exp = newExp; } else if( parser.match("~=") ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(ConcatExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -814,7 +814,7 @@ newExp.add( ")" ); exp = newExp; } else if( parser.match("<=") ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(ConcatExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -825,7 +825,7 @@ newExp.add( ")" ); exp = newExp; } else if( parser.match(">=") ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(ConcatExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -836,7 +836,7 @@ newExp.add( ")" ); exp = newExp; } else if( parser.match("<") ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(ConcatExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -847,7 +847,7 @@ newExp.add( ")" ); exp = newExp; } else if( parser.match(">") ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(ConcatExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -869,7 +869,7 @@ if( exp==null ) return parser.failure(null); if( parser.match("..") ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(ConcatExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -890,7 +890,7 @@ return parser.failure(null); while(true) { if( parser.match('+') ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(TermExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -901,7 +901,7 @@ newExp.add( ")" ); exp = newExp; } else if( Minus() ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(TermExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -929,7 +929,7 @@ return parser.failure(null); while(true) { if( parser.match('*') ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(UnaryExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -940,7 +940,7 @@ newExp.add( ")" ); exp = newExp; } else if( parser.match('/') ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(UnaryExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -951,7 +951,7 @@ newExp.add( ")" ); exp = newExp; } else if( Mod() ) { - Spaces(in); + Spaces(); exp = exp.single(); Expr exp2 = required(UnaryExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); @@ -975,7 +975,7 @@ private Expr UnaryExpr(In in) throws ParseException { parser.begin(); if( parser.match('#') ) { - Spaces(in); + Spaces(); Expr exp = required(UnaryExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); newExp.add( "LuanImpl.len(luan," ); @@ -984,7 +984,7 @@ return parser.success(newExp); } if( Minus() ) { - Spaces(in); + Spaces(); Expr exp = required(UnaryExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); newExp.add( "LuanImpl.unm(luan," ); @@ -992,8 +992,8 @@ newExp.add( ")" ); return parser.success(newExp); } - if( Keyword("not",in) ) { - Spaces(in); + if( Keyword("not") ) { + Spaces(); Expr exp = required(UnaryExpr(in)).single(); Expr newExp = new Expr(Val.SINGLE,false); newExp.add( "!Luan.checkBoolean(" ); @@ -1013,7 +1013,7 @@ if( exp1==null ) return parser.failure(null); if( parser.match('^') ) { - Spaces(in); + Spaces(); Expr exp2 = required(PowExpr(in)); Expr newExp = new Expr(Val.SINGLE,false); newExp.add( "LuanImpl.pow(luan," ); @@ -1034,14 +1034,14 @@ exp = VarExp(in); if( exp != null ) return parser.success(exp); - exp = VarArgs(in); + exp = VarArgs(); if( exp != null ) return parser.success(exp); return parser.failure(null); } private Expr FunctionExpr(In in) throws ParseException { - if( !Keyword("function",in) ) + if( !Keyword("function") ) return null; return RequiredFunction(in); } @@ -1049,58 +1049,57 @@ private Expr RequiredFunction(In in) throws ParseException { parser.begin(); RequiredMatch('('); - In inParens = in.parens(); - Spaces(inParens); + Spaces(); frame = new Frame(frame); Stmts stmt = new Stmts(); - List<String> names = NameList(in); + List<String> names = NameList(); if( names != null ) { Expr args = new Expr(Val.ARRAY,false); args.add( "args" ); stmt.addAll( makeLocalSetStmt(names,args) ); if( parser.match(',') ) { - Spaces(inParens); + Spaces(); if( !parser.match("...") ) throw parser.exception(); - Spaces(inParens); + Spaces(); frame.isVarArg = true; - stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args," + names.size() + ");\n" ); + stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args," + names.size() + "); " ); } } else if( parser.match("...") ) { - Spaces(inParens); + Spaces(); frame.isVarArg = true; - stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);\n" ); + stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args,0); " ); } RequiredMatch(')'); - Spaces(in); + Spaces(); Stmts block = RequiredBlock(); stmt.addAll( block ); stmt.hasReturn = block.hasReturn; + Expr fnDef = newFnExpStr(stmt); RequiredKeyword("end",in); - Expr fnDef = newFnExpStr(stmt); frame = frame.parent; return parser.success(fnDef); } - private Expr VarArgs(In in) throws ParseException { + private Expr VarArgs() throws ParseException { parser.begin(); if( !frame.isVarArg || !parser.match("...") ) return parser.failure(null); - Spaces(in); + Spaces(); Expr exp = new Expr(Val.ARRAY,false); exp.add("varArgs"); return parser.success(exp); } - private Expr TableExpr(In in) throws ParseException { + private Expr TableExpr() throws ParseException { parser.begin(); if( !parser.match('{') ) return parser.failure(null); - Spaces(In.NOTHING); + Spaces(); List<Expr> builder = new ArrayList<Expr>(); Field(builder); while( FieldSep() ) { - Spaces(In.NOTHING); + Spaces(); Field(builder); } Expr exp = TemplateExpressions(In.NOTHING); @@ -1108,7 +1107,7 @@ builder.add(exp); if( !parser.match('}') ) throw parser.exception("Expected table element or '}'"); - Spaces(in); + Spaces(); exp = new Expr(Val.SINGLE,false); exp.add( "LuanImpl.table(" ); exp.addAll( expString(builder).array() ); @@ -1124,9 +1123,9 @@ parser.begin(); Expr exp = SubExpr(In.NOTHING); if( exp==null ) - exp = NameExpr(In.NOTHING); + exp = NameExpr(); if( exp!=null && parser.match('=') ) { - Spaces(In.NOTHING); + Spaces(); Expr val = RequiredExpr(In.NOTHING).single(); Expr newExp = new Expr(Val.SINGLE,false); newExp.add( "new TableField(" ); @@ -1165,21 +1164,20 @@ private Var VarStart(In in) throws ParseException { if( parser.match('(') ) { - In inParens = in.parens(); - Spaces(inParens); - Expr exp = RequiredExpr(inParens).single(); + Spaces(); + Expr exp = RequiredExpr(in).single(); RequiredMatch(')'); - Spaces(in); + Spaces(); return exprVar(exp); } - String name = Name(in); + String name = Name(); if( name != null ) return nameVar(name); Expr exp; - exp = TableExpr(in); + exp = TableExpr(); if( exp != null ) return exprVar(exp); - exp = Literal(in); + exp = Literal(); if( exp != null ) return exprVar(exp); return null; @@ -1191,8 +1189,8 @@ if( exp2 != null ) return parser.success(indexVar(exp1,exp2)); if( parser.match('.') ) { - Spaces(in); - exp2 = NameExpr(in); + Spaces(); + exp2 = NameExpr(); if( exp2!=null ) return parser.success(indexVar(exp1,exp2)); return parser.failure(null); @@ -1242,7 +1240,7 @@ stmt.addAll( sym.exp() ); stmt.add( " = " ); stmt.addAll( val.single() ); - stmt.add( ";\n" ); + stmt.add( "; " ); return stmt; } Expr envExpr = env(); @@ -1289,7 +1287,7 @@ stmt.addAll( key.single() ); stmt.add( "," ); stmt.addAll( val.single() ); - stmt.add( ");\n" ); + stmt.add( "); " ); return stmt; } }; @@ -1305,31 +1303,23 @@ private boolean args(In in,List<Expr> builder) throws ParseException { parser.begin(); if( parser.match('(') ) { - In inParens = in.parens(); - Spaces(inParens); - ExpList(inParens,builder); // optional + Spaces(); + ExpList(in,builder); // optional if( !parser.match(')') ) throw parser.exception("Expression or ')' expected"); - Spaces(in); + Spaces(); return parser.success(); } - Expr exp = TableExpr(in); + Expr exp = TableExpr(); if( exp != null ) { builder.add(exp); return parser.success(); } - String s = StringLiteral(in); + String s = StringLiteral(); if( s != null ) { builder.add( constExpStr(s) ); return parser.success(); } -/* - Expressions exps = TemplateExpressions(in); - if( exps != null ) { - builder.add(exps); - return parser.success(); - } -*/ return parser.failure(); } @@ -1350,7 +1340,7 @@ return parser.failure(); builder.add(exp); while( parser.match(',') ) { - Spaces(in); + Spaces(); exp = TemplateExpressions(in); if( exp != null ) { builder.add(exp); @@ -1365,30 +1355,30 @@ parser.begin(); if( !parser.match('[') || parser.test("[") || parser.test("=") ) return parser.failure(null); - Spaces(In.NOTHING); + Spaces(); Expr exp = RequiredExpr(In.NOTHING).single(); RequiredMatch(']'); - Spaces(in); + Spaces(); return parser.success(exp); } - private Expr NameExpr(In in) throws ParseException { + private Expr NameExpr() throws ParseException { parser.begin(); - String name = Name(in); + String name = Name(); if( name==null ) return parser.failure(null); return parser.success(constExpStr(name)); } - private String RequiredName(In in) throws ParseException { + private String RequiredName() throws ParseException { parser.begin(); - String name = Name(in); + String name = Name(); if( name==null ) throw parser.exception("Name expected"); return parser.success(name); } - private String Name(In in) throws ParseException { + private String Name() throws ParseException { int start = parser.begin(); if( !NameFirstChar() ) return parser.failure(null); @@ -1396,7 +1386,7 @@ String match = parser.textFrom(start); if( keywords.contains(match) ) return parser.failure(null); - Spaces(in); + Spaces(); return parser.success(match); } @@ -1419,15 +1409,15 @@ } private void RequiredKeyword(String keyword,In in) throws ParseException { - if( !Keyword(keyword,in) ) + if( !Keyword(keyword) ) throw parser.exception("'"+keyword+"' expected"); } - private boolean Keyword(String keyword,In in) throws ParseException { + private boolean Keyword(String keyword) throws ParseException { parser.begin(); if( !parser.match(keyword) || NameChar() ) return parser.failure(); - Spaces(in); + Spaces(); return parser.success(); } @@ -1456,20 +1446,20 @@ "while" )); - private Expr Literal(In in) throws ParseException { + private Expr Literal() throws ParseException { parser.begin(); - if( NilLiteral(in) ) { + if( NilLiteral() ) { Expr exp = new Expr(Val.SINGLE,false); exp.add( "null" ); return parser.success(exp); } - Boolean b = BooleanLiteral(in); + Boolean b = BooleanLiteral(); if( b != null ) { Expr exp = new Expr(Val.SINGLE,false); exp.add( b.toString() ); return parser.success(exp); } - Number n = NumberLiteral(in); + Number n = NumberLiteral(); if( n != null ) { String s = n.toString(); if( n instanceof Long ) @@ -1478,13 +1468,18 @@ exp.add( s ); return parser.success(exp); } - String s = StringLiteral(in); + String s = StringLiteral(); if( s != null ) return parser.success(constExpStr(s)); return parser.failure(null); } private Expr constExpStr(String s) { + int n = 0; + int from = 0; + while( (from = s.indexOf('\n',from) + 1) != 0 ) { + n++; + } s = s .replace("\\","\\\\") .replace("\"","\\\"") @@ -1493,24 +1488,27 @@ .replace("\t","\\t") .replace("\b","\\b") ; + s = "\"" + s + "\""; + while( n-- > 0 ) + s += "\n"; Expr exp = new Expr(Val.SINGLE,false); - exp.add( "\""+s+"\"" ); + exp.add( s ); return exp; } - private boolean NilLiteral(In in) throws ParseException { - return Keyword("nil",in); + private boolean NilLiteral() throws ParseException { + return Keyword("nil"); } - private Boolean BooleanLiteral(In in) throws ParseException { - if( Keyword("true",in) ) + private Boolean BooleanLiteral() throws ParseException { + if( Keyword("true") ) return true; - if( Keyword("false",in) ) + if( Keyword("false") ) return false; return null; } - private Number NumberLiteral(In in) throws ParseException { + private Number NumberLiteral() throws ParseException { parser.begin(); Number n; if( parser.matchIgnoreCase("0x") ) { @@ -1520,7 +1518,7 @@ } if( n==null || NameChar() ) return parser.failure(null); - Spaces(in); + Spaces(); return parser.success(n); } @@ -1620,14 +1618,14 @@ return Digit() || parser.anyOf("abcdefABCDEF"); } - private String StringLiteral(In in) throws ParseException { + private String StringLiteral() throws ParseException { String s; if( (s=QuotedString('"'))==null && (s=QuotedString('\''))==null && (s=LongString())==null ) return null; - Spaces(in); + Spaces(); return s; } @@ -1689,13 +1687,15 @@ if( Digit() ) Digit(); // optional return parser.success((char)Integer.parseInt(parser.textFrom(start))); } - if( EndOfLine() ) + if( EndOfLine() ) { + parser.sb().setLength(parser.sb().length()-1); return parser.success('\n'); + } return parser.failure(null); } - private void Spaces(In in) throws ParseException { - while( parser.anyOf(" \t") || Comment() || ContinueOnNextLine() || in.parens && EndOfLine() ); + private void Spaces() throws ParseException { + while( parser.anyOf(" \t") || Comment() || ContinueOnNextLine() ); } private boolean ContinueOnNextLine() { @@ -1723,9 +1723,10 @@ if( !parser.match('[') ) return parser.failure(); while( !LongBracketsEnd(nEquals) ) { - if( !parser.anyChar() ) + if( !(EndOfLine() || parser.anyChar()) ) throw parser.exception("Unclosed comment"); } + parser.upSb(); return parser.success(); } @@ -1744,7 +1745,25 @@ - private static class ParseList extends ArrayList { + private class ParseList extends ArrayList { + + void addNewLines() { + if( parser.sb().length() > 0 ) { + add( parser.sb().toString() ); + parser.sb().setLength(0); +/* +if( parser.sourceName.equals("stdin") ) { + StringWriter sw = new StringWriter(); + new Throwable().printStackTrace(new PrintWriter(sw,true)); +// add(sw.toString()); +} +*/ + } + } + + ParseList() { + addNewLines(); + } @Override public boolean add(Object obj) { if( obj instanceof List ) throw new RuntimeException(); @@ -1770,7 +1789,7 @@ private enum Val { SINGLE, ARRAY } - private static class Expr extends ParseList { + private class Expr extends ParseList { final Val valType; final boolean isStmt; @@ -1837,7 +1856,7 @@ } } - private static class Stmts extends ParseList { + private class Stmts extends ParseList { boolean hasReturn = false; } @@ -1860,50 +1879,49 @@ private String toFnString(Stmts stmts,List<UpSym> upValueSymbols,String className) { if( !stmts.hasReturn ) - stmts.add( "return LuanFunction.NOTHING;\n" ); + stmts.add( "\nreturn LuanFunction.NOTHING;" ); return "" - +"package luan.impl;\n" - +"import luan.Luan;\n" - +"import luan.LuanFunction;\n" - +"import luan.LuanState;\n" - +"import luan.LuanJava;\n" - +"import luan.LuanException;\n" - +"import luan.modules.PackageLuan;\n" - +"\n" - +"public class " + className +" extends Closure {\n" - +" public "+className+"(LuanJava java) throws LuanException {\n" - +" super("+upValueSymbols.size()+",java);\n" - + init(upValueSymbols) - +" }\n" - +"\n" - +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" - +" Object t;\n" - +" Object[] a;\n" - +" " + stmts - +" }\n" + +"package luan.impl; " + +"import luan.Luan; " + +"import luan.LuanFunction; " + +"import luan.LuanState; " + +"import luan.LuanJava; " + +"import luan.LuanException; " + +"import luan.modules.PackageLuan; " + + +"public class " + className +" extends Closure { " + +"public "+className+"(LuanJava java) throws LuanException { " + +"super("+upValueSymbols.size()+",java); " + + init(upValueSymbols) + +"} " + + +"@Override public Object doCall(LuanState luan,Object[] args) throws LuanException { " + +"Object t; " + +"Object[] a; " + + stmts + +"\n} " +"}\n" ; } - private static Expr toFnExpStr(Stmts stmt,List<UpSym> upValueSymbols) { + private Expr toFnExpStr(Stmts stmt,List<UpSym> upValueSymbols) { + stmt.addNewLines(); if( !stmt.hasReturn ) - stmt.add( "return LuanFunction.NOTHING;\n" ); + stmt.add( "return LuanFunction.NOTHING; " ); Expr exp = new Expr(Val.SINGLE,false); exp.add( "" - +"\n" - +"new Closure("+upValueSymbols.size()+",java) {\n" - +"{\n" - + init(upValueSymbols) - +"}\n" - +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" - +" Object t;\n" - +" Object[] a;\n" - +" " + +"new Closure("+upValueSymbols.size()+",java) { " + +"{ " + + init(upValueSymbols) + +"} " + +"@Override public Object doCall(LuanState luan,Object[] args) throws LuanException { " + +"Object t; " + +"Object[] a; " ); exp.addAll( stmt ); exp.add( "" - +" }\n" - +"}\n" + +"} " + +"} " ); return exp; }
--- a/core/src/luan/impl/Parser.java Wed Apr 13 16:24:48 2016 -0600 +++ b/core/src/luan/impl/Parser.java Thu Apr 14 15:19:25 2016 -0600 @@ -2,11 +2,17 @@ final class Parser { + + private static class Frame { + int i; + StringBuilder sb; + } + // private final LuanSource src; public final String sourceName; public final String text; private final int len; - private int[] stack = new int[256]; + private Frame[] stack = new Frame[256]; private int frame = 0; private int iHigh; @@ -15,31 +21,37 @@ this.sourceName = sourceName; this.text = text; this.len = text.length(); + stack[0] = new Frame(); } private int i() { - return stack[frame]; + return stack[frame].i; } private void i(int i) { - stack[frame] += i; - if( iHigh < stack[frame] ) - iHigh = stack[frame]; + Frame f = stack[frame]; + f.i += i; + if( iHigh < f.i ) + iHigh = f.i; } public int begin() { frame++; if( frame == stack.length ) { - int[] a = new int[2*frame]; + Frame[] a = new Frame[2*frame]; System.arraycopy(stack,0,a,0,frame); stack = a; } - stack[frame] = stack[frame-1]; + Frame f = new Frame(); + f.i = stack[frame-1].i; + stack[frame] = f; return i(); } public void rollback() { - stack[frame] = stack[frame-1]; + Frame f = stack[frame]; + f.i = stack[frame-1].i; + f.sb = null; } public <T> T success(T t) { @@ -48,8 +60,10 @@ } public boolean success() { + Frame f = stack[frame]; + if( f.sb != null && f.sb.length() > 0 ) throw new RuntimeException("sb not emtpy"); frame--; - stack[frame] = stack[frame+1]; + stack[frame].i = f.i; return true; } @@ -71,6 +85,26 @@ return exception("Invalid input"); } + public StringBuilder sb() { + Frame f = stack[frame]; + if( f.sb == null ) + f.sb = new StringBuilder(); + return f.sb; + } + + public void upSb() { + Frame f = stack[frame]; + StringBuilder sb = f.sb; + if( sb != null && sb.length() > 0 ) { + Frame fUp = stack[frame-1]; + if( fUp.sb == null ) + fUp.sb = sb; + else + fUp.sb.append(sb.toString()); + f.sb = null; + } + } + public int currentIndex() { return i(); }