Mercurial Hosting > luan
comparison core/src/luan/impl/LuanParser.java @ 681:f1c935be546d
improve stack trace
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 14 Apr 2016 20:10:38 -0600 |
parents | ecd436959855 |
children | 0c334975d526 |
comparison
equal
deleted
inserted
replaced
680:ecd436959855 | 681:f1c935be546d |
---|---|
243 | 243 |
244 private Class newFnClass(Stmts stmt) { | 244 private Class newFnClass(Stmts stmt) { |
245 return toFnClass( stmt, frame.upValueSymbols ); | 245 return toFnClass( stmt, frame.upValueSymbols ); |
246 } | 246 } |
247 | 247 |
248 private Expr newFnExpStr(Stmts stmt) { | 248 private Expr newFnExp(Stmts stmt,String name) { |
249 return toFnExpStr( stmt, frame.upValueSymbols ); | 249 return toFnExp( stmt, frame.upValueSymbols, name ); |
250 } | 250 } |
251 | 251 |
252 Class Expression() throws ParseException { | 252 Class Expression() throws ParseException { |
253 Spaces(); | 253 Spaces(); |
254 parser.begin(); | 254 parser.begin(); |
434 parser.begin(); | 434 parser.begin(); |
435 if( !Keyword("function") ) | 435 if( !Keyword("function") ) |
436 return parser.failure(null); | 436 return parser.failure(null); |
437 | 437 |
438 parser.currentIndex(); | 438 parser.currentIndex(); |
439 Var var = nameVar(RequiredName()); | 439 String name = RequiredName(); |
440 Var var = nameVar(name); | |
440 while( parser.match( '.' ) ) { | 441 while( parser.match( '.' ) ) { |
441 Spaces(); | 442 Spaces(); |
442 Expr exp = NameExpr(); | 443 // Expr exp = NameExpr(); |
443 if( exp==null ) | 444 name = Name(); |
445 if( name==null ) | |
444 return parser.failure(null); | 446 return parser.failure(null); |
445 var = indexVar( var.exp(), exp ); | 447 var = indexVar( var.exp(), constExpStr(name) ); |
446 } | 448 } |
447 | 449 |
448 Expr fnDef = RequiredFunction(In.NOTHING); | 450 Expr fnDef = RequiredFunction(name); |
449 return parser.success( var.set(fnDef) ); | 451 return parser.success( var.set(fnDef) ); |
450 } | 452 } |
451 | 453 |
452 private Stmts LocalFunctionStmt() throws ParseException { | 454 private Stmts LocalFunctionStmt() throws ParseException { |
453 parser.begin(); | 455 parser.begin(); |
454 if( !(Keyword("local") && Keyword("function")) ) | 456 if( !(Keyword("local") && Keyword("function")) ) |
455 return parser.failure(null); | 457 return parser.failure(null); |
456 Stmts stmt = new Stmts(); | 458 Stmts stmt = new Stmts(); |
457 String name = RequiredName(); | 459 String name = RequiredName(); |
458 stmt.addAll( addSymbol(name,null) ); | 460 stmt.addAll( addSymbol(name,null) ); |
459 Expr fnDef = RequiredFunction(In.NOTHING); | 461 Expr fnDef = RequiredFunction(name); |
460 stmt.addAll( nameVar(name).set(fnDef) ); | 462 stmt.addAll( nameVar(name).set(fnDef) ); |
461 return parser.success( stmt ); | 463 return parser.success( stmt ); |
462 } | 464 } |
463 | 465 |
464 private Stmts BreakStmt() throws ParseException { | 466 private Stmts BreakStmt() throws ParseException { |
481 return parser.failure(null); | 483 return parser.failure(null); |
482 List<String> names = RequiredNameList(); | 484 List<String> names = RequiredNameList(); |
483 if( !Keyword("in") ) | 485 if( !Keyword("in") ) |
484 return parser.failure(null); | 486 return parser.failure(null); |
485 Expr expr = RequiredExpr(In.NOTHING).single(); | 487 Expr expr = RequiredExpr(In.NOTHING).single(); |
486 RequiredKeyword("do",In.NOTHING); | 488 RequiredKeyword("do"); |
487 | 489 |
488 String fnVar = "fn"+ ++forCounter; | 490 String fnVar = "fn"+ ++forCounter; |
489 Expr fnExp = new Expr(null,false); | 491 Expr fnExp = new Expr(null,false); |
490 fnExp.add( fnVar + ".call(luan)" ); | 492 fnExp.add( fnVar + ".call(luan)" ); |
491 Stmts stmt = new Stmts(); | 493 Stmts stmt = new Stmts(); |
498 stmt.addAll( makeLocalSetStmt(names,fnExp) ); | 500 stmt.addAll( makeLocalSetStmt(names,fnExp) ); |
499 stmt.add( "if( " ); | 501 stmt.add( "if( " ); |
500 stmt.addAll( nameVar(names.get(0)).exp() ); | 502 stmt.addAll( nameVar(names.get(0)).exp() ); |
501 stmt.add( "==null ) break; " ); | 503 stmt.add( "==null ) break; " ); |
502 Stmts loop = RequiredLoopBlock(); | 504 Stmts loop = RequiredLoopBlock(); |
503 RequiredKeyword("end",In.NOTHING); | 505 RequiredKeyword("end"); |
504 stmt.addAll( loop ); | 506 stmt.addAll( loop ); |
505 stmt.add( "} " ); | 507 stmt.add( "} " ); |
506 popSymbols( symbolsSize() - stackStart ); | 508 popSymbols( symbolsSize() - stackStart ); |
507 return parser.success(stmt); | 509 return parser.success(stmt); |
508 } | 510 } |
510 private Stmts DoStmt() throws ParseException { | 512 private Stmts DoStmt() throws ParseException { |
511 parser.begin(); | 513 parser.begin(); |
512 if( !Keyword("do") ) | 514 if( !Keyword("do") ) |
513 return parser.failure(null); | 515 return parser.failure(null); |
514 Stmts stmt = RequiredBlock(); | 516 Stmts stmt = RequiredBlock(); |
515 RequiredKeyword("end",In.NOTHING); | 517 RequiredKeyword("end"); |
516 return parser.success(stmt); | 518 return parser.success(stmt); |
517 } | 519 } |
518 | 520 |
519 private Stmts LocalStmt() throws ParseException { | 521 private Stmts LocalStmt() throws ParseException { |
520 parser.begin(); | 522 parser.begin(); |
577 private Stmts WhileStmt() throws ParseException { | 579 private Stmts WhileStmt() throws ParseException { |
578 parser.begin(); | 580 parser.begin(); |
579 if( !Keyword("while") ) | 581 if( !Keyword("while") ) |
580 return parser.failure(null); | 582 return parser.failure(null); |
581 Expr cnd = RequiredExpr(In.NOTHING).single(); | 583 Expr cnd = RequiredExpr(In.NOTHING).single(); |
582 RequiredKeyword("do",In.NOTHING); | 584 RequiredKeyword("do"); |
583 Stmts loop = RequiredLoopBlock(); | 585 Stmts loop = RequiredLoopBlock(); |
584 RequiredKeyword("end",In.NOTHING); | 586 RequiredKeyword("end"); |
585 Stmts stmt = new Stmts(); | 587 Stmts stmt = new Stmts(); |
586 stmt.add( "while( Luan.checkBoolean(" ); | 588 stmt.add( "while( Luan.checkBoolean(" ); |
587 stmt.addAll( cnd ); | 589 stmt.addAll( cnd ); |
588 stmt.add( ") ) { " ); | 590 stmt.add( ") ) { " ); |
589 stmt.addAll( loop ); | 591 stmt.addAll( loop ); |
594 private Stmts RepeatStmt() throws ParseException { | 596 private Stmts RepeatStmt() throws ParseException { |
595 parser.begin(); | 597 parser.begin(); |
596 if( !Keyword("repeat") ) | 598 if( !Keyword("repeat") ) |
597 return parser.failure(null); | 599 return parser.failure(null); |
598 Stmts loop =RequiredLoopBlock(); | 600 Stmts loop =RequiredLoopBlock(); |
599 RequiredKeyword("until",In.NOTHING); | 601 RequiredKeyword("until"); |
600 Expr cnd = RequiredExpr(In.NOTHING).single(); | 602 Expr cnd = RequiredExpr(In.NOTHING).single(); |
601 Stmts stmt = new Stmts(); | 603 Stmts stmt = new Stmts(); |
602 stmt.add( "do { " ); | 604 stmt.add( "do { " ); |
603 stmt.addAll( loop ); | 605 stmt.addAll( loop ); |
604 stmt.add( "} while( !Luan.checkBoolean(" ); | 606 stmt.add( "} while( !Luan.checkBoolean(" ); |
620 return parser.failure(null); | 622 return parser.failure(null); |
621 Stmts stmt = new Stmts(); | 623 Stmts stmt = new Stmts(); |
622 Expr cnd; | 624 Expr cnd; |
623 Stmts block; | 625 Stmts block; |
624 cnd = RequiredExpr(In.NOTHING).single(); | 626 cnd = RequiredExpr(In.NOTHING).single(); |
625 RequiredKeyword("then",In.NOTHING); | 627 RequiredKeyword("then"); |
626 block = RequiredBlock(); | 628 block = RequiredBlock(); |
627 stmt.add( "if( Luan.checkBoolean(" ); | 629 stmt.add( "if( Luan.checkBoolean(" ); |
628 stmt.addAll( cnd ); | 630 stmt.addAll( cnd ); |
629 stmt.add( ") ) { " ); | 631 stmt.add( ") ) { " ); |
630 stmt.addAll( block ); | 632 stmt.addAll( block ); |
631 while( Keyword("elseif") ) { | 633 while( Keyword("elseif") ) { |
632 cnd = RequiredExpr(In.NOTHING).single(); | 634 cnd = RequiredExpr(In.NOTHING).single(); |
633 RequiredKeyword("then",In.NOTHING); | 635 RequiredKeyword("then"); |
634 block = RequiredBlock(); | 636 block = RequiredBlock(); |
635 stmt.add( "} else if( Luan.checkBoolean(" ); | 637 stmt.add( "} else if( Luan.checkBoolean(" ); |
636 stmt.addAll( cnd ); | 638 stmt.addAll( cnd ); |
637 stmt.add( ") ) { " ); | 639 stmt.add( ") ) { " ); |
638 stmt.addAll( block ); | 640 stmt.addAll( block ); |
640 if( Keyword("else") ) { | 642 if( Keyword("else") ) { |
641 block = RequiredBlock(); | 643 block = RequiredBlock(); |
642 stmt.add( "} else { " ); | 644 stmt.add( "} else { " ); |
643 stmt.addAll( block ); | 645 stmt.addAll( block ); |
644 } | 646 } |
645 RequiredKeyword("end",In.NOTHING); | 647 RequiredKeyword("end"); |
646 stmt.add( "} " ); | 648 stmt.add( "} " ); |
647 return parser.success( stmt ); | 649 return parser.success( stmt ); |
648 } | 650 } |
649 | 651 |
650 private Stmts SetStmt() throws ParseException { | 652 private Stmts SetStmt() throws ParseException { |
1027 return parser.success(exp1); | 1029 return parser.success(exp1); |
1028 } | 1030 } |
1029 | 1031 |
1030 private Expr SingleExpr(In in) throws ParseException { | 1032 private Expr SingleExpr(In in) throws ParseException { |
1031 parser.begin(); | 1033 parser.begin(); |
1032 Expr exp = FunctionExpr(in); | 1034 Expr exp = FunctionExpr(); |
1033 if( exp != null ) | 1035 if( exp != null ) |
1034 return parser.success(exp); | 1036 return parser.success(exp); |
1035 exp = VarExp(in); | 1037 exp = VarExp(in); |
1036 if( exp != null ) | 1038 if( exp != null ) |
1037 return parser.success(exp); | 1039 return parser.success(exp); |
1039 if( exp != null ) | 1041 if( exp != null ) |
1040 return parser.success(exp); | 1042 return parser.success(exp); |
1041 return parser.failure(null); | 1043 return parser.failure(null); |
1042 } | 1044 } |
1043 | 1045 |
1044 private Expr FunctionExpr(In in) throws ParseException { | 1046 private Expr FunctionExpr() throws ParseException { |
1045 if( !Keyword("function") ) | 1047 if( !Keyword("function") ) |
1046 return null; | 1048 return null; |
1047 return RequiredFunction(in); | 1049 return RequiredFunction(null); |
1048 } | 1050 } |
1049 | 1051 |
1050 private Expr RequiredFunction(In in) throws ParseException { | 1052 private Expr RequiredFunction(String name) throws ParseException { |
1051 parser.begin(); | 1053 parser.begin(); |
1052 RequiredMatch('('); | 1054 RequiredMatch('('); |
1053 Spaces(); | 1055 Spaces(); |
1054 frame = new Frame(frame); | 1056 frame = new Frame(frame); |
1055 Stmts stmt = new Stmts(); | 1057 Stmts stmt = new Stmts(); |
1074 RequiredMatch(')'); | 1076 RequiredMatch(')'); |
1075 Spaces(); | 1077 Spaces(); |
1076 Stmts block = RequiredBlock(); | 1078 Stmts block = RequiredBlock(); |
1077 stmt.addAll( block ); | 1079 stmt.addAll( block ); |
1078 stmt.hasReturn = block.hasReturn; | 1080 stmt.hasReturn = block.hasReturn; |
1079 Expr fnDef = newFnExpStr(stmt); | 1081 Expr fnDef = newFnExp(stmt,name); |
1080 RequiredKeyword("end",in); | 1082 RequiredKeyword("end"); |
1081 frame = frame.parent; | 1083 frame = frame.parent; |
1082 return parser.success(fnDef); | 1084 return parser.success(fnDef); |
1083 } | 1085 } |
1084 | 1086 |
1085 private Expr VarArgs() throws ParseException { | 1087 private Expr VarArgs() throws ParseException { |
1407 private void RequiredMatch(String s) throws ParseException { | 1409 private void RequiredMatch(String s) throws ParseException { |
1408 if( !parser.match(s) ) | 1410 if( !parser.match(s) ) |
1409 throw parser.exception("'"+s+"' expected"); | 1411 throw parser.exception("'"+s+"' expected"); |
1410 } | 1412 } |
1411 | 1413 |
1412 private void RequiredKeyword(String keyword,In in) throws ParseException { | 1414 private void RequiredKeyword(String keyword) throws ParseException { |
1413 if( !Keyword(keyword) ) | 1415 if( !Keyword(keyword) ) |
1414 throw parser.exception("'"+keyword+"' expected"); | 1416 throw parser.exception("'"+keyword+"' expected"); |
1415 } | 1417 } |
1416 | 1418 |
1417 private boolean Keyword(String keyword) throws ParseException { | 1419 private boolean Keyword(String keyword) throws ParseException { |
1903 +"\n} " | 1905 +"\n} " |
1904 +"}\n" | 1906 +"}\n" |
1905 ; | 1907 ; |
1906 } | 1908 } |
1907 | 1909 |
1908 private Expr toFnExpStr(Stmts stmt,List<UpSym> upValueSymbols) { | 1910 private Expr toFnExp(Stmts stmt,List<UpSym> upValueSymbols,String name) { |
1909 stmt.addNewLines(); | 1911 stmt.addNewLines(); |
1910 if( !stmt.hasReturn ) | 1912 if( !stmt.hasReturn ) |
1911 stmt.add( "return LuanFunction.NOTHING; " ); | 1913 stmt.add( "return LuanFunction.NOTHING; " ); |
1912 Expr exp = new Expr(Val.SINGLE,false); | 1914 Expr exp = new Expr(Val.SINGLE,false); |
1913 exp.add( "" | 1915 exp.add( "" |
1914 +"new Closure("+upValueSymbols.size()+",java) { " | 1916 +"new Closure("+upValueSymbols.size()+",java) { " |
1915 +"{ " | 1917 +"{ " |
1916 + init(upValueSymbols) | 1918 + init(upValueSymbols) |
1917 +"} " | 1919 +"} " |
1918 +"@Override public Object doCall(LuanState luan,Object[] args) throws LuanException { " | 1920 +"@Override public Object doCall(LuanState luan,Object[] args) throws LuanException { " |
1921 ); | |
1922 if( name != null ) { | |
1923 exp.add( "" | |
1924 +"return _" + name + "(luan,args); " | |
1925 +"} " | |
1926 +"private Object _" + name + "(LuanState luan,Object[] args) throws LuanException { " | |
1927 ); | |
1928 } | |
1929 exp.add( "" | |
1919 +"Object t; " | 1930 +"Object t; " |
1920 +"Object[] a; " | 1931 +"Object[] a; " |
1921 ); | 1932 ); |
1922 exp.addAll( stmt ); | 1933 exp.addAll( stmt ); |
1923 exp.add( "" | 1934 exp.add( "" |