Mercurial Hosting > luan
comparison core/src/luan/impl/LuanParser.java @ 660:e064377994b2
compile table put
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 06 Apr 2016 21:06:29 -0600 |
parents | e038905512d3 |
children | 1bbb08c0d8f1 |
comparison
equal
deleted
inserted
replaced
659:f1150518c467 | 660:e064377994b2 |
---|---|
246 private void Stmt(StringBuilder stmts) throws ParseException { | 246 private void Stmt(StringBuilder stmts) throws ParseException { |
247 if( LocalStmt(stmts) ) | 247 if( LocalStmt(stmts) ) |
248 return; | 248 return; |
249 StmtString stmt; | 249 StmtString stmt; |
250 if( (stmt=ReturnStmt()) != null | 250 if( (stmt=ReturnStmt()) != null |
251 || (stmt=stmtStr(FunctionStmt())) != null | 251 || (stmt=FunctionStmt()) != null |
252 || (stmt=stmtStr(LocalFunctionStmt())) != null | 252 || (stmt=stmtStr(LocalFunctionStmt())) != null |
253 || (stmt=BreakStmt()) != null | 253 || (stmt=BreakStmt()) != null |
254 || (stmt=ForStmt()) != null | 254 || (stmt=ForStmt()) != null |
255 || (stmt=DoStmt()) != null | 255 || (stmt=DoStmt()) != null |
256 || (stmt=WhileStmt()) != null | 256 || (stmt=WhileStmt()) != null |
336 String code = "luan.returnValues = " + (exprs!=null ? exprs.code : "LuanFunction.NOTHING") + ";\n" | 336 String code = "luan.returnValues = " + (exprs!=null ? exprs.code : "LuanFunction.NOTHING") + ";\n" |
337 +"return;\n"; | 337 +"return;\n"; |
338 return parser.success( new StmtString(code) ); | 338 return parser.success( new StmtString(code) ); |
339 } | 339 } |
340 | 340 |
341 private Stmt FunctionStmt() throws ParseException { | 341 private StmtString FunctionStmt() throws ParseException { |
342 parser.begin(); | 342 parser.begin(); |
343 if( !Keyword("function",In.NOTHING) ) | 343 if( !Keyword("function",In.NOTHING) ) |
344 return parser.failure(null); | 344 return parser.failure(null); |
345 | 345 |
346 parser.currentIndex(); | 346 parser.currentIndex(); |
350 ExpString exp = NameExpr(In.NOTHING); | 350 ExpString exp = NameExpr(In.NOTHING); |
351 if( exp==null ) | 351 if( exp==null ) |
352 return parser.failure(null); | 352 return parser.failure(null); |
353 var = indexVar( var.exp(), exp ); | 353 var = indexVar( var.exp(), exp ); |
354 } | 354 } |
355 Settable fnName = var.settable(); | |
356 | 355 |
357 FnDef fnDef = RequiredFunction(In.NOTHING); | 356 FnDef fnDef = RequiredFunction(In.NOTHING); |
358 return parser.success( new SetStmt(fnName,fnDef) ); | 357 return parser.success( var.set(new ExpString(fnDef)) ); |
359 } | 358 } |
360 | 359 |
361 private Stmt LocalFunctionStmt() throws ParseException { | 360 private Stmt LocalFunctionStmt() throws ParseException { |
362 parser.begin(); | 361 parser.begin(); |
363 if( !(Keyword("local",In.NOTHING) && Keyword("function",In.NOTHING)) ) | 362 if( !(Keyword("local",In.NOTHING) && Keyword("function",In.NOTHING)) ) |
553 return parser.success( new StmtString(sb.toString()) ); | 552 return parser.success( new StmtString(sb.toString()) ); |
554 } | 553 } |
555 | 554 |
556 private StmtString SetStmt() throws ParseException { | 555 private StmtString SetStmt() throws ParseException { |
557 parser.begin(); | 556 parser.begin(); |
558 List<Settable> vars = new ArrayList<Settable>(); | 557 List<Var> vars = new ArrayList<Var>(); |
559 Settable s = SettableVar(); | 558 Var v = SettableVar(); |
560 if( s == null ) | 559 if( v == null ) |
561 return parser.failure(null); | 560 return parser.failure(null); |
562 vars.add(s); | 561 vars.add(v); |
563 while( parser.match( ',' ) ) { | 562 while( parser.match( ',' ) ) { |
564 Spaces(In.NOTHING); | 563 Spaces(In.NOTHING); |
565 s = SettableVar(); | 564 v = SettableVar(); |
566 if( s == null ) | 565 if( v == null ) |
567 return parser.failure(null); | 566 return parser.failure(null); |
568 vars.add(s); | 567 vars.add(v); |
569 } | 568 } |
570 if( !parser.match( '=' ) ) | 569 if( !parser.match( '=' ) ) |
571 return parser.failure(null); | 570 return parser.failure(null); |
572 Spaces(In.NOTHING); | 571 Spaces(In.NOTHING); |
573 ExpString values = ExpStringList(In.NOTHING); | 572 ExpString values = ExpStringList(In.NOTHING); |
574 if( values==null ) | 573 if( values==null ) |
575 // throw parser.exception("Expressions expected"); | 574 // throw parser.exception("Expressions expected"); |
576 return parser.failure(null); | 575 return parser.failure(null); |
577 String varsStr = varsToString(vars.toArray(new Settable[0])); | 576 int n = vars.size(); |
578 String code = "LuanImpl.set(luan," + varsStr + "," + values.code + "); "; | 577 if( n == 1 ) |
579 return parser.success( new StmtString(code) ); | 578 return parser.success( vars.get(0).set(values) ); |
579 StringBuilder sb = new StringBuilder(); | |
580 sb.append( "t = " + values.code + ";\n" ); | |
581 ExpString t = new ExpString("t",true,false); | |
582 sb.append( vars.get(0).set(new ExpString("t",true,false)).code ); | |
583 for( int i=1; i<n; i++ ) { | |
584 sb.append( vars.get(0).set(new ExpString("LuanImpl.pick(t,"+i+")",true,false)).code ); | |
585 } | |
586 return parser.success( new StmtString(sb.toString()) ); | |
580 } | 587 } |
581 | 588 |
582 private static String varsToString(Settable[] vars) { | 589 private static String varsToString(Settable[] vars) { |
583 StringBuilder sb = new StringBuilder(); | 590 StringBuilder sb = new StringBuilder(); |
584 sb.append( "new Settable[]{" ); | 591 sb.append( "new Settable[]{" ); |
600 return parser.success( new StmtString(code) ); | 607 return parser.success( new StmtString(code) ); |
601 } | 608 } |
602 return parser.failure(null); | 609 return parser.failure(null); |
603 } | 610 } |
604 | 611 |
605 private Settable SettableVar() throws ParseException { | 612 private Var SettableVar() throws ParseException { |
606 int start = parser.begin(); | 613 int start = parser.begin(); |
607 Var var = VarZ(In.NOTHING); | 614 Var var = VarZ(In.NOTHING); |
608 if( var==null ) | 615 if( var==null || !var.isSettable() ) |
609 return parser.failure(null); | 616 return parser.failure(null); |
610 return parser.success( var.settable() ); | 617 return parser.success( var ); |
611 } | 618 } |
612 | 619 |
613 private ExpString RequiredExpr(In in) throws ParseException { | 620 private ExpString RequiredExpr(In in) throws ParseException { |
614 parser.begin(); | 621 parser.begin(); |
615 return parser.success(required(ExprZ(in),"Bad expression")); | 622 return parser.success(required(ExprZ(in),"Bad expression")); |
625 if( exp==null ) | 632 if( exp==null ) |
626 return parser.failure(null); | 633 return parser.failure(null); |
627 while( Keyword("or",in) ) { | 634 while( Keyword("or",in) ) { |
628 exp = exp.expr(); | 635 exp = exp.expr(); |
629 ExpString exp2 = required(RelExpr(in)).expr(); | 636 ExpString exp2 = required(RelExpr(in)).expr(); |
630 String code = "(LuanImpl.cnd(cnd = " + exp.code + ") ? cnd : (" + exp2.code + "))"; | 637 String code = "(LuanImpl.cnd(t = " + exp.code + ") ? t : (" + exp2.code + "))"; |
631 exp = new ExpString(code,true,true); | 638 exp = new ExpString(code,true,true); |
632 } | 639 } |
633 return parser.success(exp); | 640 return parser.success(exp); |
634 } | 641 } |
635 | 642 |
639 if( exp==null ) | 646 if( exp==null ) |
640 return parser.failure(null); | 647 return parser.failure(null); |
641 while( Keyword("and",in) ) { | 648 while( Keyword("and",in) ) { |
642 exp = exp.expr(); | 649 exp = exp.expr(); |
643 ExpString exp2 = required(RelExpr(in)).expr(); | 650 ExpString exp2 = required(RelExpr(in)).expr(); |
644 String code = "(LuanImpl.cnd(cnd = " + exp.code + ") ? (" + exp2.code + ") : cnd)"; | 651 String code = "(LuanImpl.cnd(t = " + exp.code + ") ? (" + exp2.code + ") : t)"; |
645 exp = new ExpString(code,true,true); | 652 exp = new ExpString(code,true,true); |
646 } | 653 } |
647 return parser.success(exp); | 654 return parser.success(exp); |
648 } | 655 } |
649 | 656 |
977 return parser.failure(null); | 984 return parser.failure(null); |
978 } | 985 } |
979 | 986 |
980 private interface Var { | 987 private interface Var { |
981 public ExpString exp() throws ParseException; | 988 public ExpString exp() throws ParseException; |
982 public Settable settable() throws ParseException; | 989 // public Settable settable() throws ParseException; |
990 public boolean isSettable(); | |
991 public StmtString set(ExpString val) throws ParseException; | |
983 } | 992 } |
984 | 993 |
985 private Expr env() { | 994 private Expr env() { |
986 int index = stackIndex(_ENV); | 995 int index = stackIndex(_ENV); |
987 if( index != -1 ) | 996 if( index != -1 ) |
1007 return indexExpStr( new ExpString(envExpr), constExpStr(name) ); | 1016 return indexExpStr( new ExpString(envExpr), constExpStr(name) ); |
1008 parser.failure(null); | 1017 parser.failure(null); |
1009 throw parser.exception("name '"+name+"' not defined"); | 1018 throw parser.exception("name '"+name+"' not defined"); |
1010 } | 1019 } |
1011 | 1020 |
1012 public Settable settable() throws ParseException { | 1021 public boolean isSettable() { |
1022 return true; | |
1023 } | |
1024 | |
1025 private Settable settable() throws ParseException { | |
1013 int index = stackIndex(name); | 1026 int index = stackIndex(name); |
1014 if( index != -1 ) | 1027 if( index != -1 ) |
1015 return new SetLocalVar(index); | 1028 return new SetLocalVar(index); |
1016 index = upValueIndex(name); | 1029 index = upValueIndex(name); |
1017 if( index != -1 ) | 1030 if( index != -1 ) |
1020 if( envExpr != null ) | 1033 if( envExpr != null ) |
1021 return new SetTableEntry( envExpr, new ConstExpr(name) ); | 1034 return new SetTableEntry( envExpr, new ConstExpr(name) ); |
1022 parser.failure(null); | 1035 parser.failure(null); |
1023 throw parser.exception("name '"+name+"' not defined"); | 1036 throw parser.exception("name '"+name+"' not defined"); |
1024 } | 1037 } |
1038 | |
1039 public StmtString set(ExpString val) throws ParseException { | |
1040 String code = new SettableString(settable()).code + ".set(luan," + val.expr().code + ");\n"; | |
1041 return new StmtString(code); | |
1042 } | |
1025 }; | 1043 }; |
1026 } | 1044 } |
1027 | 1045 |
1028 private Var exprVar(final ExpString expr) { | 1046 private Var exprVar(final ExpString expr) { |
1029 return new Var() { | 1047 return new Var() { |
1030 | 1048 |
1031 public ExpString exp() { | 1049 public ExpString exp() { |
1032 return expr; | 1050 return expr; |
1033 } | 1051 } |
1034 | 1052 |
1035 public Settable settable() { | 1053 public boolean isSettable() { |
1036 return null; | 1054 return false; |
1055 } | |
1056 | |
1057 public StmtString set(ExpString val) { | |
1058 throw new RuntimeException(); | |
1037 } | 1059 } |
1038 }; | 1060 }; |
1039 } | 1061 } |
1040 | 1062 |
1041 private Var indexVar(final ExpString table,final ExpString key) { | 1063 private Var indexVar(final ExpString table,final ExpString key) { |
1043 | 1065 |
1044 public ExpString exp() { | 1066 public ExpString exp() { |
1045 return indexExpStr( table, key ); | 1067 return indexExpStr( table, key ); |
1046 } | 1068 } |
1047 | 1069 |
1070 public boolean isSettable() { | |
1071 return true; | |
1072 } | |
1073 /* | |
1048 public Settable settable() { | 1074 public Settable settable() { |
1049 return new SetTableEntry(expr(LuanParser.exp(table)),expr(LuanParser.exp(key))); | 1075 return new SetTableEntry(expr(LuanParser.exp(table)),expr(LuanParser.exp(key))); |
1076 } | |
1077 */ | |
1078 public StmtString set(ExpString val) { | |
1079 String code = "LuanImpl.put(luan," + table.expr().code + "," + key.expr().code + "," + val.expr().code + ");\n"; | |
1080 return new StmtString(code); | |
1050 } | 1081 } |
1051 }; | 1082 }; |
1052 } | 1083 } |
1053 | 1084 |
1054 private ExpString Args(In in,ExpString fn,List<ExpString> builder) throws ParseException { | 1085 private ExpString Args(In in,ExpString fn,List<ExpString> builder) throws ParseException { |
1501 } | 1532 } |
1502 | 1533 |
1503 ExpString expr() { | 1534 ExpString expr() { |
1504 return isExpr ? this : new ExpString( "Luan.first(" + code + ")", true, isStmt ); | 1535 return isExpr ? this : new ExpString( "Luan.first(" + code + ")", true, isStmt ); |
1505 } | 1536 } |
1506 | |
1507 Expressions toExpressions() { | |
1508 String superClass = isStmt ? "StmtExp" : "Expressions"; | |
1509 String className = "EXP" + ++classCounter; | |
1510 String classCode = "" | |
1511 +"package luan.impl;\n" | |
1512 +"import luan.Luan;\n" | |
1513 +"import luan.LuanFunction;\n" | |
1514 +"import luan.LuanException;\n" | |
1515 +"import luan.modules.PackageLuan;\n" | |
1516 +"\n" | |
1517 +"public class " + className +" implements " + superClass + " {\n" | |
1518 +" @Override public Object eval(LuanStateImpl luan) throws LuanException {\n" | |
1519 +" Object cnd;\n" | |
1520 +" return " + code + ";\n" | |
1521 +" }\n" | |
1522 +"}\n" | |
1523 ; | |
1524 //System.out.println(code); | |
1525 try { | |
1526 Class cls = LuanJavaCompiler.compile("luan.impl."+className,code,classCode); | |
1527 return (Expressions)cls.newInstance(); | |
1528 } catch(ClassNotFoundException e) { | |
1529 throw new RuntimeException(e); | |
1530 } catch(InstantiationException e) { | |
1531 throw new RuntimeException(e); | |
1532 } catch(IllegalAccessException e) { | |
1533 throw new RuntimeException(e); | |
1534 } | |
1535 } | |
1536 } | |
1537 | |
1538 private static Expressions exp(ExpString expStr) { | |
1539 return expStr==null ? null : expStr.toExpressions(); | |
1540 } | 1537 } |
1541 | 1538 |
1542 private ExpString expString(List<ExpString> list) { | 1539 private ExpString expString(List<ExpString> list) { |
1543 switch(list.size()) { | 1540 switch(list.size()) { |
1544 case 0: | 1541 case 0: |
1587 +"import luan.LuanException;\n" | 1584 +"import luan.LuanException;\n" |
1588 +"import luan.modules.PackageLuan;\n" | 1585 +"import luan.modules.PackageLuan;\n" |
1589 +"\n" | 1586 +"\n" |
1590 +"public class " + className +" implements Stmt {\n" | 1587 +"public class " + className +" implements Stmt {\n" |
1591 +" @Override public void eval(LuanStateImpl luan) throws LuanException {\n" | 1588 +" @Override public void eval(LuanStateImpl luan) throws LuanException {\n" |
1592 +" Object cnd;\n" | 1589 +" Object t;\n" |
1593 +" " + code | 1590 +" " + code |
1594 +" }\n" | 1591 +" }\n" |
1595 +"}\n" | 1592 +"}\n" |
1596 ; | 1593 ; |
1597 //System.out.println(code); | 1594 //System.out.println(code); |