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 }