comparison core/src/luan/impl/LuanParser.java @ 195:24ede40ee0aa

make MetatableGetter DeepCloneable, scoped, and secure git-svn-id: https://luan-java.googlecode.com/svn/trunk@196 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Thu, 03 Jul 2014 08:19:48 +0000
parents 66ed8886abc0
children 9fb218211763
comparison
equal deleted inserted replaced
194:08df375e2e5f 195:24ede40ee0aa
270 int start = parser.currentIndex(); 270 int start = parser.currentIndex();
271 Expressions exp = TemplateExpressions(In.NOTHING); 271 Expressions exp = TemplateExpressions(In.NOTHING);
272 if( exp == null ) 272 if( exp == null )
273 return null; 273 return null;
274 Expr fnExp = (Expr)nameVar(start,"Io").expr(); 274 Expr fnExp = (Expr)nameVar(start,"Io").expr();
275 fnExp = new IndexExpr( se(start,"stdout"), fnExp, new ConstExpr("stdout") ); 275 LuanSource.Element se = se(start,"stdout");
276 fnExp = new IndexExpr( se(start,"write"), fnExp, new ConstExpr("write") ); 276 fnExp = new IndexExpr( se, fnExp, new ConstExpr(se,"stdout") );
277 se = se(start,"write");
278 fnExp = new IndexExpr( se, fnExp, new ConstExpr(se,"write") );
277 FnCall fnCall = new FnCall( se(start), fnExp, exp ); 279 FnCall fnCall = new FnCall( se(start), fnExp, exp );
278 return new ExpressionsStmt(fnCall); 280 return new ExpressionsStmt(fnCall);
279 } 281 }
280 282
281 private Expressions TemplateExpressions(In in) throws ParseException { 283 private Expressions TemplateExpressions(In in) throws ParseException {
302 throw parser.exception("'%>' unexpected"); 304 throw parser.exception("'%>' unexpected");
303 if( !parser.anyChar() ) 305 if( !parser.anyChar() )
304 throw parser.exception("Unclosed template expression"); 306 throw parser.exception("Unclosed template expression");
305 } while( !parser.test( "<%" ) ); 307 } while( !parser.test( "<%" ) );
306 String match = parser.textFrom(i); 308 String match = parser.textFrom(i);
307 builder.add( new ConstExpr(match) ); 309 builder.add( new ConstExpr(se(i),match) );
308 } 310 }
309 } 311 }
310 } 312 }
311 313
312 private Stmt ReturnStmt() throws ParseException { 314 private Stmt ReturnStmt() throws ParseException {
358 i = modName.lastIndexOf('.'); 360 i = modName.lastIndexOf('.');
359 String varName = modName.substring(i+1); 361 String varName = modName.substring(i+1);
360 if( !isValidName(varName) ) 362 if( !isValidName(varName) )
361 throw parser.exception("invalid variable name '"+varName+"' in import"); 363 throw parser.exception("invalid variable name '"+varName+"' in import");
362 LuanSource.Element se = se(start); 364 LuanSource.Element se = se(start);
363 FnCall require = new FnCall( se, new ConstExpr(se,PackageLuan.requireFn), new ConstExpr(modName) ); 365 FnCall require = new FnCall( se, new ConstExpr(se,PackageLuan.requireFn), new ConstExpr(se(start,modName),modName) );
364 Settable settable; 366 Settable settable;
365 if( interactive ) { 367 if( interactive ) {
366 settable = nameVar(se,varName).settable(); 368 settable = nameVar(se,varName).settable();
367 } else { 369 } else {
368 addSymbol( varName ); 370 addSymbol( varName );
972 if( index != -1 ) 974 if( index != -1 )
973 return new GetLocalVar(se,index); 975 return new GetLocalVar(se,index);
974 index = upValueIndex(name); 976 index = upValueIndex(name);
975 if( index != -1 ) 977 if( index != -1 )
976 return new GetUpVar(se,index); 978 return new GetUpVar(se,index);
977 return new IndexExpr( se, env(), new ConstExpr(name) ); 979 return new IndexExpr( se, env(), new ConstExpr(se,name) );
978 } 980 }
979 981
980 public Settable settable() { 982 public Settable settable() {
981 int index = stackIndex(name); 983 int index = stackIndex(name);
982 if( index != -1 ) 984 if( index != -1 )
983 return new SetLocalVar(index); 985 return new SetLocalVar(index);
984 index = upValueIndex(name); 986 index = upValueIndex(name);
985 if( index != -1 ) 987 if( index != -1 )
986 return new SetUpVar(index); 988 return new SetUpVar(index);
987 return new SetTableEntry( se, env(), new ConstExpr(name) ); 989 return new SetTableEntry( se, env(), new ConstExpr(se,name) );
988 } 990 }
989 }; 991 };
990 } 992 }
991 993
992 private Var exprVar(final Expressions expr) { 994 private Var exprVar(final Expressions expr) {
1021 ? parser.success( new FnCall( se(start), fn, ExpList.build(builder) ) ) 1023 ? parser.success( new FnCall( se(start), fn, ExpList.build(builder) ) )
1022 : parser.failure((FnCall)null); 1024 : parser.failure((FnCall)null);
1023 } 1025 }
1024 1026
1025 private boolean args(In in,List<Expressions> builder) throws ParseException { 1027 private boolean args(In in,List<Expressions> builder) throws ParseException {
1028 int start = parser.begin();
1026 if( parser.match('(') ) { 1029 if( parser.match('(') ) {
1027 In inParens = in.parens(); 1030 In inParens = in.parens();
1028 Spaces(inParens); 1031 Spaces(inParens);
1029 ExpList(inParens,builder); // optional 1032 ExpList(inParens,builder); // optional
1030 if( !parser.match(')') ) 1033 if( !parser.match(')') )
1031 throw parser.exception("Expression or ')' expected"); 1034 throw parser.exception("Expression or ')' expected");
1032 Spaces(in); 1035 Spaces(in);
1033 return true; 1036 return parser.success();
1034 } 1037 }
1035 Expr exp = TableExpr(in); 1038 Expr exp = TableExpr(in);
1036 if( exp != null ) { 1039 if( exp != null ) {
1037 builder.add(exp); 1040 builder.add(exp);
1038 return true; 1041 return parser.success();
1039 } 1042 }
1040 String s = StringLiteral(in); 1043 String s = StringLiteral(in);
1041 if( s != null ) { 1044 if( s != null ) {
1042 builder.add( new ConstExpr(s) ); 1045 builder.add( new ConstExpr(se(start),s) );
1043 return true; 1046 return parser.success();
1044 } 1047 }
1045 /* 1048 /*
1046 Expressions exps = TemplateExpressions(in); 1049 Expressions exps = TemplateExpressions(in);
1047 if( exps != null ) { 1050 if( exps != null ) {
1048 builder.add(exps); 1051 builder.add(exps);
1049 return true; 1052 return parser.success();
1050 } 1053 }
1051 */ 1054 */
1052 return false; 1055 return parser.failure();
1053 } 1056 }
1054 1057
1055 private Expressions ExpList(In in) throws ParseException { 1058 private Expressions ExpList(In in) throws ParseException {
1056 List<Expressions> builder = new ArrayList<Expressions>(); 1059 List<Expressions> builder = new ArrayList<Expressions>();
1057 return ExpList(in,builder) ? ExpList.build(builder) : null; 1060 return ExpList(in,builder) ? ExpList.build(builder) : null;
1091 Spaces(in); 1094 Spaces(in);
1092 return parser.success(exp); 1095 return parser.success(exp);
1093 } 1096 }
1094 1097
1095 private Expr NameExpr(In in) throws ParseException { 1098 private Expr NameExpr(In in) throws ParseException {
1099 int start = parser.begin();
1096 String name = Name(in); 1100 String name = Name(in);
1097 return name==null ? null : new ConstExpr(name); 1101 if( name==null )
1102 return parser.failure(null);
1103 return parser.success(new ConstExpr(se(start),name));
1098 } 1104 }
1099 1105
1100 private String RequiredName(In in) throws ParseException { 1106 private String RequiredName(In in) throws ParseException {
1101 parser.begin(); 1107 parser.begin();
1102 String name = Name(in); 1108 String name = Name(in);
1175 "until", 1181 "until",
1176 "while" 1182 "while"
1177 )); 1183 ));
1178 1184
1179 private Expr Literal(In in) throws ParseException { 1185 private Expr Literal(In in) throws ParseException {
1186 int start = parser.begin();
1180 if( NilLiteral(in) ) 1187 if( NilLiteral(in) )
1181 return new ConstExpr(null); 1188 return parser.success(new ConstExpr(se(start),null));
1182 Boolean b = BooleanLiteral(in); 1189 Boolean b = BooleanLiteral(in);
1183 if( b != null ) 1190 if( b != null )
1184 return new ConstExpr(b); 1191 return parser.success(new ConstExpr(se(start),b));
1185 Number n = NumberLiteral(in); 1192 Number n = NumberLiteral(in);
1186 if( n != null ) 1193 if( n != null )
1187 return new ConstExpr(n); 1194 return parser.success(new ConstExpr(se(start),n));
1188 String s = StringLiteral(in); 1195 String s = StringLiteral(in);
1189 if( s != null ) 1196 if( s != null )
1190 return new ConstExpr(s); 1197 return parser.success(new ConstExpr(se(start),s));
1191 return null; 1198 return parser.failure(null);
1192 } 1199 }
1193 1200
1194 private boolean NilLiteral(In in) throws ParseException { 1201 private boolean NilLiteral(In in) throws ParseException {
1195 return Keyword("nil",in); 1202 return Keyword("nil",in);
1196 } 1203 }