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