comparison core/src/luan/impl/LuanParser.java @ 679:43522473599d

make java line numbers match
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 14 Apr 2016 15:19:25 -0600
parents 49f3d290bebd
children ecd436959855
comparison
equal deleted inserted replaced
678:49f3d290bebd 679:43522473599d
1 package luan.impl; 1 package luan.impl;
2 2
3 //import java.io.StringWriter;
4 //import java.io.PrintWriter;
3 import java.util.Set; 5 import java.util.Set;
4 import java.util.HashSet; 6 import java.util.HashSet;
5 import java.util.Arrays; 7 import java.util.Arrays;
6 import java.util.List; 8 import java.util.List;
7 import java.util.ArrayList; 9 import java.util.ArrayList;
34 Stmts stmt = new Stmts(); 36 Stmts stmt = new Stmts();
35 if( value==null ) { 37 if( value==null ) {
36 stmt.add( new Object() { 38 stmt.add( new Object() {
37 @Override public String toString() { 39 @Override public String toString() {
38 if( !isPointer ) 40 if( !isPointer )
39 return "Object " + javaName + ";\n"; 41 return "Object " + javaName + "; ";
40 else 42 else
41 return "final Pointer " + javaName + " = new Pointer();\n"; 43 return "final Pointer " + javaName + " = new Pointer(); ";
42 } 44 }
43 } ); 45 } );
44 } else { 46 } else {
45 if( value.valType != Val.SINGLE ) throw new RuntimeException(); 47 if( value.valType != Val.SINGLE ) throw new RuntimeException();
46 stmt.add( new Object() { 48 stmt.add( new Object() {
53 } ); 55 } );
54 stmt.addAll(value); 56 stmt.addAll(value);
55 stmt.add( new Object() { 57 stmt.add( new Object() {
56 @Override public String toString() { 58 @Override public String toString() {
57 if( !isPointer ) 59 if( !isPointer )
58 return ";\n"; 60 return "; ";
59 else 61 else
60 return ");\n"; 62 return "); ";
61 } 63 }
62 } ); 64 } );
63 } 65 }
64 return stmt; 66 return stmt;
65 } 67 }
88 this.i = i; 90 this.i = i;
89 this.value = value; 91 this.value = value;
90 } 92 }
91 93
92 String init() { 94 String init() {
93 return "upValues[" + i + "] = " + value + ";\n"; 95 return "upValues[" + i + "] = " + value + "; ";
94 } 96 }
95 97
96 @Override public Expr exp() { 98 @Override public Expr exp() {
97 Expr exp = new Expr(Val.SINGLE,false); 99 Expr exp = new Expr(Val.SINGLE,false);
98 exp.add( new Object() { 100 exp.add( new Object() {
162 } 164 }
163 165
164 } 166 }
165 167
166 private static class In { 168 private static class In {
167 static final In NOTHING = new In(false,false); 169 static final In NOTHING = new In(false);
168 170
169 final boolean parens;
170 final boolean template; 171 final boolean template;
171 172
172 private In(boolean parens,boolean template) { 173 private In(boolean template) {
173 this.parens = parens;
174 this.template = template; 174 this.template = template;
175 } 175 }
176 176
177 In parens() {
178 return parens ? this : new In(true,false);
179 }
180
181 In template() { 177 In template() {
182 return template ? this : new In(false,true); 178 return template ? this : new In(true);
183 } 179 }
184 } 180 }
185 181
186 // final LuanSource source; 182 // final LuanSource source;
187 private Frame frame; 183 private Frame frame;
188 private final Parser parser; 184 private final Parser parser;
189 private final Stmts top = new Stmts(); 185 private final Stmts top;
190 186
191 LuanParser(String sourceName,String sourceText) { 187 LuanParser(String sourceName,String sourceText) {
192 // this.source = source; 188 // this.source = source;
193 this.frame = new Frame(); 189 this.frame = new Frame();
194 this.parser = new Parser(sourceName,sourceText); 190 this.parser = new Parser(sourceName,sourceText);
191 this.top = new Stmts();
195 } 192 }
196 193
197 void addVar(String name) { 194 void addVar(String name) {
198 UpSym upSym = frame.addUpSym( "-ADDED-" ,"new Pointer()"); 195 UpSym upSym = frame.addUpSym( "-ADDED-" ,"new Pointer()");
199 if( name != null ) { 196 if( name != null ) {
200 LocalSym sym = frame.addLocalSym( name ); 197 LocalSym sym = frame.addLocalSym( name );
201 sym.isPointer = true; 198 sym.isPointer = true;
202 top.add( "final Pointer " + sym.javaName + " = upValues[" + upSym.i + "];\n" ); 199 top.add( "final Pointer " + sym.javaName + " = upValues[" + upSym.i + "]; " );
203 } 200 }
204 } 201 }
205 202
206 private int symbolsSize() { 203 private int symbolsSize() {
207 return frame.symbols.size(); 204 return frame.symbols.size();
250 private Expr newFnExpStr(Stmts stmt) { 247 private Expr newFnExpStr(Stmts stmt) {
251 return toFnExpStr( stmt, frame.upValueSymbols ); 248 return toFnExpStr( stmt, frame.upValueSymbols );
252 } 249 }
253 250
254 Class Expression() throws ParseException { 251 Class Expression() throws ParseException {
255 Spaces(In.NOTHING); 252 Spaces();
256 parser.begin(); 253 parser.begin();
257 Expr expr = ExprZ(In.NOTHING); 254 Expr expr = ExprZ(In.NOTHING);
258 if( expr != null && parser.endOfInput() ) { 255 if( expr != null && parser.endOfInput() ) {
259 top.add( "return " ); 256 top.add( "return " );
260 top.addAll( expr ); 257 top.addAll( expr );
261 top.add( ";\n" ); 258 top.add( "; " );
262 top.hasReturn = true; 259 top.hasReturn = true;
263 return parser.success(newFnClass(top)); 260 return parser.success(newFnClass(top));
264 } 261 }
265 return parser.failure(null); 262 return parser.failure(null);
266 } 263 }
274 GetRequiredModule(); 271 GetRequiredModule();
275 return toFnString( top, frame.upValueSymbols ); 272 return toFnString( top, frame.upValueSymbols );
276 } 273 }
277 274
278 void GetRequiredModule() throws ParseException { 275 void GetRequiredModule() throws ParseException {
279 Spaces(In.NOTHING); 276 Spaces();
280 parser.begin(); 277 parser.begin();
281 frame.isVarArg = true; 278 frame.isVarArg = true;
282 top.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);\n" ); 279 top.add( "final Object[] varArgs = LuanImpl.varArgs(args,0); " );
283 Stmts block = RequiredBlock(); 280 Stmts block = RequiredBlock();
284 top.addAll( block ); 281 top.addAll( block );
285 top.hasReturn = block.hasReturn; 282 top.hasReturn = block.hasReturn;
286 if( !parser.endOfInput() ) 283 if( !parser.endOfInput() )
287 throw parser.exception(); 284 throw parser.exception();
290 287
291 private Stmts RequiredBlock() throws ParseException { 288 private Stmts RequiredBlock() throws ParseException {
292 Stmts stmts = new Stmts(); 289 Stmts stmts = new Stmts();
293 int stackStart = symbolsSize(); 290 int stackStart = symbolsSize();
294 boolean isReturn = Stmt(stmts); 291 boolean isReturn = Stmt(stmts);
295 while( !isReturn && StmtSep(stmts) ) { 292 while( !isReturn && (StmtSep() || TemplateSep(stmts)) ) {
296 Spaces(In.NOTHING); 293 Spaces();
294 stmts.addNewLines();
297 isReturn = Stmt(stmts); 295 isReturn = Stmt(stmts);
298 } 296 }
299 while( StmtSep(null) ) 297 while( StmtSep() )
300 Spaces(In.NOTHING); 298 Spaces();
299 stmts.addNewLines();
301 int stackEnd = symbolsSize(); 300 int stackEnd = symbolsSize();
302 popSymbols( stackEnd - stackStart ); 301 popSymbols( stackEnd - stackStart );
303 stmts.hasReturn = isReturn; 302 stmts.hasReturn = isReturn;
304 return stmts; 303 return stmts;
305 } 304 }
306 305
307 private boolean StmtSep(Stmts stmts) throws ParseException { 306 private boolean StmtSep() throws ParseException {
308 parser.begin(); 307 return parser.match( ';' ) || EndOfLine();
309 if( parser.match( ';' ) ) 308 }
310 return parser.success(); 309
311 if( EndOfLine() ) 310 private boolean TemplateSep(Stmts stmts) throws ParseException {
312 return parser.success(); 311 Stmts stmt = TemplateStmt();
313 if( stmts != null ) { 312 if( stmt != null ) {
314 // parser.rollback(); 313 stmts.addAll(stmt);
315 Stmts stmt = TemplateStmt(); 314 return true;
316 if( stmt != null ) { 315 }
317 stmts.addAll(stmt); 316 return false;
318 return parser.success();
319 }
320 }
321 return parser.failure();
322 } 317 }
323 318
324 private boolean EndOfLine() { 319 private boolean EndOfLine() {
325 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); 320 if( parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ) ) {
321 parser.sb().append('\n');
322 return true;
323 } else {
324 return false;
325 }
326 } 326 }
327 327
328 private boolean Stmt(Stmts stmts) throws ParseException { 328 private boolean Stmt(Stmts stmts) throws ParseException {
329 Stmts stmt; 329 Stmts stmt;
330 if( (stmt=ReturnStmt()) != null ) { 330 if( (stmt=ReturnStmt()) != null ) {
377 Expr stdoutExp = indexExpStr( requireCall.single(), constExpStr("stdout") ); 377 Expr stdoutExp = indexExpStr( requireCall.single(), constExpStr("stdout") );
378 Expr writeExp = indexExpStr( stdoutExp, constExpStr("write") ); 378 Expr writeExp = indexExpStr( stdoutExp, constExpStr("write") );
379 Expr writeCall = callExpStr( writeExp, exprs ); 379 Expr writeCall = callExpStr( writeExp, exprs );
380 Stmts stmt = new Stmts(); 380 Stmts stmt = new Stmts();
381 stmt.addAll( writeCall ); 381 stmt.addAll( writeCall );
382 stmt.add( ";\n" ); 382 stmt.add( "; " );
383 return stmt; 383 return stmt;
384 } 384 }
385 385
386 private Expr TemplateExpressions(In in) throws ParseException { 386 private Expr TemplateExpressions(In in) throws ParseException {
387 if( in.template ) 387 if( in.template )
392 EndOfLine(); 392 EndOfLine();
393 In inTemplate = in.template(); 393 In inTemplate = in.template();
394 List<Expr> builder = new ArrayList<Expr>(); 394 List<Expr> builder = new ArrayList<Expr>();
395 while(true) { 395 while(true) {
396 if( parser.match( "<%=" ) ) { 396 if( parser.match( "<%=" ) ) {
397 Spaces(inTemplate); 397 Spaces();
398 builder.add( RequiredExpr(inTemplate) ); 398 builder.add( RequiredExpr(inTemplate) );
399 RequiredMatch( "%>" ); 399 RequiredMatch( "%>" );
400 } else if( parser.match( "<%" ) ) { 400 } else if( parser.match( "<%" ) ) {
401 Spaces(inTemplate); 401 Spaces();
402 return parser.success(expString(builder)); 402 return parser.success(expString(builder));
403 } else { 403 } else {
404 int i = parser.currentIndex(); 404 int i = parser.currentIndex();
405 do { 405 do {
406 if( parser.match( "%>" ) ) 406 if( parser.match( "%>" ) )
414 } 414 }
415 } 415 }
416 416
417 private Stmts ReturnStmt() throws ParseException { 417 private Stmts ReturnStmt() throws ParseException {
418 parser.begin(); 418 parser.begin();
419 if( !Keyword("return",In.NOTHING) ) 419 if( !Keyword("return") )
420 return parser.failure(null); 420 return parser.failure(null);
421 Expr exprs = ExpStringList(In.NOTHING); 421 Expr exprs = ExpStringList(In.NOTHING);
422 Stmts stmt = new Stmts(); 422 Stmts stmt = new Stmts();
423 stmt.add( "return " ); 423 stmt.add( "return " );
424 if( exprs != null ) 424 if( exprs != null )
425 stmt.addAll( exprs ); 425 stmt.addAll( exprs );
426 else 426 else
427 stmt.add( "LuanFunction.NOTHING" ); 427 stmt.add( "LuanFunction.NOTHING" );
428 stmt.add( ";\n" ); 428 stmt.add( "; " );
429 return parser.success( stmt ); 429 return parser.success( stmt );
430 } 430 }
431 431
432 private Stmts FunctionStmt() throws ParseException { 432 private Stmts FunctionStmt() throws ParseException {
433 parser.begin(); 433 parser.begin();
434 if( !Keyword("function",In.NOTHING) ) 434 if( !Keyword("function") )
435 return parser.failure(null); 435 return parser.failure(null);
436 436
437 parser.currentIndex(); 437 parser.currentIndex();
438 Var var = nameVar(RequiredName(In.NOTHING)); 438 Var var = nameVar(RequiredName());
439 while( parser.match( '.' ) ) { 439 while( parser.match( '.' ) ) {
440 Spaces(In.NOTHING); 440 Spaces();
441 Expr exp = NameExpr(In.NOTHING); 441 Expr exp = NameExpr();
442 if( exp==null ) 442 if( exp==null )
443 return parser.failure(null); 443 return parser.failure(null);
444 var = indexVar( var.exp(), exp ); 444 var = indexVar( var.exp(), exp );
445 } 445 }
446 446
448 return parser.success( var.set(fnDef) ); 448 return parser.success( var.set(fnDef) );
449 } 449 }
450 450
451 private Stmts LocalFunctionStmt() throws ParseException { 451 private Stmts LocalFunctionStmt() throws ParseException {
452 parser.begin(); 452 parser.begin();
453 if( !(Keyword("local",In.NOTHING) && Keyword("function",In.NOTHING)) ) 453 if( !(Keyword("local") && Keyword("function")) )
454 return parser.failure(null); 454 return parser.failure(null);
455 Stmts stmt = new Stmts(); 455 Stmts stmt = new Stmts();
456 String name = RequiredName(In.NOTHING); 456 String name = RequiredName();
457 stmt.addAll( addSymbol(name,null) ); 457 stmt.addAll( addSymbol(name,null) );
458 Expr fnDef = RequiredFunction(In.NOTHING); 458 Expr fnDef = RequiredFunction(In.NOTHING);
459 stmt.addAll( nameVar(name).set(fnDef) ); 459 stmt.addAll( nameVar(name).set(fnDef) );
460 return parser.success( stmt ); 460 return parser.success( stmt );
461 } 461 }
462 462
463 private Stmts BreakStmt() throws ParseException { 463 private Stmts BreakStmt() throws ParseException {
464 parser.begin(); 464 parser.begin();
465 if( !Keyword("break",In.NOTHING) ) 465 if( !Keyword("break") )
466 return parser.failure(null); 466 return parser.failure(null);
467 if( frame.loops <= 0 ) 467 if( frame.loops <= 0 )
468 throw parser.exception("'break' outside of loop"); 468 throw parser.exception("'break' outside of loop");
469 Stmts stmt = new Stmts(); 469 Stmts stmt = new Stmts();
470 stmt.add( "break;\n" ); 470 stmt.add( "break; " );
471 return parser.success( stmt ); 471 return parser.success( stmt );
472 } 472 }
473 473
474 int forCounter = 0; 474 int forCounter = 0;
475 475
476 private Stmts ForStmt() throws ParseException { 476 private Stmts ForStmt() throws ParseException {
477 parser.begin(); 477 parser.begin();
478 int stackStart = symbolsSize(); 478 int stackStart = symbolsSize();
479 if( !Keyword("for",In.NOTHING) ) 479 if( !Keyword("for") )
480 return parser.failure(null); 480 return parser.failure(null);
481 List<String> names = RequiredNameList(In.NOTHING); 481 List<String> names = RequiredNameList();
482 if( !Keyword("in",In.NOTHING) ) 482 if( !Keyword("in") )
483 return parser.failure(null); 483 return parser.failure(null);
484 Expr expr = RequiredExpr(In.NOTHING).single(); 484 Expr expr = RequiredExpr(In.NOTHING).single();
485 RequiredKeyword("do",In.NOTHING); 485 RequiredKeyword("do",In.NOTHING);
486 486
487 String fnVar = "fn"+ ++forCounter; 487 String fnVar = "fn"+ ++forCounter;
490 Stmts stmt = new Stmts(); 490 Stmts stmt = new Stmts();
491 stmt.add( "" 491 stmt.add( ""
492 +"LuanFunction "+fnVar+" = Luan.checkFunction(" 492 +"LuanFunction "+fnVar+" = Luan.checkFunction("
493 ); 493 );
494 stmt.addAll( expr ); 494 stmt.addAll( expr );
495 stmt.add( ");\n" ); 495 stmt.add( "); " );
496 stmt.add( "while(true) {\n" ); 496 stmt.add( "while(true) { " );
497 stmt.addAll( makeLocalSetStmt(names,fnExp) ); 497 stmt.addAll( makeLocalSetStmt(names,fnExp) );
498 stmt.add( "if( " ); 498 stmt.add( "if( " );
499 stmt.addAll( nameVar(names.get(0)).exp() ); 499 stmt.addAll( nameVar(names.get(0)).exp() );
500 stmt.add( "==null ) break;\n" ); 500 stmt.add( "==null ) break; " );
501 Stmts loop = RequiredLoopBlock(); 501 Stmts loop = RequiredLoopBlock();
502 RequiredKeyword("end",In.NOTHING); 502 RequiredKeyword("end",In.NOTHING);
503 stmt.addAll( loop ); 503 stmt.addAll( loop );
504 stmt.add( "}\n" ); 504 stmt.add( "} " );
505 popSymbols( symbolsSize() - stackStart ); 505 popSymbols( symbolsSize() - stackStart );
506 return parser.success(stmt); 506 return parser.success(stmt);
507 } 507 }
508 508
509 private Stmts DoStmt() throws ParseException { 509 private Stmts DoStmt() throws ParseException {
510 parser.begin(); 510 parser.begin();
511 if( !Keyword("do",In.NOTHING) ) 511 if( !Keyword("do") )
512 return parser.failure(null); 512 return parser.failure(null);
513 Stmts stmt = RequiredBlock(); 513 Stmts stmt = RequiredBlock();
514 RequiredKeyword("end",In.NOTHING); 514 RequiredKeyword("end",In.NOTHING);
515 return parser.success(stmt); 515 return parser.success(stmt);
516 } 516 }
517 517
518 private Stmts LocalStmt() throws ParseException { 518 private Stmts LocalStmt() throws ParseException {
519 parser.begin(); 519 parser.begin();
520 if( !Keyword("local",In.NOTHING) ) 520 if( !Keyword("local") )
521 return parser.failure(null); 521 return parser.failure(null);
522 List<String> names = NameList(In.NOTHING); 522 List<String> names = NameList();
523 if( names==null ) { 523 if( names==null ) {
524 if( Keyword("function",In.NOTHING) ) 524 if( Keyword("function") )
525 return parser.failure(null); // handled later 525 return parser.failure(null); // handled later
526 throw parser.exception("Invalid local statement"); 526 throw parser.exception("Invalid local statement");
527 } 527 }
528 Stmts stmt = new Stmts(); 528 Stmts stmt = new Stmts();
529 if( parser.match( '=' ) ) { 529 if( parser.match( '=' ) ) {
530 Spaces(In.NOTHING); 530 Spaces();
531 Expr values = ExpStringList(In.NOTHING); 531 Expr values = ExpStringList(In.NOTHING);
532 if( values==null ) 532 if( values==null )
533 throw parser.exception("Expressions expected"); 533 throw parser.exception("Expressions expected");
534 stmt.addAll( makeLocalSetStmt(names,values) ); 534 stmt.addAll( makeLocalSetStmt(names,values) );
535 } else { 535 } else {
540 } 540 }
541 } 541 }
542 return parser.success(stmt); 542 return parser.success(stmt);
543 } 543 }
544 544
545 private List<String> RequiredNameList(In in) throws ParseException { 545 private List<String> RequiredNameList() throws ParseException {
546 parser.begin(); 546 parser.begin();
547 List<String> names = NameList(in); 547 List<String> names = NameList();
548 if( names==null ) 548 if( names==null )
549 throw parser.exception("Name expected"); 549 throw parser.exception("Name expected");
550 return parser.success(names); 550 return parser.success(names);
551 } 551 }
552 552
553 private List<String> NameList(In in) throws ParseException { 553 private List<String> NameList() throws ParseException {
554 String name = Name(in); 554 String name = Name();
555 if( name==null ) 555 if( name==null )
556 return null; 556 return null;
557 List<String> names = new ArrayList<String>(); 557 List<String> names = new ArrayList<String>();
558 names.add(name); 558 names.add(name);
559 while( (name=anotherName(in)) != null ) { 559 while( (name=anotherName()) != null ) {
560 names.add(name); 560 names.add(name);
561 } 561 }
562 return names; 562 return names;
563 } 563 }
564 564
565 private String anotherName(In in) throws ParseException { 565 private String anotherName() throws ParseException {
566 parser.begin(); 566 parser.begin();
567 if( !parser.match( ',' ) ) 567 if( !parser.match( ',' ) )
568 return parser.failure(null); 568 return parser.failure(null);
569 Spaces(in); 569 Spaces();
570 String name = Name(in); 570 String name = Name();
571 if( name==null ) 571 if( name==null )
572 return parser.failure(null); 572 return parser.failure(null);
573 return parser.success(name); 573 return parser.success(name);
574 } 574 }
575 575
576 private Stmts WhileStmt() throws ParseException { 576 private Stmts WhileStmt() throws ParseException {
577 parser.begin(); 577 parser.begin();
578 if( !Keyword("while",In.NOTHING) ) 578 if( !Keyword("while") )
579 return parser.failure(null); 579 return parser.failure(null);
580 Expr cnd = RequiredExpr(In.NOTHING).single(); 580 Expr cnd = RequiredExpr(In.NOTHING).single();
581 RequiredKeyword("do",In.NOTHING); 581 RequiredKeyword("do",In.NOTHING);
582 Stmts loop = RequiredLoopBlock(); 582 Stmts loop = RequiredLoopBlock();
583 RequiredKeyword("end",In.NOTHING); 583 RequiredKeyword("end",In.NOTHING);
584 Stmts stmt = new Stmts(); 584 Stmts stmt = new Stmts();
585 stmt.add( "while( Luan.checkBoolean(" ); 585 stmt.add( "while( Luan.checkBoolean(" );
586 stmt.addAll( cnd ); 586 stmt.addAll( cnd );
587 stmt.add( ") ) {\n" ); 587 stmt.add( ") ) { " );
588 stmt.addAll( loop ); 588 stmt.addAll( loop );
589 stmt.add( "}\n" ); 589 stmt.add( "} " );
590 return parser.success( stmt ); 590 return parser.success( stmt );
591 } 591 }
592 592
593 private Stmts RepeatStmt() throws ParseException { 593 private Stmts RepeatStmt() throws ParseException {
594 parser.begin(); 594 parser.begin();
595 if( !Keyword("repeat",In.NOTHING) ) 595 if( !Keyword("repeat") )
596 return parser.failure(null); 596 return parser.failure(null);
597 Stmts loop =RequiredLoopBlock(); 597 Stmts loop =RequiredLoopBlock();
598 RequiredKeyword("until",In.NOTHING); 598 RequiredKeyword("until",In.NOTHING);
599 Expr cnd = RequiredExpr(In.NOTHING).single(); 599 Expr cnd = RequiredExpr(In.NOTHING).single();
600 Stmts stmt = new Stmts(); 600 Stmts stmt = new Stmts();
601 stmt.add( "do {\n" ); 601 stmt.add( "do { " );
602 stmt.addAll( loop ); 602 stmt.addAll( loop );
603 stmt.add( "} while( !Luan.checkBoolean(" ); 603 stmt.add( "} while( !Luan.checkBoolean(" );
604 stmt.addAll( cnd ); 604 stmt.addAll( cnd );
605 stmt.add( ") );\n" ); 605 stmt.add( ") ); " );
606 return parser.success( stmt ); 606 return parser.success( stmt );
607 } 607 }
608 608
609 private Stmts RequiredLoopBlock() throws ParseException { 609 private Stmts RequiredLoopBlock() throws ParseException {
610 incLoops(); 610 incLoops();
613 return stmt; 613 return stmt;
614 } 614 }
615 615
616 private Stmts IfStmt() throws ParseException { 616 private Stmts IfStmt() throws ParseException {
617 parser.begin(); 617 parser.begin();
618 if( !Keyword("if",In.NOTHING) ) 618 if( !Keyword("if") )
619 return parser.failure(null); 619 return parser.failure(null);
620 Stmts stmt = new Stmts(); 620 Stmts stmt = new Stmts();
621 Expr cnd; 621 Expr cnd;
622 Stmts block; 622 Stmts block;
623 cnd = RequiredExpr(In.NOTHING).single(); 623 cnd = RequiredExpr(In.NOTHING).single();
624 RequiredKeyword("then",In.NOTHING); 624 RequiredKeyword("then",In.NOTHING);
625 block = RequiredBlock(); 625 block = RequiredBlock();
626 stmt.add( "if( Luan.checkBoolean(" ); 626 stmt.add( "if( Luan.checkBoolean(" );
627 stmt.addAll( cnd ); 627 stmt.addAll( cnd );
628 stmt.add( ") ) {\n" ); 628 stmt.add( ") ) { " );
629 stmt.addAll( block ); 629 stmt.addAll( block );
630 while( Keyword("elseif",In.NOTHING) ) { 630 while( Keyword("elseif") ) {
631 cnd = RequiredExpr(In.NOTHING).single(); 631 cnd = RequiredExpr(In.NOTHING).single();
632 RequiredKeyword("then",In.NOTHING); 632 RequiredKeyword("then",In.NOTHING);
633 block = RequiredBlock(); 633 block = RequiredBlock();
634 stmt.add( "} else if( Luan.checkBoolean(" ); 634 stmt.add( "} else if( Luan.checkBoolean(" );
635 stmt.addAll( cnd ); 635 stmt.addAll( cnd );
636 stmt.add( ") ) {\n" ); 636 stmt.add( ") ) { " );
637 stmt.addAll( block ); 637 stmt.addAll( block );
638 } 638 }
639 if( Keyword("else",In.NOTHING) ) { 639 if( Keyword("else") ) {
640 block = RequiredBlock(); 640 block = RequiredBlock();
641 stmt.add( "} else {\n" ); 641 stmt.add( "} else { " );
642 stmt.addAll( block ); 642 stmt.addAll( block );
643 } 643 }
644 RequiredKeyword("end",In.NOTHING); 644 RequiredKeyword("end",In.NOTHING);
645 stmt.add( "}\n" ); 645 stmt.add( "} " );
646 return parser.success( stmt ); 646 return parser.success( stmt );
647 } 647 }
648 648
649 private Stmts SetStmt() throws ParseException { 649 private Stmts SetStmt() throws ParseException {
650 parser.begin(); 650 parser.begin();
652 Var v = SettableVar(); 652 Var v = SettableVar();
653 if( v == null ) 653 if( v == null )
654 return parser.failure(null); 654 return parser.failure(null);
655 vars.add(v); 655 vars.add(v);
656 while( parser.match( ',' ) ) { 656 while( parser.match( ',' ) ) {
657 Spaces(In.NOTHING); 657 Spaces();
658 v = SettableVar(); 658 v = SettableVar();
659 if( v == null ) 659 if( v == null )
660 return parser.failure(null); 660 return parser.failure(null);
661 vars.add(v); 661 vars.add(v);
662 } 662 }
663 if( !parser.match( '=' ) ) 663 if( !parser.match( '=' ) )
664 return parser.failure(null); 664 return parser.failure(null);
665 Spaces(In.NOTHING); 665 Spaces();
666 Expr values = ExpStringList(In.NOTHING); 666 Expr values = ExpStringList(In.NOTHING);
667 if( values==null ) 667 if( values==null )
668 // throw parser.exception("Expressions expected"); 668 // throw parser.exception("Expressions expected");
669 return parser.failure(null); 669 return parser.failure(null);
670 return parser.success( makeSetStmt(vars,values) ); 670 return parser.success( makeSetStmt(vars,values) );
676 return vars.get(0).set(values); 676 return vars.get(0).set(values);
677 Stmts stmt = new Stmts(); 677 Stmts stmt = new Stmts();
678 String varName = values.valType==Val.ARRAY ? "a" : "t"; 678 String varName = values.valType==Val.ARRAY ? "a" : "t";
679 stmt.add( varName + " = " ); 679 stmt.add( varName + " = " );
680 stmt.addAll( values ); 680 stmt.addAll( values );
681 stmt.add( ";\n" ); 681 stmt.add( "; " );
682 Expr t = new Expr(values.valType,false); 682 Expr t = new Expr(values.valType,false);
683 t.add( varName ); 683 t.add( varName );
684 t = t.single(); 684 t = t.single();
685 stmt.addAll( vars.get(0).set(t) ); 685 stmt.addAll( vars.get(0).set(t) );
686 for( int i=1; i<n; i++ ) { 686 for( int i=1; i<n; i++ ) {
697 return addSymbol(names.get(0),values.single()); 697 return addSymbol(names.get(0),values.single());
698 Stmts stmt = new Stmts(); 698 Stmts stmt = new Stmts();
699 String varName = values.valType==Val.ARRAY ? "a" : "t"; 699 String varName = values.valType==Val.ARRAY ? "a" : "t";
700 stmt.add( varName + " = " ); 700 stmt.add( varName + " = " );
701 stmt.addAll( values ); 701 stmt.addAll( values );
702 stmt.add( ";\n" ); 702 stmt.add( "; " );
703 Expr t = new Expr(values.valType,false); 703 Expr t = new Expr(values.valType,false);
704 t.add( varName ); 704 t.add( varName );
705 t = t.single(); 705 t = t.single();
706 stmt.addAll( addSymbol(names.get(0),t) ); 706 stmt.addAll( addSymbol(names.get(0),t) );
707 for( int i=1; i<n; i++ ) { 707 for( int i=1; i<n; i++ ) {
722 stmt.addAll( exp ); 722 stmt.addAll( exp );
723 stmt.add( ")" ); 723 stmt.add( ")" );
724 } else { 724 } else {
725 stmt.addAll( exp ); 725 stmt.addAll( exp );
726 } 726 }
727 stmt.add( ";\n" ); 727 stmt.add( "; " );
728 return parser.success( stmt ); 728 return parser.success( stmt );
729 } 729 }
730 return parser.failure(null); 730 return parser.failure(null);
731 } 731 }
732 732
750 private Expr OrExpr(In in) throws ParseException { 750 private Expr OrExpr(In in) throws ParseException {
751 parser.begin(); 751 parser.begin();
752 Expr exp = AndExpr(in); 752 Expr exp = AndExpr(in);
753 if( exp==null ) 753 if( exp==null )
754 return parser.failure(null); 754 return parser.failure(null);
755 while( Keyword("or",in) ) { 755 while( Keyword("or") ) {
756 exp = exp.single(); 756 exp = exp.single();
757 Expr exp2 = required(RelExpr(in)).single(); 757 Expr exp2 = required(RelExpr(in)).single();
758 Expr newExp = new Expr(Val.SINGLE,true); 758 Expr newExp = new Expr(Val.SINGLE,true);
759 newExp.add( "(LuanImpl.cnd(t = " ); 759 newExp.add( "(LuanImpl.cnd(t = " );
760 newExp.addAll( exp ); 760 newExp.addAll( exp );
769 private Expr AndExpr(In in) throws ParseException { 769 private Expr AndExpr(In in) throws ParseException {
770 parser.begin(); 770 parser.begin();
771 Expr exp = RelExpr(in); 771 Expr exp = RelExpr(in);
772 if( exp==null ) 772 if( exp==null )
773 return parser.failure(null); 773 return parser.failure(null);
774 while( Keyword("and",in) ) { 774 while( Keyword("and") ) {
775 exp = exp.single(); 775 exp = exp.single();
776 Expr exp2 = required(RelExpr(in)).single(); 776 Expr exp2 = required(RelExpr(in)).single();
777 Expr newExp = new Expr(Val.SINGLE,true); 777 Expr newExp = new Expr(Val.SINGLE,true);
778 newExp.add( "(LuanImpl.cnd(t = " ); 778 newExp.add( "(LuanImpl.cnd(t = " );
779 newExp.addAll( exp ); 779 newExp.addAll( exp );
790 Expr exp = ConcatExpr(in); 790 Expr exp = ConcatExpr(in);
791 if( exp==null ) 791 if( exp==null )
792 return parser.failure(null); 792 return parser.failure(null);
793 while(true) { 793 while(true) {
794 if( parser.match("==") ) { 794 if( parser.match("==") ) {
795 Spaces(in); 795 Spaces();
796 exp = exp.single(); 796 exp = exp.single();
797 Expr exp2 = required(ConcatExpr(in)).single(); 797 Expr exp2 = required(ConcatExpr(in)).single();
798 Expr newExp = new Expr(Val.SINGLE,false); 798 Expr newExp = new Expr(Val.SINGLE,false);
799 newExp.add( "LuanImpl.eq(luan," ); 799 newExp.add( "LuanImpl.eq(luan," );
800 newExp.addAll( exp ); 800 newExp.addAll( exp );
801 newExp.add( "," ); 801 newExp.add( "," );
802 newExp.addAll( exp2 ); 802 newExp.addAll( exp2 );
803 newExp.add( ")" ); 803 newExp.add( ")" );
804 exp = newExp; 804 exp = newExp;
805 } else if( parser.match("~=") ) { 805 } else if( parser.match("~=") ) {
806 Spaces(in); 806 Spaces();
807 exp = exp.single(); 807 exp = exp.single();
808 Expr exp2 = required(ConcatExpr(in)).single(); 808 Expr exp2 = required(ConcatExpr(in)).single();
809 Expr newExp = new Expr(Val.SINGLE,false); 809 Expr newExp = new Expr(Val.SINGLE,false);
810 newExp.add( "!LuanImpl.eq(luan," ); 810 newExp.add( "!LuanImpl.eq(luan," );
811 newExp.addAll( exp ); 811 newExp.addAll( exp );
812 newExp.add( "," ); 812 newExp.add( "," );
813 newExp.addAll( exp2 ); 813 newExp.addAll( exp2 );
814 newExp.add( ")" ); 814 newExp.add( ")" );
815 exp = newExp; 815 exp = newExp;
816 } else if( parser.match("<=") ) { 816 } else if( parser.match("<=") ) {
817 Spaces(in); 817 Spaces();
818 exp = exp.single(); 818 exp = exp.single();
819 Expr exp2 = required(ConcatExpr(in)).single(); 819 Expr exp2 = required(ConcatExpr(in)).single();
820 Expr newExp = new Expr(Val.SINGLE,false); 820 Expr newExp = new Expr(Val.SINGLE,false);
821 newExp.add( "LuanImpl.le(luan," ); 821 newExp.add( "LuanImpl.le(luan," );
822 newExp.addAll( exp ); 822 newExp.addAll( exp );
823 newExp.add( "," ); 823 newExp.add( "," );
824 newExp.addAll( exp2 ); 824 newExp.addAll( exp2 );
825 newExp.add( ")" ); 825 newExp.add( ")" );
826 exp = newExp; 826 exp = newExp;
827 } else if( parser.match(">=") ) { 827 } else if( parser.match(">=") ) {
828 Spaces(in); 828 Spaces();
829 exp = exp.single(); 829 exp = exp.single();
830 Expr exp2 = required(ConcatExpr(in)).single(); 830 Expr exp2 = required(ConcatExpr(in)).single();
831 Expr newExp = new Expr(Val.SINGLE,false); 831 Expr newExp = new Expr(Val.SINGLE,false);
832 newExp.add( "LuanImpl.le(luan," ); 832 newExp.add( "LuanImpl.le(luan," );
833 newExp.addAll( exp2 ); 833 newExp.addAll( exp2 );
834 newExp.add( "," ); 834 newExp.add( "," );
835 newExp.addAll( exp ); 835 newExp.addAll( exp );
836 newExp.add( ")" ); 836 newExp.add( ")" );
837 exp = newExp; 837 exp = newExp;
838 } else if( parser.match("<") ) { 838 } else if( parser.match("<") ) {
839 Spaces(in); 839 Spaces();
840 exp = exp.single(); 840 exp = exp.single();
841 Expr exp2 = required(ConcatExpr(in)).single(); 841 Expr exp2 = required(ConcatExpr(in)).single();
842 Expr newExp = new Expr(Val.SINGLE,false); 842 Expr newExp = new Expr(Val.SINGLE,false);
843 newExp.add( "LuanImpl.lt(luan," ); 843 newExp.add( "LuanImpl.lt(luan," );
844 newExp.addAll( exp ); 844 newExp.addAll( exp );
845 newExp.add( "," ); 845 newExp.add( "," );
846 newExp.addAll( exp2 ); 846 newExp.addAll( exp2 );
847 newExp.add( ")" ); 847 newExp.add( ")" );
848 exp = newExp; 848 exp = newExp;
849 } else if( parser.match(">") ) { 849 } else if( parser.match(">") ) {
850 Spaces(in); 850 Spaces();
851 exp = exp.single(); 851 exp = exp.single();
852 Expr exp2 = required(ConcatExpr(in)).single(); 852 Expr exp2 = required(ConcatExpr(in)).single();
853 Expr newExp = new Expr(Val.SINGLE,false); 853 Expr newExp = new Expr(Val.SINGLE,false);
854 newExp.add( "LuanImpl.lt(luan," ); 854 newExp.add( "LuanImpl.lt(luan," );
855 newExp.addAll( exp2 ); 855 newExp.addAll( exp2 );
867 parser.begin(); 867 parser.begin();
868 Expr exp = SumExpr(in); 868 Expr exp = SumExpr(in);
869 if( exp==null ) 869 if( exp==null )
870 return parser.failure(null); 870 return parser.failure(null);
871 if( parser.match("..") ) { 871 if( parser.match("..") ) {
872 Spaces(in); 872 Spaces();
873 exp = exp.single(); 873 exp = exp.single();
874 Expr exp2 = required(ConcatExpr(in)).single(); 874 Expr exp2 = required(ConcatExpr(in)).single();
875 Expr newExp = new Expr(Val.SINGLE,false); 875 Expr newExp = new Expr(Val.SINGLE,false);
876 newExp.add( "LuanImpl.concat(luan," ); 876 newExp.add( "LuanImpl.concat(luan," );
877 newExp.addAll( exp ); 877 newExp.addAll( exp );
888 Expr exp = TermExpr(in); 888 Expr exp = TermExpr(in);
889 if( exp==null ) 889 if( exp==null )
890 return parser.failure(null); 890 return parser.failure(null);
891 while(true) { 891 while(true) {
892 if( parser.match('+') ) { 892 if( parser.match('+') ) {
893 Spaces(in); 893 Spaces();
894 exp = exp.single(); 894 exp = exp.single();
895 Expr exp2 = required(TermExpr(in)).single(); 895 Expr exp2 = required(TermExpr(in)).single();
896 Expr newExp = new Expr(Val.SINGLE,false); 896 Expr newExp = new Expr(Val.SINGLE,false);
897 newExp.add( "LuanImpl.add(luan," ); 897 newExp.add( "LuanImpl.add(luan," );
898 newExp.addAll( exp ); 898 newExp.addAll( exp );
899 newExp.add( "," ); 899 newExp.add( "," );
900 newExp.addAll( exp2 ); 900 newExp.addAll( exp2 );
901 newExp.add( ")" ); 901 newExp.add( ")" );
902 exp = newExp; 902 exp = newExp;
903 } else if( Minus() ) { 903 } else if( Minus() ) {
904 Spaces(in); 904 Spaces();
905 exp = exp.single(); 905 exp = exp.single();
906 Expr exp2 = required(TermExpr(in)).single(); 906 Expr exp2 = required(TermExpr(in)).single();
907 Expr newExp = new Expr(Val.SINGLE,false); 907 Expr newExp = new Expr(Val.SINGLE,false);
908 newExp.add( "LuanImpl.sub(luan," ); 908 newExp.add( "LuanImpl.sub(luan," );
909 newExp.addAll( exp ); 909 newExp.addAll( exp );
927 Expr exp = UnaryExpr(in); 927 Expr exp = UnaryExpr(in);
928 if( exp==null ) 928 if( exp==null )
929 return parser.failure(null); 929 return parser.failure(null);
930 while(true) { 930 while(true) {
931 if( parser.match('*') ) { 931 if( parser.match('*') ) {
932 Spaces(in); 932 Spaces();
933 exp = exp.single(); 933 exp = exp.single();
934 Expr exp2 = required(UnaryExpr(in)).single(); 934 Expr exp2 = required(UnaryExpr(in)).single();
935 Expr newExp = new Expr(Val.SINGLE,false); 935 Expr newExp = new Expr(Val.SINGLE,false);
936 newExp.add( "LuanImpl.mul(luan," ); 936 newExp.add( "LuanImpl.mul(luan," );
937 newExp.addAll( exp ); 937 newExp.addAll( exp );
938 newExp.add( "," ); 938 newExp.add( "," );
939 newExp.addAll( exp2 ); 939 newExp.addAll( exp2 );
940 newExp.add( ")" ); 940 newExp.add( ")" );
941 exp = newExp; 941 exp = newExp;
942 } else if( parser.match('/') ) { 942 } else if( parser.match('/') ) {
943 Spaces(in); 943 Spaces();
944 exp = exp.single(); 944 exp = exp.single();
945 Expr exp2 = required(UnaryExpr(in)).single(); 945 Expr exp2 = required(UnaryExpr(in)).single();
946 Expr newExp = new Expr(Val.SINGLE,false); 946 Expr newExp = new Expr(Val.SINGLE,false);
947 newExp.add( "LuanImpl.div(luan," ); 947 newExp.add( "LuanImpl.div(luan," );
948 newExp.addAll( exp ); 948 newExp.addAll( exp );
949 newExp.add( "," ); 949 newExp.add( "," );
950 newExp.addAll( exp2 ); 950 newExp.addAll( exp2 );
951 newExp.add( ")" ); 951 newExp.add( ")" );
952 exp = newExp; 952 exp = newExp;
953 } else if( Mod() ) { 953 } else if( Mod() ) {
954 Spaces(in); 954 Spaces();
955 exp = exp.single(); 955 exp = exp.single();
956 Expr exp2 = required(UnaryExpr(in)).single(); 956 Expr exp2 = required(UnaryExpr(in)).single();
957 Expr newExp = new Expr(Val.SINGLE,false); 957 Expr newExp = new Expr(Val.SINGLE,false);
958 newExp.add( "LuanImpl.mod(luan," ); 958 newExp.add( "LuanImpl.mod(luan," );
959 newExp.addAll( exp ); 959 newExp.addAll( exp );
973 } 973 }
974 974
975 private Expr UnaryExpr(In in) throws ParseException { 975 private Expr UnaryExpr(In in) throws ParseException {
976 parser.begin(); 976 parser.begin();
977 if( parser.match('#') ) { 977 if( parser.match('#') ) {
978 Spaces(in); 978 Spaces();
979 Expr exp = required(UnaryExpr(in)).single(); 979 Expr exp = required(UnaryExpr(in)).single();
980 Expr newExp = new Expr(Val.SINGLE,false); 980 Expr newExp = new Expr(Val.SINGLE,false);
981 newExp.add( "LuanImpl.len(luan," ); 981 newExp.add( "LuanImpl.len(luan," );
982 newExp.addAll( exp ); 982 newExp.addAll( exp );
983 newExp.add( ")" ); 983 newExp.add( ")" );
984 return parser.success(newExp); 984 return parser.success(newExp);
985 } 985 }
986 if( Minus() ) { 986 if( Minus() ) {
987 Spaces(in); 987 Spaces();
988 Expr exp = required(UnaryExpr(in)).single(); 988 Expr exp = required(UnaryExpr(in)).single();
989 Expr newExp = new Expr(Val.SINGLE,false); 989 Expr newExp = new Expr(Val.SINGLE,false);
990 newExp.add( "LuanImpl.unm(luan," ); 990 newExp.add( "LuanImpl.unm(luan," );
991 newExp.addAll( exp ); 991 newExp.addAll( exp );
992 newExp.add( ")" ); 992 newExp.add( ")" );
993 return parser.success(newExp); 993 return parser.success(newExp);
994 } 994 }
995 if( Keyword("not",in) ) { 995 if( Keyword("not") ) {
996 Spaces(in); 996 Spaces();
997 Expr exp = required(UnaryExpr(in)).single(); 997 Expr exp = required(UnaryExpr(in)).single();
998 Expr newExp = new Expr(Val.SINGLE,false); 998 Expr newExp = new Expr(Val.SINGLE,false);
999 newExp.add( "!Luan.checkBoolean(" ); 999 newExp.add( "!Luan.checkBoolean(" );
1000 newExp.addAll( exp ); 1000 newExp.addAll( exp );
1001 newExp.add( ")" ); 1001 newExp.add( ")" );
1011 parser.begin(); 1011 parser.begin();
1012 Expr exp1 = SingleExpr(in); 1012 Expr exp1 = SingleExpr(in);
1013 if( exp1==null ) 1013 if( exp1==null )
1014 return parser.failure(null); 1014 return parser.failure(null);
1015 if( parser.match('^') ) { 1015 if( parser.match('^') ) {
1016 Spaces(in); 1016 Spaces();
1017 Expr exp2 = required(PowExpr(in)); 1017 Expr exp2 = required(PowExpr(in));
1018 Expr newExp = new Expr(Val.SINGLE,false); 1018 Expr newExp = new Expr(Val.SINGLE,false);
1019 newExp.add( "LuanImpl.pow(luan," ); 1019 newExp.add( "LuanImpl.pow(luan," );
1020 newExp.addAll( exp1.single() ); 1020 newExp.addAll( exp1.single() );
1021 newExp.add( "," ); 1021 newExp.add( "," );
1032 if( exp != null ) 1032 if( exp != null )
1033 return parser.success(exp); 1033 return parser.success(exp);
1034 exp = VarExp(in); 1034 exp = VarExp(in);
1035 if( exp != null ) 1035 if( exp != null )
1036 return parser.success(exp); 1036 return parser.success(exp);
1037 exp = VarArgs(in); 1037 exp = VarArgs();
1038 if( exp != null ) 1038 if( exp != null )
1039 return parser.success(exp); 1039 return parser.success(exp);
1040 return parser.failure(null); 1040 return parser.failure(null);
1041 } 1041 }
1042 1042
1043 private Expr FunctionExpr(In in) throws ParseException { 1043 private Expr FunctionExpr(In in) throws ParseException {
1044 if( !Keyword("function",in) ) 1044 if( !Keyword("function") )
1045 return null; 1045 return null;
1046 return RequiredFunction(in); 1046 return RequiredFunction(in);
1047 } 1047 }
1048 1048
1049 private Expr RequiredFunction(In in) throws ParseException { 1049 private Expr RequiredFunction(In in) throws ParseException {
1050 parser.begin(); 1050 parser.begin();
1051 RequiredMatch('('); 1051 RequiredMatch('(');
1052 In inParens = in.parens(); 1052 Spaces();
1053 Spaces(inParens);
1054 frame = new Frame(frame); 1053 frame = new Frame(frame);
1055 Stmts stmt = new Stmts(); 1054 Stmts stmt = new Stmts();
1056 List<String> names = NameList(in); 1055 List<String> names = NameList();
1057 if( names != null ) { 1056 if( names != null ) {
1058 Expr args = new Expr(Val.ARRAY,false); 1057 Expr args = new Expr(Val.ARRAY,false);
1059 args.add( "args" ); 1058 args.add( "args" );
1060 stmt.addAll( makeLocalSetStmt(names,args) ); 1059 stmt.addAll( makeLocalSetStmt(names,args) );
1061 if( parser.match(',') ) { 1060 if( parser.match(',') ) {
1062 Spaces(inParens); 1061 Spaces();
1063 if( !parser.match("...") ) 1062 if( !parser.match("...") )
1064 throw parser.exception(); 1063 throw parser.exception();
1065 Spaces(inParens); 1064 Spaces();
1066 frame.isVarArg = true; 1065 frame.isVarArg = true;
1067 stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args," + names.size() + ");\n" ); 1066 stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args," + names.size() + "); " );
1068 } 1067 }
1069 } else if( parser.match("...") ) { 1068 } else if( parser.match("...") ) {
1070 Spaces(inParens); 1069 Spaces();
1071 frame.isVarArg = true; 1070 frame.isVarArg = true;
1072 stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);\n" ); 1071 stmt.add( "final Object[] varArgs = LuanImpl.varArgs(args,0); " );
1073 } 1072 }
1074 RequiredMatch(')'); 1073 RequiredMatch(')');
1075 Spaces(in); 1074 Spaces();
1076 Stmts block = RequiredBlock(); 1075 Stmts block = RequiredBlock();
1077 stmt.addAll( block ); 1076 stmt.addAll( block );
1078 stmt.hasReturn = block.hasReturn; 1077 stmt.hasReturn = block.hasReturn;
1078 Expr fnDef = newFnExpStr(stmt);
1079 RequiredKeyword("end",in); 1079 RequiredKeyword("end",in);
1080 Expr fnDef = newFnExpStr(stmt);
1081 frame = frame.parent; 1080 frame = frame.parent;
1082 return parser.success(fnDef); 1081 return parser.success(fnDef);
1083 } 1082 }
1084 1083
1085 private Expr VarArgs(In in) throws ParseException { 1084 private Expr VarArgs() throws ParseException {
1086 parser.begin(); 1085 parser.begin();
1087 if( !frame.isVarArg || !parser.match("...") ) 1086 if( !frame.isVarArg || !parser.match("...") )
1088 return parser.failure(null); 1087 return parser.failure(null);
1089 Spaces(in); 1088 Spaces();
1090 Expr exp = new Expr(Val.ARRAY,false); 1089 Expr exp = new Expr(Val.ARRAY,false);
1091 exp.add("varArgs"); 1090 exp.add("varArgs");
1092 return parser.success(exp); 1091 return parser.success(exp);
1093 } 1092 }
1094 1093
1095 private Expr TableExpr(In in) throws ParseException { 1094 private Expr TableExpr() throws ParseException {
1096 parser.begin(); 1095 parser.begin();
1097 if( !parser.match('{') ) 1096 if( !parser.match('{') )
1098 return parser.failure(null); 1097 return parser.failure(null);
1099 Spaces(In.NOTHING); 1098 Spaces();
1100 List<Expr> builder = new ArrayList<Expr>(); 1099 List<Expr> builder = new ArrayList<Expr>();
1101 Field(builder); 1100 Field(builder);
1102 while( FieldSep() ) { 1101 while( FieldSep() ) {
1103 Spaces(In.NOTHING); 1102 Spaces();
1104 Field(builder); 1103 Field(builder);
1105 } 1104 }
1106 Expr exp = TemplateExpressions(In.NOTHING); 1105 Expr exp = TemplateExpressions(In.NOTHING);
1107 if( exp != null ) 1106 if( exp != null )
1108 builder.add(exp); 1107 builder.add(exp);
1109 if( !parser.match('}') ) 1108 if( !parser.match('}') )
1110 throw parser.exception("Expected table element or '}'"); 1109 throw parser.exception("Expected table element or '}'");
1111 Spaces(in); 1110 Spaces();
1112 exp = new Expr(Val.SINGLE,false); 1111 exp = new Expr(Val.SINGLE,false);
1113 exp.add( "LuanImpl.table(" ); 1112 exp.add( "LuanImpl.table(" );
1114 exp.addAll( expString(builder).array() ); 1113 exp.addAll( expString(builder).array() );
1115 exp.add( ")" ); 1114 exp.add( ")" );
1116 return parser.success( exp ); 1115 return parser.success( exp );
1122 1121
1123 private boolean Field(List<Expr> builder) throws ParseException { 1122 private boolean Field(List<Expr> builder) throws ParseException {
1124 parser.begin(); 1123 parser.begin();
1125 Expr exp = SubExpr(In.NOTHING); 1124 Expr exp = SubExpr(In.NOTHING);
1126 if( exp==null ) 1125 if( exp==null )
1127 exp = NameExpr(In.NOTHING); 1126 exp = NameExpr();
1128 if( exp!=null && parser.match('=') ) { 1127 if( exp!=null && parser.match('=') ) {
1129 Spaces(In.NOTHING); 1128 Spaces();
1130 Expr val = RequiredExpr(In.NOTHING).single(); 1129 Expr val = RequiredExpr(In.NOTHING).single();
1131 Expr newExp = new Expr(Val.SINGLE,false); 1130 Expr newExp = new Expr(Val.SINGLE,false);
1132 newExp.add( "new TableField(" ); 1131 newExp.add( "new TableField(" );
1133 newExp.addAll( exp ); 1132 newExp.addAll( exp );
1134 newExp.add( "," ); 1133 newExp.add( "," );
1163 return parser.success(var); 1162 return parser.success(var);
1164 } 1163 }
1165 1164
1166 private Var VarStart(In in) throws ParseException { 1165 private Var VarStart(In in) throws ParseException {
1167 if( parser.match('(') ) { 1166 if( parser.match('(') ) {
1168 In inParens = in.parens(); 1167 Spaces();
1169 Spaces(inParens); 1168 Expr exp = RequiredExpr(in).single();
1170 Expr exp = RequiredExpr(inParens).single();
1171 RequiredMatch(')'); 1169 RequiredMatch(')');
1172 Spaces(in); 1170 Spaces();
1173 return exprVar(exp); 1171 return exprVar(exp);
1174 } 1172 }
1175 String name = Name(in); 1173 String name = Name();
1176 if( name != null ) 1174 if( name != null )
1177 return nameVar(name); 1175 return nameVar(name);
1178 Expr exp; 1176 Expr exp;
1179 exp = TableExpr(in); 1177 exp = TableExpr();
1180 if( exp != null ) 1178 if( exp != null )
1181 return exprVar(exp); 1179 return exprVar(exp);
1182 exp = Literal(in); 1180 exp = Literal();
1183 if( exp != null ) 1181 if( exp != null )
1184 return exprVar(exp); 1182 return exprVar(exp);
1185 return null; 1183 return null;
1186 } 1184 }
1187 1185
1189 parser.begin(); 1187 parser.begin();
1190 Expr exp2 = SubExpr(in); 1188 Expr exp2 = SubExpr(in);
1191 if( exp2 != null ) 1189 if( exp2 != null )
1192 return parser.success(indexVar(exp1,exp2)); 1190 return parser.success(indexVar(exp1,exp2));
1193 if( parser.match('.') ) { 1191 if( parser.match('.') ) {
1194 Spaces(in); 1192 Spaces();
1195 exp2 = NameExpr(in); 1193 exp2 = NameExpr();
1196 if( exp2!=null ) 1194 if( exp2!=null )
1197 return parser.success(indexVar(exp1,exp2)); 1195 return parser.success(indexVar(exp1,exp2));
1198 return parser.failure(null); 1196 return parser.failure(null);
1199 } 1197 }
1200 Expr fnCall = Args( in, exp1, new ArrayList<Expr>() ); 1198 Expr fnCall = Args( in, exp1, new ArrayList<Expr>() );
1240 if( sym != null ) { 1238 if( sym != null ) {
1241 Stmts stmt = new Stmts(); 1239 Stmts stmt = new Stmts();
1242 stmt.addAll( sym.exp() ); 1240 stmt.addAll( sym.exp() );
1243 stmt.add( " = " ); 1241 stmt.add( " = " );
1244 stmt.addAll( val.single() ); 1242 stmt.addAll( val.single() );
1245 stmt.add( ";\n" ); 1243 stmt.add( "; " );
1246 return stmt; 1244 return stmt;
1247 } 1245 }
1248 Expr envExpr = env(); 1246 Expr envExpr = env();
1249 if( envExpr != null ) 1247 if( envExpr != null )
1250 return indexVar( envExpr, constExpStr(name) ).set(val); 1248 return indexVar( envExpr, constExpStr(name) ).set(val);
1287 stmt.addAll( table.single() ); 1285 stmt.addAll( table.single() );
1288 stmt.add( "," ); 1286 stmt.add( "," );
1289 stmt.addAll( key.single() ); 1287 stmt.addAll( key.single() );
1290 stmt.add( "," ); 1288 stmt.add( "," );
1291 stmt.addAll( val.single() ); 1289 stmt.addAll( val.single() );
1292 stmt.add( ");\n" ); 1290 stmt.add( "); " );
1293 return stmt; 1291 return stmt;
1294 } 1292 }
1295 }; 1293 };
1296 } 1294 }
1297 1295
1303 } 1301 }
1304 1302
1305 private boolean args(In in,List<Expr> builder) throws ParseException { 1303 private boolean args(In in,List<Expr> builder) throws ParseException {
1306 parser.begin(); 1304 parser.begin();
1307 if( parser.match('(') ) { 1305 if( parser.match('(') ) {
1308 In inParens = in.parens(); 1306 Spaces();
1309 Spaces(inParens); 1307 ExpList(in,builder); // optional
1310 ExpList(inParens,builder); // optional
1311 if( !parser.match(')') ) 1308 if( !parser.match(')') )
1312 throw parser.exception("Expression or ')' expected"); 1309 throw parser.exception("Expression or ')' expected");
1313 Spaces(in); 1310 Spaces();
1314 return parser.success(); 1311 return parser.success();
1315 } 1312 }
1316 Expr exp = TableExpr(in); 1313 Expr exp = TableExpr();
1317 if( exp != null ) { 1314 if( exp != null ) {
1318 builder.add(exp); 1315 builder.add(exp);
1319 return parser.success(); 1316 return parser.success();
1320 } 1317 }
1321 String s = StringLiteral(in); 1318 String s = StringLiteral();
1322 if( s != null ) { 1319 if( s != null ) {
1323 builder.add( constExpStr(s) ); 1320 builder.add( constExpStr(s) );
1324 return parser.success(); 1321 return parser.success();
1325 } 1322 }
1326 /*
1327 Expressions exps = TemplateExpressions(in);
1328 if( exps != null ) {
1329 builder.add(exps);
1330 return parser.success();
1331 }
1332 */
1333 return parser.failure(); 1323 return parser.failure();
1334 } 1324 }
1335 1325
1336 private Expr ExpStringList(In in) throws ParseException { 1326 private Expr ExpStringList(In in) throws ParseException {
1337 List<Expr> builder = new ArrayList<Expr>(); 1327 List<Expr> builder = new ArrayList<Expr>();
1348 exp = ExprZ(in); 1338 exp = ExprZ(in);
1349 if( exp==null ) 1339 if( exp==null )
1350 return parser.failure(); 1340 return parser.failure();
1351 builder.add(exp); 1341 builder.add(exp);
1352 while( parser.match(',') ) { 1342 while( parser.match(',') ) {
1353 Spaces(in); 1343 Spaces();
1354 exp = TemplateExpressions(in); 1344 exp = TemplateExpressions(in);
1355 if( exp != null ) { 1345 if( exp != null ) {
1356 builder.add(exp); 1346 builder.add(exp);
1357 return parser.success(); 1347 return parser.success();
1358 } 1348 }
1363 1353
1364 private Expr SubExpr(In in) throws ParseException { 1354 private Expr SubExpr(In in) throws ParseException {
1365 parser.begin(); 1355 parser.begin();
1366 if( !parser.match('[') || parser.test("[") || parser.test("=") ) 1356 if( !parser.match('[') || parser.test("[") || parser.test("=") )
1367 return parser.failure(null); 1357 return parser.failure(null);
1368 Spaces(In.NOTHING); 1358 Spaces();
1369 Expr exp = RequiredExpr(In.NOTHING).single(); 1359 Expr exp = RequiredExpr(In.NOTHING).single();
1370 RequiredMatch(']'); 1360 RequiredMatch(']');
1371 Spaces(in); 1361 Spaces();
1372 return parser.success(exp); 1362 return parser.success(exp);
1373 } 1363 }
1374 1364
1375 private Expr NameExpr(In in) throws ParseException { 1365 private Expr NameExpr() throws ParseException {
1376 parser.begin(); 1366 parser.begin();
1377 String name = Name(in); 1367 String name = Name();
1378 if( name==null ) 1368 if( name==null )
1379 return parser.failure(null); 1369 return parser.failure(null);
1380 return parser.success(constExpStr(name)); 1370 return parser.success(constExpStr(name));
1381 } 1371 }
1382 1372
1383 private String RequiredName(In in) throws ParseException { 1373 private String RequiredName() throws ParseException {
1384 parser.begin(); 1374 parser.begin();
1385 String name = Name(in); 1375 String name = Name();
1386 if( name==null ) 1376 if( name==null )
1387 throw parser.exception("Name expected"); 1377 throw parser.exception("Name expected");
1388 return parser.success(name); 1378 return parser.success(name);
1389 } 1379 }
1390 1380
1391 private String Name(In in) throws ParseException { 1381 private String Name() throws ParseException {
1392 int start = parser.begin(); 1382 int start = parser.begin();
1393 if( !NameFirstChar() ) 1383 if( !NameFirstChar() )
1394 return parser.failure(null); 1384 return parser.failure(null);
1395 while( NameChar() ); 1385 while( NameChar() );
1396 String match = parser.textFrom(start); 1386 String match = parser.textFrom(start);
1397 if( keywords.contains(match) ) 1387 if( keywords.contains(match) )
1398 return parser.failure(null); 1388 return parser.failure(null);
1399 Spaces(in); 1389 Spaces();
1400 return parser.success(match); 1390 return parser.success(match);
1401 } 1391 }
1402 1392
1403 private boolean NameChar() { 1393 private boolean NameChar() {
1404 return NameFirstChar() || Digit(); 1394 return NameFirstChar() || Digit();
1417 if( !parser.match(s) ) 1407 if( !parser.match(s) )
1418 throw parser.exception("'"+s+"' expected"); 1408 throw parser.exception("'"+s+"' expected");
1419 } 1409 }
1420 1410
1421 private void RequiredKeyword(String keyword,In in) throws ParseException { 1411 private void RequiredKeyword(String keyword,In in) throws ParseException {
1422 if( !Keyword(keyword,in) ) 1412 if( !Keyword(keyword) )
1423 throw parser.exception("'"+keyword+"' expected"); 1413 throw parser.exception("'"+keyword+"' expected");
1424 } 1414 }
1425 1415
1426 private boolean Keyword(String keyword,In in) throws ParseException { 1416 private boolean Keyword(String keyword) throws ParseException {
1427 parser.begin(); 1417 parser.begin();
1428 if( !parser.match(keyword) || NameChar() ) 1418 if( !parser.match(keyword) || NameChar() )
1429 return parser.failure(); 1419 return parser.failure();
1430 Spaces(in); 1420 Spaces();
1431 return parser.success(); 1421 return parser.success();
1432 } 1422 }
1433 1423
1434 private static final Set<String> keywords = new HashSet<String>(Arrays.asList( 1424 private static final Set<String> keywords = new HashSet<String>(Arrays.asList(
1435 "and", 1425 "and",
1454 "true", 1444 "true",
1455 "until", 1445 "until",
1456 "while" 1446 "while"
1457 )); 1447 ));
1458 1448
1459 private Expr Literal(In in) throws ParseException { 1449 private Expr Literal() throws ParseException {
1460 parser.begin(); 1450 parser.begin();
1461 if( NilLiteral(in) ) { 1451 if( NilLiteral() ) {
1462 Expr exp = new Expr(Val.SINGLE,false); 1452 Expr exp = new Expr(Val.SINGLE,false);
1463 exp.add( "null" ); 1453 exp.add( "null" );
1464 return parser.success(exp); 1454 return parser.success(exp);
1465 } 1455 }
1466 Boolean b = BooleanLiteral(in); 1456 Boolean b = BooleanLiteral();
1467 if( b != null ) { 1457 if( b != null ) {
1468 Expr exp = new Expr(Val.SINGLE,false); 1458 Expr exp = new Expr(Val.SINGLE,false);
1469 exp.add( b.toString() ); 1459 exp.add( b.toString() );
1470 return parser.success(exp); 1460 return parser.success(exp);
1471 } 1461 }
1472 Number n = NumberLiteral(in); 1462 Number n = NumberLiteral();
1473 if( n != null ) { 1463 if( n != null ) {
1474 String s = n.toString(); 1464 String s = n.toString();
1475 if( n instanceof Long ) 1465 if( n instanceof Long )
1476 s += "L"; 1466 s += "L";
1477 Expr exp = new Expr(Val.SINGLE,false); 1467 Expr exp = new Expr(Val.SINGLE,false);
1478 exp.add( s ); 1468 exp.add( s );
1479 return parser.success(exp); 1469 return parser.success(exp);
1480 } 1470 }
1481 String s = StringLiteral(in); 1471 String s = StringLiteral();
1482 if( s != null ) 1472 if( s != null )
1483 return parser.success(constExpStr(s)); 1473 return parser.success(constExpStr(s));
1484 return parser.failure(null); 1474 return parser.failure(null);
1485 } 1475 }
1486 1476
1487 private Expr constExpStr(String s) { 1477 private Expr constExpStr(String s) {
1478 int n = 0;
1479 int from = 0;
1480 while( (from = s.indexOf('\n',from) + 1) != 0 ) {
1481 n++;
1482 }
1488 s = s 1483 s = s
1489 .replace("\\","\\\\") 1484 .replace("\\","\\\\")
1490 .replace("\"","\\\"") 1485 .replace("\"","\\\"")
1491 .replace("\n","\\n") 1486 .replace("\n","\\n")
1492 .replace("\r","\\r") 1487 .replace("\r","\\r")
1493 .replace("\t","\\t") 1488 .replace("\t","\\t")
1494 .replace("\b","\\b") 1489 .replace("\b","\\b")
1495 ; 1490 ;
1491 s = "\"" + s + "\"";
1492 while( n-- > 0 )
1493 s += "\n";
1496 Expr exp = new Expr(Val.SINGLE,false); 1494 Expr exp = new Expr(Val.SINGLE,false);
1497 exp.add( "\""+s+"\"" ); 1495 exp.add( s );
1498 return exp; 1496 return exp;
1499 } 1497 }
1500 1498
1501 private boolean NilLiteral(In in) throws ParseException { 1499 private boolean NilLiteral() throws ParseException {
1502 return Keyword("nil",in); 1500 return Keyword("nil");
1503 } 1501 }
1504 1502
1505 private Boolean BooleanLiteral(In in) throws ParseException { 1503 private Boolean BooleanLiteral() throws ParseException {
1506 if( Keyword("true",in) ) 1504 if( Keyword("true") )
1507 return true; 1505 return true;
1508 if( Keyword("false",in) ) 1506 if( Keyword("false") )
1509 return false; 1507 return false;
1510 return null; 1508 return null;
1511 } 1509 }
1512 1510
1513 private Number NumberLiteral(In in) throws ParseException { 1511 private Number NumberLiteral() throws ParseException {
1514 parser.begin(); 1512 parser.begin();
1515 Number n; 1513 Number n;
1516 if( parser.matchIgnoreCase("0x") ) { 1514 if( parser.matchIgnoreCase("0x") ) {
1517 n = HexNumber(); 1515 n = HexNumber();
1518 } else { 1516 } else {
1519 n = DecNumber(); 1517 n = DecNumber();
1520 } 1518 }
1521 if( n==null || NameChar() ) 1519 if( n==null || NameChar() )
1522 return parser.failure(null); 1520 return parser.failure(null);
1523 Spaces(in); 1521 Spaces();
1524 return parser.success(n); 1522 return parser.success(n);
1525 } 1523 }
1526 1524
1527 private Number DecNumber() { 1525 private Number DecNumber() {
1528 int start = parser.begin(); 1526 int start = parser.begin();
1618 1616
1619 private boolean HexDigit() { 1617 private boolean HexDigit() {
1620 return Digit() || parser.anyOf("abcdefABCDEF"); 1618 return Digit() || parser.anyOf("abcdefABCDEF");
1621 } 1619 }
1622 1620
1623 private String StringLiteral(In in) throws ParseException { 1621 private String StringLiteral() throws ParseException {
1624 String s; 1622 String s;
1625 if( (s=QuotedString('"'))==null 1623 if( (s=QuotedString('"'))==null
1626 && (s=QuotedString('\''))==null 1624 && (s=QuotedString('\''))==null
1627 && (s=LongString())==null 1625 && (s=LongString())==null
1628 ) 1626 )
1629 return null; 1627 return null;
1630 Spaces(in); 1628 Spaces();
1631 return s; 1629 return s;
1632 } 1630 }
1633 1631
1634 private String LongString() throws ParseException { 1632 private String LongString() throws ParseException {
1635 parser.begin(); 1633 parser.begin();
1687 return parser.success((char)Integer.parseInt(parser.textFrom(start+1),16)); 1685 return parser.success((char)Integer.parseInt(parser.textFrom(start+1),16));
1688 if( Digit() ) { 1686 if( Digit() ) {
1689 if( Digit() ) Digit(); // optional 1687 if( Digit() ) Digit(); // optional
1690 return parser.success((char)Integer.parseInt(parser.textFrom(start))); 1688 return parser.success((char)Integer.parseInt(parser.textFrom(start)));
1691 } 1689 }
1692 if( EndOfLine() ) 1690 if( EndOfLine() ) {
1691 parser.sb().setLength(parser.sb().length()-1);
1693 return parser.success('\n'); 1692 return parser.success('\n');
1693 }
1694 return parser.failure(null); 1694 return parser.failure(null);
1695 } 1695 }
1696 1696
1697 private void Spaces(In in) throws ParseException { 1697 private void Spaces() throws ParseException {
1698 while( parser.anyOf(" \t") || Comment() || ContinueOnNextLine() || in.parens && EndOfLine() ); 1698 while( parser.anyOf(" \t") || Comment() || ContinueOnNextLine() );
1699 } 1699 }
1700 1700
1701 private boolean ContinueOnNextLine() { 1701 private boolean ContinueOnNextLine() {
1702 parser.begin(); 1702 parser.begin();
1703 return parser.match('\\') && EndOfLine() ? parser.success() : parser.failure(); 1703 return parser.match('\\') && EndOfLine() ? parser.success() : parser.failure();
1721 while( parser.match('=') ); 1721 while( parser.match('=') );
1722 int nEquals = parser.currentIndex() - start; 1722 int nEquals = parser.currentIndex() - start;
1723 if( !parser.match('[') ) 1723 if( !parser.match('[') )
1724 return parser.failure(); 1724 return parser.failure();
1725 while( !LongBracketsEnd(nEquals) ) { 1725 while( !LongBracketsEnd(nEquals) ) {
1726 if( !parser.anyChar() ) 1726 if( !(EndOfLine() || parser.anyChar()) )
1727 throw parser.exception("Unclosed comment"); 1727 throw parser.exception("Unclosed comment");
1728 } 1728 }
1729 parser.upSb();
1729 return parser.success(); 1730 return parser.success();
1730 } 1731 }
1731 1732
1732 private boolean LongBracketsEnd(int nEquals) { 1733 private boolean LongBracketsEnd(int nEquals) {
1733 parser.begin(); 1734 parser.begin();
1742 return parser.success(); 1743 return parser.success();
1743 } 1744 }
1744 1745
1745 1746
1746 1747
1747 private static class ParseList extends ArrayList { 1748 private class ParseList extends ArrayList {
1749
1750 void addNewLines() {
1751 if( parser.sb().length() > 0 ) {
1752 add( parser.sb().toString() );
1753 parser.sb().setLength(0);
1754 /*
1755 if( parser.sourceName.equals("stdin") ) {
1756 StringWriter sw = new StringWriter();
1757 new Throwable().printStackTrace(new PrintWriter(sw,true));
1758 // add(sw.toString());
1759 }
1760 */
1761 }
1762 }
1763
1764 ParseList() {
1765 addNewLines();
1766 }
1748 1767
1749 @Override public boolean add(Object obj) { 1768 @Override public boolean add(Object obj) {
1750 if( obj instanceof List ) throw new RuntimeException(); 1769 if( obj instanceof List ) throw new RuntimeException();
1751 return super.add(obj); 1770 return super.add(obj);
1752 } 1771 }
1768 1787
1769 private static AtomicInteger classCounter = new AtomicInteger(); 1788 private static AtomicInteger classCounter = new AtomicInteger();
1770 1789
1771 private enum Val { SINGLE, ARRAY } 1790 private enum Val { SINGLE, ARRAY }
1772 1791
1773 private static class Expr extends ParseList { 1792 private class Expr extends ParseList {
1774 final Val valType; 1793 final Val valType;
1775 final boolean isStmt; 1794 final boolean isStmt;
1776 1795
1777 Expr(Val valType,boolean isStmt) { 1796 Expr(Val valType,boolean isStmt) {
1778 this.valType = valType; 1797 this.valType = valType;
1835 } 1854 }
1836 return exp; 1855 return exp;
1837 } 1856 }
1838 } 1857 }
1839 1858
1840 private static class Stmts extends ParseList { 1859 private class Stmts extends ParseList {
1841 boolean hasReturn = false; 1860 boolean hasReturn = false;
1842 } 1861 }
1843 1862
1844 private Class toFnClass(Stmts stmts,List<UpSym> upValueSymbols) { 1863 private Class toFnClass(Stmts stmts,List<UpSym> upValueSymbols) {
1845 String className = "EXP" + classCounter.incrementAndGet(); 1864 String className = "EXP" + classCounter.incrementAndGet();
1858 return toFnString(stmts,upValueSymbols,className); 1877 return toFnString(stmts,upValueSymbols,className);
1859 } 1878 }
1860 1879
1861 private String toFnString(Stmts stmts,List<UpSym> upValueSymbols,String className) { 1880 private String toFnString(Stmts stmts,List<UpSym> upValueSymbols,String className) {
1862 if( !stmts.hasReturn ) 1881 if( !stmts.hasReturn )
1863 stmts.add( "return LuanFunction.NOTHING;\n" ); 1882 stmts.add( "\nreturn LuanFunction.NOTHING;" );
1864 return "" 1883 return ""
1865 +"package luan.impl;\n" 1884 +"package luan.impl; "
1866 +"import luan.Luan;\n" 1885 +"import luan.Luan; "
1867 +"import luan.LuanFunction;\n" 1886 +"import luan.LuanFunction; "
1868 +"import luan.LuanState;\n" 1887 +"import luan.LuanState; "
1869 +"import luan.LuanJava;\n" 1888 +"import luan.LuanJava; "
1870 +"import luan.LuanException;\n" 1889 +"import luan.LuanException; "
1871 +"import luan.modules.PackageLuan;\n" 1890 +"import luan.modules.PackageLuan; "
1872 +"\n" 1891
1873 +"public class " + className +" extends Closure {\n" 1892 +"public class " + className +" extends Closure { "
1874 +" public "+className+"(LuanJava java) throws LuanException {\n" 1893 +"public "+className+"(LuanJava java) throws LuanException { "
1875 +" super("+upValueSymbols.size()+",java);\n" 1894 +"super("+upValueSymbols.size()+",java); "
1876 + init(upValueSymbols) 1895 + init(upValueSymbols)
1877 +" }\n" 1896 +"} "
1878 +"\n" 1897
1879 +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" 1898 +"@Override public Object doCall(LuanState luan,Object[] args) throws LuanException { "
1880 +" Object t;\n" 1899 +"Object t; "
1881 +" Object[] a;\n" 1900 +"Object[] a; "
1882 +" " + stmts 1901 + stmts
1883 +" }\n" 1902 +"\n} "
1884 +"}\n" 1903 +"}\n"
1885 ; 1904 ;
1886 } 1905 }
1887 1906
1888 private static Expr toFnExpStr(Stmts stmt,List<UpSym> upValueSymbols) { 1907 private Expr toFnExpStr(Stmts stmt,List<UpSym> upValueSymbols) {
1908 stmt.addNewLines();
1889 if( !stmt.hasReturn ) 1909 if( !stmt.hasReturn )
1890 stmt.add( "return LuanFunction.NOTHING;\n" ); 1910 stmt.add( "return LuanFunction.NOTHING; " );
1891 Expr exp = new Expr(Val.SINGLE,false); 1911 Expr exp = new Expr(Val.SINGLE,false);
1892 exp.add( "" 1912 exp.add( ""
1893 +"\n" 1913 +"new Closure("+upValueSymbols.size()+",java) { "
1894 +"new Closure("+upValueSymbols.size()+",java) {\n" 1914 +"{ "
1895 +"{\n" 1915 + init(upValueSymbols)
1896 + init(upValueSymbols) 1916 +"} "
1897 +"}\n" 1917 +"@Override public Object doCall(LuanState luan,Object[] args) throws LuanException { "
1898 +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" 1918 +"Object t; "
1899 +" Object t;\n" 1919 +"Object[] a; "
1900 +" Object[] a;\n"
1901 +" "
1902 ); 1920 );
1903 exp.addAll( stmt ); 1921 exp.addAll( stmt );
1904 exp.add( "" 1922 exp.add( ""
1905 +" }\n" 1923 +"} "
1906 +"}\n" 1924 +"} "
1907 ); 1925 );
1908 return exp; 1926 return exp;
1909 } 1927 }
1910 1928
1911 private static String init(List<UpSym> upValueSymbols) { 1929 private static String init(List<UpSym> upValueSymbols) {