Mercurial Hosting > luan
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 } |