Mercurial Hosting > luan
changeset 687:fc08c3b42010
add theme_to_luan
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 18 Apr 2016 01:08:35 -0600 |
parents | 33f1b4ad2c9d |
children | f99f51bc5bea |
files | core/src/luan/impl/LuanParser.java core/src/luan/impl/ThemeParser.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/JavaLuan.java core/src/luan/modules/Luan.luan core/src/luan/modules/Parsers.luan core/src/luan/modules/parsers/Theme.java |
diffstat | 7 files changed, 193 insertions(+), 439 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/impl/LuanParser.java Sun Apr 17 16:39:28 2016 -0600 +++ b/core/src/luan/impl/LuanParser.java Mon Apr 18 01:08:35 2016 -0600 @@ -179,14 +179,11 @@ } } -// final LuanSource source; private Frame frame; private final Parser parser; private final Stmts top; - private boolean hasTemplateWrite = false; LuanParser(String sourceName,String sourceText) { -// this.source = source; this.frame = new Frame(); this.parser = new Parser(sourceName,sourceText); this.top = new Stmts(); @@ -194,11 +191,9 @@ void addVar(String name) { UpSym upSym = frame.addUpSym( "-ADDED-" ,"new Pointer()"); - if( name != null ) { - LocalSym sym = frame.addLocalSym( name ); - sym.isPointer = true; - top.add( "final Pointer " + sym.javaName + " = upValues[" + upSym.i + "]; " ); - } + LocalSym sym = frame.addLocalSym( name ); + sym.isPointer = true; + top.add( "final Pointer " + sym.javaName + " = upValues[" + upSym.i + "]; " ); } private int symbolsSize() { @@ -377,12 +372,8 @@ Expr exprs = TemplateExpressions(In.NOTHING); if( exprs == null ) return null; - if( !hasTemplateWrite ) { - top.add(0,"final LuanFunction template_write = Luan.checkFunction(luan.index(PackageLuan.require(luan,\"luan:Io\"),\"template_write\")); "); - hasTemplateWrite = true; - } Stmts stmt = new Stmts(); - stmt.add( "template_write.call(luan," ); + stmt.add( "Luan.checkFunction(luan.index(PackageLuan.require(luan,\"luan:Io\"),\"template_write\")).call(luan," ); stmt.addAll( exprs.array() ); stmt.add( "); " ); return stmt; @@ -1275,7 +1266,8 @@ Expr envExpr = env(); if( envExpr != null ) return indexVar( envExpr, constExpStr(name) ).set(val); - throw new RuntimeException(); + parser.failure(null); + throw parser.exception("name '"+name+"' not defined"); } }; }
--- a/core/src/luan/impl/ThemeParser.java Sun Apr 17 16:39:28 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,414 +0,0 @@ -package luan.impl; - -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; -import luan.Luan; -import luan.LuanTable; -import luan.LuanState; -import luan.LuanFunction; -import luan.LuanException; -import luan.modules.PackageLuan; - - -public final class ThemeParser { - - public static LuanFunction compile(LuanState luan,String sourceName,String sourceText) throws LuanException { -/* - try { - FnDef fnDef = new ThemeParser(sourceName,sourceText).parse(); - final LuanStateImpl luanImpl = (LuanStateImpl)luan; - return new Closure(luanImpl,fnDef); - } catch(ParseException e) { -//e.printStackTrace(); - throw new LuanException( e.getFancyMessage() ); - } -*/ - return null; - } -/* - private static final class Frame { - final Frame parent; - final List<String> symbols = new ArrayList<String>(); - int stackSize = 0; - final boolean isVarArg; - final List<String> upValueSymbols = new ArrayList<String>(); - final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>(); - - Frame() { - this.parent = null; - isVarArg = true; - } - - Frame(Frame parent) { - this.parent = parent; - isVarArg = false; - if( upValueIndex(MOD) != 0 ) - throw new RuntimeException(); - } - - int stackIndex(String name) { - int i = symbols.size(); - while( --i >= 0 ) { - if( symbols.get(i).equals(name) ) - return i; - } - return -1; - } - - int upValueIndex(String name) { - int i = upValueSymbols.size(); - while( --i >= 0 ) { - if( upValueSymbols.get(i).equals(name) ) - return i; - } - if( parent==null ) - return -1; - i = parent.stackIndex(name); - if( i != -1 ) { - upValueGetters.add(new UpValue.StackGetter(i)); - } else { - i = parent.upValueIndex(name); - if( i == -1 ) - return -1; - upValueGetters.add(new UpValue.NestedGetter(i)); - } - upValueSymbols.add(name); - return upValueSymbols.size() - 1; - } - - void addUpValueGetter(String name,UpValue.Getter upValueGetter) { - upValueSymbols.add(name); - upValueGetters.add(upValueGetter); - } - } - - private static final String IO = "-IO-"; - private static final String MOD = "-MOD-"; - private static final String ENV = "-ENV-"; - private static final String INDENT = "-INDENT-"; - private static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0]; - -// private final LuanSource source; - private final Parser parser; - private Frame frame = new Frame(); - - private ThemeParser(String sourceName,String sourceText) { -// this.source = source; - this.parser = new Parser(sourceName,sourceText); - } - - private int symbolsSize() { - return frame.symbols.size(); - } - - private void addSymbol(String name) { - frame.symbols.add(name); - if( frame.stackSize < symbolsSize() ) - frame.stackSize = symbolsSize(); - } - - private Class newFnDef(Stmt stmt) { -// return new FnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); - return null; - } - - private int stackIndex(String name) { - return frame.stackIndex(name); - } - - private void popSymbols(int n) { - List<String> symbols = frame.symbols; - while( n-- > 0 ) { - symbols.remove(symbols.size()-1); - } - } - - private int upValueIndex(String name) { - return frame.upValueIndex(name); - } - - private ParseException exception(String msg) { - parser.failure(); - return parser.exception(msg); - } - - private Expr env() { - return new GetLocalVar(stackIndex(ENV)); - } - - private Class parse() throws ParseException { - List<Stmt> stmts = new ArrayList<Stmt>(); - int stackStart = symbolsSize(); - { - addSymbol(IO); - FnCall requireCall = new FnCall( new ConstExpr(PackageLuan.requireFn), new ConstExpr("luan:Io") ); - SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(IO)), new ExpressionsExpr(requireCall) ); - stmts.add(setStmt); - } - { - addSymbol(MOD); - TableExpr.Field indent = new TableExpr.Field(new ConstExpr(INDENT),new ConstExpr("")); - TableExpr tableExpr = new TableExpr( new TableExpr.Field[]{indent}, ExpList.emptyExpList ); - SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(MOD)), tableExpr ); - stmts.add(setStmt); - } - while( !parser.endOfInput() ) { - Stmt def = parseDef(); - if( def != null ) { - stmts.add(def); - } else { - parser.anyChar(); - } - } - stmts.add( new ReturnStmt(new GetLocalVar(stackIndex(MOD))) ); - Stmt block = new Block( stmts.toArray(new Stmt[0]), stackStart, symbolsSize() ); - Class fnDef = newFnDef(block); - return fnDef; - } - - private Stmt parseDef() throws ParseException { - parser.begin(); - if( !parser.match("{define:") ) - return parser.failure(null); - String name = parseName(); - if( name==null ) - throw parser.exception("invalid block name"); - if( !parser.match('}') ) - throw parser.exception("unclosed define tag"); - String spaces = ""; - boolean indent = BlankLine(); - if( indent ) { - int startSpaces = parser.currentIndex(); - InlineSpaces(); - spaces = parser.textFrom(startSpaces); - } - Expr table = new GetLocalVar(stackIndex(MOD)); - Settable fnName = new SetTableEntry(table,new ConstExpr(name)); - frame = new Frame(frame); - addSymbol(ENV); - Stmt block = parseBody("define:"+name,spaces,indent); - Class fnDef = newFnDef(block); - frame = frame.parent; - Stmt rtn = new SetStmt(fnName,fnDef); - return parser.success(rtn); - } - - private Stmt parseBody(String tagName,final String spaces,boolean afterIndent) throws ParseException { - List<Stmt> stmts = new ArrayList<Stmt>(); - int stackStart = symbolsSize(); - int start = parser.currentIndex(); - { - addSymbol(INDENT); - final Expr env = env(); - Expr exp = new ExprImpl() { - @Override public Object eval(LuanStateImpl luan) throws LuanException { - Object obj = env.eval(luan); - if( !(obj instanceof LuanTable) ) - throw new LuanException("bad argument (table expected, got "+Luan.type(obj)+")"); - LuanTable tbl = (LuanTable)obj; - String indent = (String)tbl.get(luan,INDENT); - if( indent==null ) throw new NullPointerException(); - return indent; - } - }; -// Expr exp = new IndexExpr( se(start,"indent"), env(), new ConstExpr(null,INDENT) ); - SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(INDENT)), exp ); - stmts.add(setStmt); - } - int end = start; - while( !matchEndTag(tagName) ) { - if( parser.endOfInput() ) - throw exception("unclosed block"); - Stmt block = parseBlock(spaces,afterIndent); - if( block != null ) { - addText(start,end,stmts,false); - start = parser.currentIndex(); - stmts.add(block); - afterIndent = false; - continue; - } - { - String extraSpaces = null; - if( afterIndent ) { - int startSpaces = parser.currentIndex(); - InlineSpaces(); - extraSpaces = parser.textFrom(startSpaces); - end = parser.currentIndex(); - } - Stmt simpleTag = parseSimpleTag(extraSpaces); - if( simpleTag != null ) { - addText(start,end,stmts,false); - start = parser.currentIndex(); - stmts.add(simpleTag); - afterIndent = false; - continue; - } - if( extraSpaces!=null && extraSpaces.length() > 0 ) - continue; - } - if( EndOfLine() ) { - end = parser.currentIndex(); - afterIndent = false; - if( parser.match(spaces) ) { - addText(start,end,stmts,true); - start = parser.currentIndex(); - afterIndent = true; - } - continue; - } - parser.anyChar(); - end = parser.currentIndex(); - afterIndent = false; - } - addText(start,end,stmts,false); - Stmt block = new Block( stmts.toArray(new Stmt[0]), stackStart, symbolsSize() ); - popSymbols(1); - return block; - } - - private boolean matchEndTag(String tagName) { - parser.begin(); -/* - if( tagName.startsWith("define:") ) - EndOfLine(); -* / - if( EndOfLine() ) - InlineSpaces(); - return parser.match("{/") && parser.match(tagName) && parser.match('}') ? parser.success() : parser.failure(); - } - - private void addText(int start,int end,List<Stmt> stmts,boolean indent) { - List<Expressions> args = new ArrayList<Expressions>(); - if( start < end ) { - String text = parser.text.substring(start,end); - args.add( new ConstExpr(text) ); - } - if( indent ) { - args.add( new GetLocalVar(stackIndex(INDENT)) ); - } - if( !args.isEmpty() ) { - Expr io = new GetUpVar(upValueIndex(IO)); - Expr stdoutExp = new IndexExpr( io, new ConstExpr("stdout") ); - Expr writeExp = new IndexExpr( stdoutExp, new ConstExpr("write") ); - FnCall writeCall = new FnCall( writeExp, ExpList.build(args) ); - stmts.add( new ExpressionsStmt(writeCall) ); - } - } - - private Stmt parseBlock(String spaces,boolean afterIndent) throws ParseException { - parser.begin(); - String tagSpaces = null; - if( afterIndent ) { - tagSpaces = spaces; - } else if( EndOfLine() ) { - int startSpaces = parser.currentIndex(); - InlineSpaces(); - tagSpaces = parser.textFrom(startSpaces); - } - if( !parser.match("{block:") ) - return parser.failure(null); - String name = parseName(); - if( name==null ) - throw exception("invalid block name"); - if( !parser.match('}') ) - return null; - if( tagSpaces != null ) { - parser.begin(); - InlineSpaces(); - if( EndOfLine() ) { - int startSpaces = parser.currentIndex(); - InlineSpaces(); - String line1Spaces = parser.textFrom(startSpaces); - if( line1Spaces.startsWith(tagSpaces) ) { - String newSpaces = spaces + line1Spaces.substring(tagSpaces.length()); - if( line1Spaces.startsWith(newSpaces) ) - spaces = newSpaces; - } - } - parser.failure(); // rollback - } - frame = new Frame(frame); - addSymbol(ENV); - Stmt block = parseBody("block:"+name,spaces,false); - Class fnDef = newFnDef(block); - frame = frame.parent; -// String rtn = "<% env." + tag.name + "(" + (tag.attrs.isEmpty() ? "nil" : table(tag.attrs)) + ",env,function(env) %>" + block + "<% end) %>"; - Expr env = env(); - Expr fn = new IndexExpr( env, new ConstExpr(name) ); - List<Expressions> args = new ArrayList<Expressions>(); - args.add( env ); - args.add( fnDef ); - FnCall fnCall = new FnCall( fn, ExpList.build(args) ); - Stmt rtn = new ExpressionsStmt(fnCall); - return parser.success(rtn); - } - - private Stmt parseSimpleTag(String spaces) throws ParseException { - parser.begin(); - if( !parser.match('{') ) - return parser.failure(null); - String name = parseName(); - if( name==null ) - return parser.failure(null); - if( !parser.match('}') ) - return parser.failure(null); -// rtn = "<% env." + name + (attrs.isEmpty() ? "()" : table(attrs)) + " %>"; - Expr env = env(); - Expr fn = new IndexExpr( env, new ConstExpr(name) ); - if( spaces!=null && spaces.length() > 0 ) { - final Expr oldEnv = env; - final Expr oldIndentExpr = new GetLocalVar(stackIndex(INDENT)); - final String addSpaces = spaces; - env = new ExprImpl() { - @Override public Object eval(LuanStateImpl luan) throws LuanException { - LuanTable mt = new LuanTable(); - mt.rawPut("__index",oldEnv.eval(luan)); - LuanTable tbl = new LuanTable(); - tbl.setMetatable(mt); - String oldIndent = (String)oldIndentExpr.eval(luan); - String newIndent = oldIndent + addSpaces; - tbl.rawPut(INDENT,newIndent); - return tbl; - } - }; - } - FnCall fnCall = new FnCall( fn, env ); - Stmt rtn = new ExpressionsStmt(fnCall); - return parser.success(rtn); - } - - private void InlineSpaces() { - while( parser.anyOf(" \t") ); - } - - private boolean BlankLine() { - parser.begin(); - while( parser.anyOf(" \t") ); - return EndOfLine() ? parser.success() : parser.failure(); - } - - private boolean EndOfLine() { - return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); - } - - private String parseName() throws ParseException { - int start = parser.begin(); - if( parser.match('/') ) - throw exception("bad closing tag"); - if( parser.match("define:") ) - throw exception("unexpected definition"); - if( !NameChar() ) - return parser.failure(null); - while( NameChar() ); - String match = parser.textFrom(start); - return parser.success(match); - } - - private boolean NameChar() { - return parser.inCharRange('a', 'z') || parser.inCharRange('A', 'Z') - || parser.inCharRange('0', '9') || parser.anyOf("-_."); - } -*/ -}
--- a/core/src/luan/modules/BasicLuan.java Sun Apr 17 16:39:28 2016 -0600 +++ b/core/src/luan/modules/BasicLuan.java Mon Apr 18 01:08:35 2016 -0600 @@ -16,7 +16,6 @@ import luan.LuanMethod; import luan.LuanMeta; import luan.impl.LuanCompiler; -import luan.impl.ThemeParser; public final class BasicLuan { @@ -33,14 +32,6 @@ return LuanCompiler.compile(sourceName,text,env,allowExpr); } - public static LuanFunction load_theme(LuanState luan,String text,String sourceName) - throws LuanException - { - if( sourceName==null ) - sourceName = "THEME"; - return ThemeParser.compile(luan,sourceName,text); - } - public static LuanFunction load_file(LuanState luan,String fileName,Boolean addExtension) throws LuanException { if( fileName == null ) fileName = "stdin:";
--- a/core/src/luan/modules/JavaLuan.java Sun Apr 17 16:39:28 2016 -0600 +++ b/core/src/luan/modules/JavaLuan.java Mon Apr 18 01:08:35 2016 -0600 @@ -109,7 +109,7 @@ //System.out.println("invalid member '"+key+"' for java object: "+obj); if( canReturnFail ) return FAIL; - throw new LuanException( "invalid index for java "+cls ); + throw new LuanException( "invalid index '"+key+"' for java "+cls ); } private static Object member(Object obj,List<Member> members) throws LuanException {
--- a/core/src/luan/modules/Luan.luan Sun Apr 17 16:39:28 2016 -0600 +++ b/core/src/luan/modules/Luan.luan Mon Apr 18 01:08:35 2016 -0600 @@ -15,7 +15,6 @@ M.ipairs = BasicLuan.ipairs M.load = BasicLuan.load M.load_file = BasicLuan.load_file -M.load_theme = BasicLuan.load_theme M.new_error = BasicLuan.new_error M.pairs = BasicLuan.pairs M.pcall = BasicLuan.pcall
--- a/core/src/luan/modules/Parsers.luan Sun Apr 17 16:39:28 2016 -0600 +++ b/core/src/luan/modules/Parsers.luan Mon Apr 18 01:08:35 2016 -0600 @@ -1,11 +1,13 @@ java() local BBCode = require "java:luan.modules.parsers.BBCode" local Csv = require "java:luan.modules.parsers.Csv" +local Theme = require "java:luan.modules.parsers.Theme" local M = {} M.bbcode_to_html = BBCode.toHtml M.bbcode_to_text = BBCode.toText M.csv_to_list = Csv.toList +M.theme_to_luan = Theme.toLuan return M
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/src/luan/modules/parsers/Theme.java Mon Apr 18 01:08:35 2016 -0600 @@ -0,0 +1,184 @@ +package luan.modules.parsers; + +import luan.LuanException; + + +public final class Theme { + + public static String toLuan(String source) throws LuanException { + try { + return new Theme(source).parse(); + } catch(ParseException e) { + throw new LuanException(e.getMessage()); + } + } + + private final Parser parser; + + private Theme(String source) { + this.parser = new Parser(source); + } + + private ParseException exception(String msg) { +// parser.failure(); + return new ParseException(parser,msg); + } + + private String parse() throws ParseException { + StringBuilder stmts = new StringBuilder(); + stmts.append( "local M = {}; " ); + while( !parser.endOfInput() ) { + String def = parseDef(); + if( def != null ) { + stmts.append(def); + } else { +// parser.anyChar(); + stmts.append(parsePadding()); + } + } + stmts.append( "\n\nreturn M\n" ); + return stmts.toString(); + } + + private String parsePadding() throws ParseException { + int start = parser.currentIndex(); + if( parser.match("--") ) { + while( parser.noneOf("\r\n") ); + } else if( !parser.anyOf(" \t\r\n") ) { + throw exception("unexpected text"); + } + return parser.textFrom(start); + } + + private String parseDef() throws ParseException { + int start = parser.begin(); + if( !parser.match("{define:") ) + return parser.failure(null); + String name = parseName(); + if( name==null ) + throw exception("invalid block name"); + if( !parser.match('}') ) + throw exception("unclosed define tag"); + String block = parseBody("define:"+name); + String rtn = "function M." + name + "(env) " + block + "end; "; + return parser.success(rtn); + } + + private String parseBody(String tagName) throws ParseException { + StringBuilder stmts = new StringBuilder(); + int start = parser.currentIndex(); + stmts.append( "%>" ); + int end = start; + while( !matchEndTag(tagName) ) { + if( parser.endOfInput() ) { + parser.failure(); + throw exception("unclosed block"); + } + String block = parseBlock(); + if( block != null ) { + addText(start,end,stmts); + start = parser.currentIndex(); + stmts.append(block); + continue; + } + String simpleTag = parseSimpleTag(); + if( simpleTag != null ) { + addText(start,end,stmts); + start = parser.currentIndex(); + stmts.append(simpleTag); + continue; + } + parser.anyChar(); + end = parser.currentIndex(); + } + addText(start,end,stmts); + stmts.append( "<% "); + return stmts.toString(); + } + + private boolean matchEndTag(String tagName) { + parser.begin(); +/* + if( tagName.startsWith("define:") ) + EndOfLine(); +*/ + return parser.match("{/") && parser.match(tagName) && parser.match('}') ? parser.success() : parser.failure(); + } + + private void addText(int start,int end,StringBuilder stmts) { + if( start < end ) { + stmts.append( parser.text.substring(start,end) ); + } + } + + private String parseBlock() throws ParseException { + int start = parser.begin(); + if( !parser.match("{block:") ) + return parser.failure(null); + String name = parseName(); + if( name==null ) { + parser.failure(); + throw exception("invalid block name"); + } + if( !parser.match('}') ) + return parser.failure(null); + String block = parseBody("block:"+name); + String rtn = "<% env."+ name + "( env, function(env) " + block + "end) %>"; +// String rtn = "<% env." + tag.name + "(" + (tag.attrs.isEmpty() ? "nil" : table(tag.attrs)) + ",env,function(env) %>" + block + "<% end) %>"; + return parser.success(rtn); + } + + private String parseSimpleTag() throws ParseException { + int start = parser.begin(); + if( !parser.match('{') ) + return parser.failure(null); + String name = parseName(); + if( name==null ) + return parser.failure(null); + if( !parser.match('}') ) + return parser.failure(null); +// rtn = "<% env." + name + (attrs.isEmpty() ? "()" : table(attrs)) + " %>"; + String rtn = "<% env." + name + "(env) %>"; + return parser.success(rtn); + } + + private void InlineSpaces() { + while( parser.anyOf(" \t") ); + } + + private boolean BlankLine() { + parser.begin(); + while( parser.anyOf(" \t") ); + return EndOfLine() ? parser.success() : parser.failure(); + } + + private boolean EndOfLine() { + return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); + } + + private String parseName() throws ParseException { + int start = parser.begin(); + if( parser.match('/') ) { + parser.failure(); + throw exception("bad closing tag"); + } + if( parser.match("define:") ) { + parser.failure(); + throw exception("unexpected definition"); + } + if( !FirstNameChar() ) + return parser.failure(null); + while( NameChar() ); + String match = parser.textFrom(start); + return parser.success(match); + } + + private boolean FirstNameChar() { + return parser.inCharRange('a', 'z') || parser.inCharRange('A', 'Z') || parser.match('_'); + } + + private boolean NameChar() { + return FirstNameChar() || parser.inCharRange('0', '9'); + } + +}