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