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);