Mercurial Hosting > luan
comparison src/luan/impl/LuanParser.java @ 1400:221eedb0f54e
fix inner class gc bug
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 13 Sep 2019 05:05:51 -0600 |
parents | f5368cd8c056 |
children | 514b7a62fe27 |
comparison
equal
deleted
inserted
replaced
1399:38a1c1b4279a | 1400:221eedb0f54e |
---|---|
87 UpSym(String name,int i,String value) { | 87 UpSym(String name,int i,String value) { |
88 this.name = name; | 88 this.name = name; |
89 this.i = i; | 89 this.i = i; |
90 this.value = value; | 90 this.value = value; |
91 } | 91 } |
92 | 92 /* |
93 String init() { | 93 String init() { |
94 return "upValues[" + i + "] = " + value + "; "; | 94 return "upValues[" + i + "] = " + value + "; "; |
95 } | 95 } |
96 | 96 */ |
97 @Override public Expr exp() { | 97 @Override public Expr exp() { |
98 Expr exp = new Expr(Val.SINGLE,false); | 98 Expr exp = new Expr(Val.SINGLE,false); |
99 exp.add( new Object() { | 99 exp.add( new Object() { |
100 @Override public String toString() { | 100 @Override public String toString() { |
101 return "upValues[" + i + "].o"; | 101 return "upValues[" + i + "].o"; |
166 return sym != null ? sym : getUpSym(name); | 166 return sym != null ? sym : getUpSym(name); |
167 } | 167 } |
168 | 168 |
169 } | 169 } |
170 | 170 |
171 private static AtomicInteger classCounter = new AtomicInteger(); | |
172 private int innerCounter = 0; | |
173 private final List<Inner> inners = new ArrayList<Inner>(); | |
174 | |
171 private Frame frame; | 175 private Frame frame; |
172 private final Parser parser; | 176 private final Parser parser; |
173 private final Stmts top; | 177 private final Stmts top; |
174 | 178 |
175 LuanParser(String sourceText,String sourceName) { | 179 LuanParser(String sourceText,String sourceName) { |
223 if( t==null ) | 227 if( t==null ) |
224 throw parser.exception(msg); | 228 throw parser.exception(msg); |
225 return t; | 229 return t; |
226 } | 230 } |
227 | 231 |
228 private Class newFnClass(Stmts stmt) { | |
229 return toFnClass( stmt, frame.upValueSymbols ); | |
230 } | |
231 | |
232 private Expr newFnExp(Stmts stmt,String name) { | 232 private Expr newFnExp(Stmts stmt,String name) { |
233 return toFnExp( stmt, frame.upValueSymbols, name ); | 233 String className = "INNER" + ++innerCounter; |
234 } | 234 Inner inner = new Inner( stmt, name, className ); |
235 /* | 235 inners.add(inner); |
236 Class Expression() throws ParseException { | 236 return inner.toInnerFnExp( frame.upValueSymbols ); |
237 Spaces(); | 237 // return toFnExp( stmt, frame.upValueSymbols, name ); |
238 parser.begin(); | 238 } |
239 Expr expr = ExprZ(); | 239 |
240 if( expr != null && parser.endOfInput() ) { | |
241 top.add( "return " ); | |
242 top.addAll( expr ); | |
243 top.add( "; " ); | |
244 top.hasReturn = true; | |
245 return parser.success(newFnClass(top)); | |
246 } | |
247 return parser.failure(null); | |
248 } | |
249 */ | |
250 Class RequiredModule() throws ParseException { | 240 Class RequiredModule() throws ParseException { |
251 GetRequiredModule(); | 241 GetRequiredModule(); |
252 return newFnClass(top); | 242 String className = "EXP" + classCounter.incrementAndGet(); |
243 String classCode = toFnString( top, frame.upValueSymbols, className, inners ); | |
244 try { | |
245 return LuanJavaCompiler.compile("luan.impl."+className,parser.sourceName,classCode); | |
246 } catch(ClassNotFoundException e) { | |
247 throw new RuntimeException(e); | |
248 } | |
253 } | 249 } |
254 | 250 |
255 String RequiredModuleSource() throws ParseException { | 251 String RequiredModuleSource() throws ParseException { |
256 GetRequiredModule(); | 252 GetRequiredModule(); |
257 return toFnString( top, frame.upValueSymbols ); | 253 String className = "EXP" + classCounter.incrementAndGet(); |
254 return toFnString( top, frame.upValueSymbols, className, inners ); | |
258 } | 255 } |
259 | 256 |
260 void GetRequiredModule() throws ParseException { | 257 void GetRequiredModule() throws ParseException { |
261 Spaces(); | 258 Spaces(); |
262 parser.begin(); | 259 parser.begin(); |
727 return stmt; | 724 return stmt; |
728 } | 725 } |
729 | 726 |
730 private Stmts ExpressionsStmt() throws ParseException { | 727 private Stmts ExpressionsStmt() throws ParseException { |
731 parser.begin(); | 728 parser.begin(); |
732 Expr exp = ExprZ(); | 729 Expr exp = Expression(); |
733 if( exp != null && exp.isStmt ) { | 730 if( exp != null && exp.isStmt ) { |
734 Stmts stmt = new Stmts(); | 731 Stmts stmt = new Stmts(); |
735 if( exp.valType==Val.SINGLE ) { | 732 if( exp.valType==Val.SINGLE ) { |
736 stmt.add( "LuanImpl.nop(" ); | 733 stmt.add( "LuanImpl.nop(" ); |
737 stmt.addAll( exp ); | 734 stmt.addAll( exp ); |
753 return parser.success( var ); | 750 return parser.success( var ); |
754 } | 751 } |
755 | 752 |
756 private Expr RequiredExpr() throws ParseException { | 753 private Expr RequiredExpr() throws ParseException { |
757 parser.begin(); | 754 parser.begin(); |
758 return parser.success(required(ExprZ(),"Bad expression")); | 755 return parser.success(required(Expression(),"Bad expression")); |
759 } | 756 } |
760 | 757 |
761 private Expr ExprZ() throws ParseException { | 758 private Expr Expression() throws ParseException { |
762 return OrExpr(); | 759 return OrExpr(); |
763 } | 760 } |
764 | 761 |
765 private Expr OrExpr() throws ParseException { | 762 private Expr OrExpr() throws ParseException { |
766 parser.begin(); | 763 parser.begin(); |
1173 newExp.addAll( val ); | 1170 newExp.addAll( val ); |
1174 newExp.add( ")" ); | 1171 newExp.add( ")" ); |
1175 return parser.success(newExp); | 1172 return parser.success(newExp); |
1176 } | 1173 } |
1177 parser.rollback(); | 1174 parser.rollback(); |
1178 Expr exprs = ExprZ(); | 1175 Expr exprs = Expression(); |
1179 if( exprs != null ) { | 1176 if( exprs != null ) { |
1180 return parser.success(exprs); | 1177 return parser.success(exprs); |
1181 } | 1178 } |
1182 return parser.failure(null); | 1179 return parser.failure(null); |
1183 } | 1180 } |
1379 return ExpList(builder) ? expString(builder) : null; | 1376 return ExpList(builder) ? expString(builder) : null; |
1380 } | 1377 } |
1381 | 1378 |
1382 private boolean ExpList(List<Expr> builder) throws ParseException { | 1379 private boolean ExpList(List<Expr> builder) throws ParseException { |
1383 parser.begin(); | 1380 parser.begin(); |
1384 Expr exp = ExprZ(); | 1381 Expr exp = Expression(); |
1385 if( exp==null ) | 1382 if( exp==null ) |
1386 return parser.failure(); | 1383 return parser.failure(); |
1387 exp.addNewLines(); | 1384 exp.addNewLines(); |
1388 builder.add(exp); | 1385 builder.add(exp); |
1389 while( parser.match(',') ) { | 1386 while( parser.match(',') ) { |
1870 return sb.toString(); | 1867 return sb.toString(); |
1871 } | 1868 } |
1872 } | 1869 } |
1873 | 1870 |
1874 | 1871 |
1875 private static AtomicInteger classCounter = new AtomicInteger(); | |
1876 | |
1877 private enum Val { SINGLE, ARRAY } | 1872 private enum Val { SINGLE, ARRAY } |
1878 | 1873 |
1879 private class Expr extends ParseList { | 1874 private class Expr extends ParseList { |
1880 final Val valType; | 1875 final Val valType; |
1881 final boolean isStmt; | 1876 final boolean isStmt; |
1954 | 1949 |
1955 private class Stmts extends ParseList { | 1950 private class Stmts extends ParseList { |
1956 boolean hasReturn = false; | 1951 boolean hasReturn = false; |
1957 } | 1952 } |
1958 | 1953 |
1959 private Class toFnClass(Stmts stmts,List<UpSym> upValueSymbols) { | 1954 private static String toFnString(Stmts stmts,List<UpSym> upValueSymbols,String className,List<Inner> inners) { |
1960 String className = "EXP" + classCounter.incrementAndGet(); | |
1961 String classCode = toFnString(stmts,upValueSymbols,className); | |
1962 try { | |
1963 //System.out.println(parser.sourceName); | |
1964 //System.out.println(classCode); | |
1965 return LuanJavaCompiler.compile("luan.impl."+className,parser.sourceName,classCode); | |
1966 } catch(ClassNotFoundException e) { | |
1967 throw new RuntimeException(e); | |
1968 } | |
1969 } | |
1970 | |
1971 private String toFnString(Stmts stmts,List<UpSym> upValueSymbols) { | |
1972 String className = "EXP" + classCounter.incrementAndGet(); | |
1973 return toFnString(stmts,upValueSymbols,className); | |
1974 } | |
1975 | |
1976 private String toFnString(Stmts stmts,List<UpSym> upValueSymbols,String className) { | |
1977 if( !stmts.hasReturn ) | 1955 if( !stmts.hasReturn ) |
1978 stmts.add( "\nreturn LuanFunction.NOTHING;" ); | 1956 stmts.add( "\nreturn LuanFunction.NOTHING;" ); |
1979 return "" | 1957 StringBuilder sb = new StringBuilder(); |
1958 sb.append( "" | |
1980 +"package luan.impl; " | 1959 +"package luan.impl; " |
1981 +"import luan.LuanClosure; " | 1960 +"import luan.LuanClosure; " |
1982 +"import luan.Luan; " | 1961 +"import luan.Luan; " |
1983 +"import luan.LuanFunction; " | 1962 +"import luan.LuanFunction; " |
1984 +"import luan.LuanException; " | 1963 +"import luan.LuanException; " |
1985 +"import luan.modules.PackageLuan; " | 1964 +"import luan.modules.PackageLuan; " |
1986 | 1965 |
1987 +"public class " + className +" extends LuanClosure { " | 1966 +"public class " + className +" extends LuanClosure { " |
1988 +"public "+className+"(Luan luan,boolean javaOk,String sourceName) throws LuanException { " | 1967 +"public "+className+"(Luan luan,boolean javaOk,String sourceName) throws LuanException { " |
1989 +"super(luan,"+upValueSymbols.size()+",javaOk,sourceName); " | 1968 +"super(luan,"+toUpValues(upValueSymbols)+",javaOk,sourceName); " |
1990 + init(upValueSymbols) | |
1991 +"} " | 1969 +"} " |
1992 | 1970 |
1993 +"@Override public Object doCall(Luan luan,Object[] args) throws LuanException { " | 1971 +"@Override public Object doCall(Luan luan,Object[] args) throws LuanException { " |
1994 +"final Pointer[] parentUpValues = upValues; " | 1972 +"final Pointer[] parentUpValues = upValues; " |
1995 +"Object t; " | 1973 +"Object t; " |
1996 +"Object[] a; " | 1974 +"Object[] a; " |
1997 + stmts | 1975 + stmts |
1998 +"\n} " | 1976 +"\n}\n" |
1977 ); | |
1978 for( Inner inner : inners ) { | |
1979 sb.append( '\n' ); | |
1980 sb.append( inner.toInnerFnString(lines(sb.toString())) + '\n' ); | |
1981 } | |
1982 sb.append( "" | |
1999 +"}\n" | 1983 +"}\n" |
2000 ; | 1984 ); |
2001 } | 1985 return sb.toString(); |
2002 | 1986 } |
1987 | |
1988 private class Inner { | |
1989 private final Stmts stmts; | |
1990 private final String name; | |
1991 private final String className; | |
1992 private final int lines; | |
1993 private final int endLine; | |
1994 | |
1995 Inner(Stmts stmts,String name,String className) { | |
1996 this.stmts = stmts; | |
1997 this.name = name; | |
1998 this.className = className; | |
1999 | |
2000 stmts.addNewLines(); | |
2001 if( !stmts.hasReturn ) | |
2002 stmts.add( "return LuanFunction.NOTHING; " ); | |
2003 this.lines = lines( stmts.toString() ); | |
2004 this.endLine = lines( parser.textFrom(0) ); | |
2005 } | |
2006 | |
2007 Expr toInnerFnExp(List<UpSym> upValueSymbols) { | |
2008 StringBuilder sb = new StringBuilder(); | |
2009 sb.append( | |
2010 "new "+className+"(luan(),"+toUpValues(upValueSymbols)+",javaOk,sourceName)" | |
2011 ); | |
2012 for( int i=0; i<lines; i++ ) { | |
2013 sb.append('\n'); | |
2014 } | |
2015 | |
2016 Expr exp = new Expr(Val.SINGLE,false); | |
2017 exp.add( sb.toString() ); | |
2018 return exp; | |
2019 } | |
2020 | |
2021 String toInnerFnString(int line) { | |
2022 int diff = line + lines - endLine; | |
2023 String name = this.name!=null ? this.name : ""; | |
2024 name += "$" + diff; | |
2025 //name += "_" + lines + "_" + endLine + "_" + line; | |
2026 StringBuilder sb = new StringBuilder(); | |
2027 sb.append( "" | |
2028 +"private static class " + className +" extends LuanClosure { " | |
2029 +className+"(Luan luan,Pointer[] upValues,boolean javaOk,String sourceName) throws LuanException { " | |
2030 +"super(luan,upValues,javaOk,sourceName); " | |
2031 +"} " | |
2032 +"@Override public Object doCall(Luan luan,Object[] args) throws LuanException { " | |
2033 +"return _" + name + "(luan,args); " | |
2034 +"} " | |
2035 +"private Object _" + name + "(Luan luan,Object[] args) throws LuanException { " | |
2036 +"final Pointer[] parentUpValues = upValues; " | |
2037 +"Object t; " | |
2038 +"Object[] a; " | |
2039 + stmts | |
2040 +"} " | |
2041 +"} " | |
2042 ); | |
2043 return sb.toString(); | |
2044 } | |
2045 } | |
2046 | |
2047 private static int lines(String s) { | |
2048 int lines = 0; | |
2049 final int n = s.length(); | |
2050 for( int i=0; i<n; i++ ) { | |
2051 if( s.charAt(i) == '\n' ) | |
2052 lines++; | |
2053 } | |
2054 return lines; | |
2055 } | |
2056 /* | |
2003 private Expr toFnExp(Stmts stmt,List<UpSym> upValueSymbols,String name) { | 2057 private Expr toFnExp(Stmts stmt,List<UpSym> upValueSymbols,String name) { |
2004 stmt.addNewLines(); | 2058 stmt.addNewLines(); |
2005 if( !stmt.hasReturn ) | 2059 if( !stmt.hasReturn ) |
2006 stmt.add( "return LuanFunction.NOTHING; " ); | 2060 stmt.add( "return LuanFunction.NOTHING; " ); |
2007 Expr exp = new Expr(Val.SINGLE,false); | 2061 Expr exp = new Expr(Val.SINGLE,false); |
2037 for( UpSym upSym : upValueSymbols ) { | 2091 for( UpSym upSym : upValueSymbols ) { |
2038 sb.append( upSym.init() ); | 2092 sb.append( upSym.init() ); |
2039 } | 2093 } |
2040 return sb.toString(); | 2094 return sb.toString(); |
2041 } | 2095 } |
2096 */ | |
2097 private static String toUpValues(List<UpSym> upValueSymbols) { | |
2098 StringBuilder sb = new StringBuilder(); | |
2099 sb.append( "new Pointer[]{ " ); | |
2100 for( UpSym upSym : upValueSymbols ) { | |
2101 sb.append( upSym.value + ", " ); | |
2102 } | |
2103 sb.append( "}" ); | |
2104 return sb.toString(); | |
2105 } | |
2042 | 2106 |
2043 } | 2107 } |