comparison core/src/luan/impl/LuanParser.java @ 649:37f0cf43f191

UnaryExpr now compiled
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 30 Mar 2016 22:42:27 -0600
parents e387e4021afe
children d658eab7bf4c
comparison
equal deleted inserted replaced
648:e387e4021afe 649:37f0cf43f191
506 } 506 }
507 507
508 private Stmt ExpressionsStmt() throws ParseException { 508 private Stmt ExpressionsStmt() throws ParseException {
509 parser.begin(); 509 parser.begin();
510 Expressions exp = ExprZ(In.NOTHING); 510 Expressions exp = ExprZ(In.NOTHING);
511 if( exp instanceof FnCall || exp instanceof AndExpr || exp instanceof OrExpr ) 511 if( exp instanceof StmtExp )
512 return parser.success( new ExpressionsStmt(exp) ); 512 return parser.success( new ExpressionsStmt(exp) );
513 return parser.failure(null); 513 return parser.failure(null);
514 } 514 }
515 515
516 private Settable SettableVar() throws ParseException { 516 private Settable SettableVar() throws ParseException {
628 return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); 628 return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure();
629 } 629 }
630 630
631 private Expressions TermExpr(In in) throws ParseException { 631 private Expressions TermExpr(In in) throws ParseException {
632 parser.begin(); 632 parser.begin();
633 Expressions exp = UnaryExpr(in); 633 ExpString expStr = UnaryExpr(in);
634 if( exp==null ) 634 if( expStr==null )
635 return parser.failure(null); 635 return parser.failure(null);
636 Expressions exp = expStr.toExpressions();
636 while(true) { 637 while(true) {
637 if( parser.match('*') ) { 638 if( parser.match('*') ) {
638 Spaces(in); 639 Spaces(in);
639 Expressions exp2 = UnaryExpr(in); 640 Expressions exp2 = required(UnaryExpr(in)).toExpressions();
640 exp = new MulExpr( expr(exp), required(expr(exp2)) ); 641 exp = new MulExpr( expr(exp), expr(exp2) );
641 } else if( parser.match('/') ) { 642 } else if( parser.match('/') ) {
642 Spaces(in); 643 Spaces(in);
643 Expressions exp2 = UnaryExpr(in); 644 Expressions exp2 = required(UnaryExpr(in)).toExpressions();
644 exp = new DivExpr( expr(exp), required(expr(exp2)) ); 645 exp = new DivExpr( expr(exp), expr(exp2) );
645 } else if( Mod() ) { 646 } else if( Mod() ) {
646 Spaces(in); 647 Spaces(in);
647 Expressions exp2 = UnaryExpr(in); 648 Expressions exp2 = required(UnaryExpr(in)).toExpressions();
648 exp = new ModExpr( expr(exp), required(expr(exp2)) ); 649 exp = new ModExpr( expr(exp), expr(exp2) );
649 } else 650 } else
650 break; 651 break;
651 } 652 }
652 return parser.success(exp); 653 return parser.success(exp);
653 } 654 }
655 private boolean Mod() { 656 private boolean Mod() {
656 parser.begin(); 657 parser.begin();
657 return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); 658 return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure();
658 } 659 }
659 660
660 private Expressions UnaryExpr(In in) throws ParseException { 661 private ExpString UnaryExpr(In in) throws ParseException {
661 parser.begin(); 662 parser.begin();
662 if( parser.match('#') ) { 663 if( parser.match('#') ) {
663 Spaces(in); 664 Spaces(in);
664 Expressions exp = required(UnaryExpr(in)); 665 ExpString exp = required(UnaryExpr(in)).expr();
665 String code = "$Luan.len($luan," + expressionsToExprString(exp) + ")"; 666 String code = "$Luan.len($luan," + exp.code + ")";
666 exp = stringToExpressions(code); 667 exp = new ExpString(code,true,false);
667 return parser.success(exp); 668 return parser.success(exp);
668 } 669 }
669 if( Minus() ) { 670 if( Minus() ) {
670 Spaces(in); 671 Spaces(in);
671 Expressions exp = UnaryExpr(in); 672 ExpString exp = required(UnaryExpr(in)).expr();
672 return parser.success( new UnmExpr( required(expr(exp)) ) ); 673 String code = "$Luan.unm($luan," + exp.code + ")";
674 exp = new ExpString(code,true,false);
675 return parser.success(exp);
673 } 676 }
674 if( Keyword("not",in) ) { 677 if( Keyword("not",in) ) {
675 Spaces(in); 678 Spaces(in);
676 Expressions exp = UnaryExpr(in); 679 ExpString exp = required(UnaryExpr(in)).expr();
677 return parser.success( new NotExpr( required(expr(exp)) ) ); 680 String code = "$Luan.not(" + exp.code + ")";
681 exp = new ExpString(code,true,false);
682 return parser.success(exp);
678 } 683 }
679 Expressions exp = PowExpr(in); 684 Expressions exp = PowExpr(in);
680 if( exp==null ) 685 if( exp==null )
681 return parser.failure(null); 686 return parser.failure(null);
682 return parser.success(exp); 687 return parser.success(new ExpString(exp));
683 } 688 }
684 689
685 private Expressions PowExpr(In in) throws ParseException { 690 private Expressions PowExpr(In in) throws ParseException {
686 parser.begin(); 691 parser.begin();
687 Expressions exp = SingleExpr(in); 692 Expressions exp = SingleExpr(in);
1350 } 1355 }
1351 1356
1352 1357
1353 1358
1354 1359
1355 private static String expressionsToExprString(Expressions exp) {
1356 int i = $Luan.addExpressions(exp);
1357 String s = "$Luan.getExpressions(" + i + ").eval($luan)";
1358 if( !(exp instanceof Expr) )
1359 s = "$Luan.first(" + s + ")";
1360 return s;
1361 }
1362
1363 private static int classCounter = 0; 1360 private static int classCounter = 0;
1364 1361
1365 private static Expressions stringToExpressions(String code) { 1362 private class ExpString {
1366 String className = "EXP" + ++classCounter; 1363 final String code;
1367 String classCode = "" 1364 final boolean isExpr;
1368 +"package luan.impl;\n" 1365 final boolean isStmt;
1369 // +"import luan.impl.$Luan;\n" 1366
1370 // +"import luan.impl.Expressions;\n" 1367 ExpString(Expressions exp) {
1371 +"import luan.LuanException;\n" 1368 if( exp==null ) throw new NullPointerException();
1372 +"\n" 1369 int i = $Luan.addExpressions(exp);
1373 +"public class " + className +" implements Expressions {\n" 1370 code = "$Luan.getExpressions(" + i + ").eval($luan)";
1374 +" @Override public Object eval(LuanStateImpl $luan) throws LuanException {\n" 1371 isExpr = exp instanceof Expr;
1375 +" return " + code + ";\n" 1372 isStmt = exp instanceof StmtExp;
1376 +" }\n" 1373 }
1377 +"}\n" 1374
1378 ; 1375 ExpString(String code,boolean isExpr,boolean isStmt) {
1379 try { 1376 this.code = code;
1380 Class cls = LuanJavaCompiler.compile("luan.impl."+className,code,classCode); 1377 this.isExpr = isExpr;
1381 return (Expressions)cls.newInstance(); 1378 this.isStmt = isStmt;
1382 } catch(ClassNotFoundException e) { 1379 }
1383 throw new RuntimeException(e); 1380
1384 } catch(InstantiationException e) { 1381 ExpString expr() {
1385 throw new RuntimeException(e); 1382 return isExpr ? this : new ExpString( "$Luan.first(" + code + ")", true, false );
1386 } catch(IllegalAccessException e) { 1383 }
1387 throw new RuntimeException(e); 1384
1385 Expressions toExpressions() {
1386 String superClass = isStmt ? "StmtExp" : "Expressions";
1387 String className = "EXP" + ++classCounter;
1388 String classCode = ""
1389 +"package luan.impl;\n"
1390 +"import luan.LuanException;\n"
1391 +"\n"
1392 +"public class " + className +" implements " + superClass + " {\n"
1393 +" @Override public Object eval(LuanStateImpl $luan) throws LuanException {\n"
1394 +" return " + code + ";\n"
1395 +" }\n"
1396 +"}\n"
1397 ;
1398 //System.out.println(code);
1399 try {
1400 Class cls = LuanJavaCompiler.compile("luan.impl."+className,code,classCode);
1401 return (Expressions)cls.newInstance();
1402 } catch(ClassNotFoundException e) {
1403 throw new RuntimeException(e);
1404 } catch(InstantiationException e) {
1405 throw new RuntimeException(e);
1406 } catch(IllegalAccessException e) {
1407 throw new RuntimeException(e);
1408 }
1388 } 1409 }
1389 } 1410 }
1390 1411
1391 } 1412 }