Mercurial Hosting > luan
comparison core/src/luan/impl/LuanParser.java @ 684:41f791e4206d
bug fixes
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 16 Apr 2016 21:42:19 -0600 |
parents | 0c334975d526 |
children | fc08c3b42010 |
comparison
equal
deleted
inserted
replaced
683:67dd1449e354 | 684:41f791e4206d |
---|---|
287 } | 287 } |
288 | 288 |
289 private Stmts RequiredBlock() throws ParseException { | 289 private Stmts RequiredBlock() throws ParseException { |
290 Stmts stmts = new Stmts(); | 290 Stmts stmts = new Stmts(); |
291 int stackStart = symbolsSize(); | 291 int stackStart = symbolsSize(); |
292 boolean isReturn = Stmt(stmts); | 292 do { |
293 while( !isReturn && (StmtSep() || TemplateSep(stmts)) ) { | |
294 Spaces(); | 293 Spaces(); |
295 stmts.addNewLines(); | 294 stmts.addNewLines(); |
296 isReturn = Stmt(stmts); | 295 Stmts stmt = Stmt(); |
297 } | 296 if( stmt != null ) { |
297 stmts.addAll(stmt); | |
298 stmts.hasReturn = stmt.hasReturn; | |
299 } | |
300 } while( !stmts.hasReturn && (StmtSep() || TemplateSep(stmts)) ); | |
301 Spaces(); | |
298 while( StmtSep() ) | 302 while( StmtSep() ) |
299 Spaces(); | 303 Spaces(); |
300 stmts.addNewLines(); | 304 stmts.addNewLines(); |
301 int stackEnd = symbolsSize(); | 305 int stackEnd = symbolsSize(); |
302 popSymbols( stackEnd - stackStart ); | 306 popSymbols( stackEnd - stackStart ); |
303 stmts.hasReturn = isReturn; | |
304 return stmts; | 307 return stmts; |
305 } | 308 } |
306 | 309 |
307 private boolean StmtSep() throws ParseException { | 310 private boolean StmtSep() throws ParseException { |
308 return parser.match( ';' ) || EndOfLine(); | 311 return parser.match( ';' ) || EndOfLine(); |
316 } | 319 } |
317 return false; | 320 return false; |
318 } | 321 } |
319 | 322 |
320 private boolean EndOfLine() { | 323 private boolean EndOfLine() { |
321 if( parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ) ) { | 324 if( MatchEndOfLine() ) { |
322 parser.sb().append('\n'); | 325 parser.sb().append('\n'); |
323 return true; | 326 return true; |
324 } else { | 327 } else { |
325 return false; | 328 return false; |
326 } | 329 } |
327 } | 330 } |
328 | 331 |
329 private boolean Stmt(Stmts stmts) throws ParseException { | 332 private boolean MatchEndOfLine() { |
333 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); | |
334 } | |
335 | |
336 private Stmts Stmt() throws ParseException { | |
330 Stmts stmt; | 337 Stmts stmt; |
331 if( (stmt=ReturnStmt()) != null ) { | 338 if( (stmt=ReturnStmt()) != null |
332 stmts.addAll(stmt); | 339 || (stmt=FunctionStmt()) != null |
333 return true; | |
334 } | |
335 if( (stmt=FunctionStmt()) != null | |
336 || (stmt=LocalStmt()) != null | 340 || (stmt=LocalStmt()) != null |
337 || (stmt=LocalFunctionStmt()) != null | 341 || (stmt=LocalFunctionStmt()) != null |
338 || (stmt=BreakStmt()) != null | 342 || (stmt=BreakStmt()) != null |
339 || (stmt=ForStmt()) != null | 343 || (stmt=ForStmt()) != null |
340 || (stmt=DoStmt()) != null | 344 || (stmt=DoStmt()) != null |
342 || (stmt=RepeatStmt()) != null | 346 || (stmt=RepeatStmt()) != null |
343 || (stmt=IfStmt()) != null | 347 || (stmt=IfStmt()) != null |
344 || (stmt=SetStmt()) != null | 348 || (stmt=SetStmt()) != null |
345 || (stmt=ExpressionsStmt()) != null | 349 || (stmt=ExpressionsStmt()) != null |
346 ) { | 350 ) { |
347 stmts.addAll(stmt); | 351 return stmt; |
348 } | 352 } |
349 return false; | 353 return null; |
350 } | 354 } |
351 | 355 |
352 private Expr indexExpStr(Expr exp1,Expr exp2) { | 356 private Expr indexExpStr(Expr exp1,Expr exp2) { |
353 Expr exp = new Expr(Val.SINGLE,false); | 357 Expr exp = new Expr(Val.SINGLE,false); |
354 exp.add( "luan.index(" ); | 358 exp.add( "luan.index(" ); |
425 if( exprs != null ) | 429 if( exprs != null ) |
426 stmt.addAll( exprs ); | 430 stmt.addAll( exprs ); |
427 else | 431 else |
428 stmt.add( "LuanFunction.NOTHING" ); | 432 stmt.add( "LuanFunction.NOTHING" ); |
429 stmt.add( "; " ); | 433 stmt.add( "; " ); |
434 stmt.hasReturn = true; | |
430 return parser.success( stmt ); | 435 return parser.success( stmt ); |
431 } | 436 } |
432 | 437 |
433 private Stmts FunctionStmt() throws ParseException { | 438 private Stmts FunctionStmt() throws ParseException { |
434 parser.begin(); | 439 parser.begin(); |
621 if( !Keyword("if") ) | 626 if( !Keyword("if") ) |
622 return parser.failure(null); | 627 return parser.failure(null); |
623 Stmts stmt = new Stmts(); | 628 Stmts stmt = new Stmts(); |
624 Expr cnd; | 629 Expr cnd; |
625 Stmts block; | 630 Stmts block; |
631 boolean hasReturn = true; | |
626 cnd = RequiredExpr(In.NOTHING).single(); | 632 cnd = RequiredExpr(In.NOTHING).single(); |
627 RequiredKeyword("then"); | 633 RequiredKeyword("then"); |
628 block = RequiredBlock(); | 634 block = RequiredBlock(); |
629 stmt.add( "if( Luan.checkBoolean(" ); | 635 stmt.add( "if( Luan.checkBoolean(" ); |
630 stmt.addAll( cnd ); | 636 stmt.addAll( cnd ); |
631 stmt.add( ") ) { " ); | 637 stmt.add( ") ) { " ); |
632 stmt.addAll( block ); | 638 stmt.addAll( block ); |
639 if( !block.hasReturn ) | |
640 hasReturn = false; | |
633 while( Keyword("elseif") ) { | 641 while( Keyword("elseif") ) { |
634 cnd = RequiredExpr(In.NOTHING).single(); | 642 cnd = RequiredExpr(In.NOTHING).single(); |
635 RequiredKeyword("then"); | 643 RequiredKeyword("then"); |
636 block = RequiredBlock(); | 644 block = RequiredBlock(); |
637 stmt.add( "} else if( Luan.checkBoolean(" ); | 645 stmt.add( "} else if( Luan.checkBoolean(" ); |
638 stmt.addAll( cnd ); | 646 stmt.addAll( cnd ); |
639 stmt.add( ") ) { " ); | 647 stmt.add( ") ) { " ); |
640 stmt.addAll( block ); | 648 stmt.addAll( block ); |
649 if( !block.hasReturn ) | |
650 hasReturn = false; | |
641 } | 651 } |
642 if( Keyword("else") ) { | 652 if( Keyword("else") ) { |
643 block = RequiredBlock(); | 653 block = RequiredBlock(); |
644 stmt.add( "} else { " ); | 654 stmt.add( "} else { " ); |
645 stmt.addAll( block ); | 655 stmt.addAll( block ); |
656 if( !block.hasReturn ) | |
657 hasReturn = false; | |
658 } else { | |
659 hasReturn = false; | |
646 } | 660 } |
647 RequiredKeyword("end"); | 661 RequiredKeyword("end"); |
648 stmt.add( "} " ); | 662 stmt.add( "} " ); |
663 stmt.hasReturn = hasReturn; | |
649 return parser.success( stmt ); | 664 return parser.success( stmt ); |
650 } | 665 } |
651 | 666 |
652 private Stmts SetStmt() throws ParseException { | 667 private Stmts SetStmt() throws ParseException { |
653 parser.begin(); | 668 parser.begin(); |
1486 if( s != null ) | 1501 if( s != null ) |
1487 return parser.success(constExpStr(s)); | 1502 return parser.success(constExpStr(s)); |
1488 return parser.failure(null); | 1503 return parser.failure(null); |
1489 } | 1504 } |
1490 | 1505 |
1506 private static int STR_LIM = 65000; | |
1507 | |
1491 private Expr constExpStr(String s) { | 1508 private Expr constExpStr(String s) { |
1492 int n = 0; | 1509 int n = 0; |
1493 int from = 0; | 1510 int from = 0; |
1494 while( (from = s.indexOf('\n',from) + 1) != 0 ) { | 1511 while( (from = s.indexOf('\n',from) + 1) != 0 ) { |
1495 n++; | 1512 n++; |
1500 .replace("\n","\\n") | 1517 .replace("\n","\\n") |
1501 .replace("\r","\\r") | 1518 .replace("\r","\\r") |
1502 .replace("\t","\\t") | 1519 .replace("\t","\\t") |
1503 .replace("\b","\\b") | 1520 .replace("\b","\\b") |
1504 ; | 1521 ; |
1505 s = "\"" + s + "\""; | 1522 if( s.length() > STR_LIM ) { |
1523 int len = s.length(); | |
1524 StringBuilder sb = new StringBuilder(); | |
1525 sb.append( "LuanImpl.strconcat(" ); | |
1526 int start = 0; | |
1527 while(true) { | |
1528 int end = start + STR_LIM; | |
1529 if( end >= len ) | |
1530 break; | |
1531 sb.append( "\"" ).append( s.substring(start,end) ).append( "\"," ); | |
1532 start = end; | |
1533 } | |
1534 sb.append( "\"" ).append( s.substring(start) ).append( "\")" ); | |
1535 s = sb.toString(); | |
1536 } else | |
1537 s = "\"" + s + "\""; | |
1506 while( n-- > 0 ) | 1538 while( n-- > 0 ) |
1507 s += "\n"; | 1539 s += "\n"; |
1508 Expr exp = new Expr(Val.SINGLE,false); | 1540 Expr exp = new Expr(Val.SINGLE,false); |
1509 exp.add( s ); | 1541 exp.add( s ); |
1510 return exp; | 1542 return exp; |
1650 int start = parser.currentIndex(); | 1682 int start = parser.currentIndex(); |
1651 while( parser.match('=') ); | 1683 while( parser.match('=') ); |
1652 int nEquals = parser.currentIndex() - start; | 1684 int nEquals = parser.currentIndex() - start; |
1653 if( !parser.match('[') ) | 1685 if( !parser.match('[') ) |
1654 return parser.failure(null); | 1686 return parser.failure(null); |
1655 EndOfLine(); | 1687 MatchEndOfLine(); |
1656 start = parser.currentIndex(); | 1688 start = parser.currentIndex(); |
1657 while( !LongBracketsEnd(nEquals) ) { | 1689 while( !LongBracketsEnd(nEquals) ) { |
1658 if( !parser.anyChar() ) | 1690 if( !parser.anyChar() ) |
1659 throw parser.exception("Unclosed long string"); | 1691 throw parser.exception("Unclosed long string"); |
1660 } | 1692 } |
1699 return parser.success((char)Integer.parseInt(parser.textFrom(start+1),16)); | 1731 return parser.success((char)Integer.parseInt(parser.textFrom(start+1),16)); |
1700 if( Digit() ) { | 1732 if( Digit() ) { |
1701 if( Digit() ) Digit(); // optional | 1733 if( Digit() ) Digit(); // optional |
1702 return parser.success((char)Integer.parseInt(parser.textFrom(start))); | 1734 return parser.success((char)Integer.parseInt(parser.textFrom(start))); |
1703 } | 1735 } |
1704 if( EndOfLine() ) { | 1736 if( MatchEndOfLine() ) { |
1705 parser.sb().setLength(parser.sb().length()-1); | |
1706 return parser.success('\n'); | 1737 return parser.success('\n'); |
1707 } | 1738 } |
1708 return parser.failure(null); | 1739 return parser.failure(null); |
1709 } | 1740 } |
1710 | 1741 |