comparison core/src/luan/impl/LuanParser.java @ 651:140cc5191b7a

start compiling statements
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 01 Apr 2016 17:24:44 -0600
parents d658eab7bf4c
children 067d9470184d
comparison
equal deleted inserted replaced
650:d658eab7bf4c 651:140cc5191b7a
191 191
192 FnDef RequiredModule() throws ParseException { 192 FnDef RequiredModule() throws ParseException {
193 Spaces(In.NOTHING); 193 Spaces(In.NOTHING);
194 int start = parser.begin(); 194 int start = parser.begin();
195 frame.isVarArg = true; 195 frame.isVarArg = true;
196 Stmt stmt = RequiredBlock(); 196 Stmt stmt = stmt(RequiredBlock());
197 if( parser.endOfInput() ) 197 if( parser.endOfInput() )
198 return parser.success(newFnDef(start,stmt)); 198 return parser.success(newFnDef(start,stmt));
199 throw parser.exception(); 199 throw parser.exception();
200 } 200 }
201 201
202 private Stmt RequiredBlock() throws ParseException { 202 private StmtString RequiredBlock() throws ParseException {
203 List<Stmt> stmts = new ArrayList<Stmt>(); 203 StringBuilder stmts = new StringBuilder();
204 int stackStart = symbolsSize(); 204 int stackStart = symbolsSize();
205 Stmt(stmts); 205 Stmt(stmts);
206 while( StmtSep(stmts) ) { 206 while( StmtSep(stmts) ) {
207 Spaces(In.NOTHING); 207 Spaces(In.NOTHING);
208 Stmt(stmts); 208 Stmt(stmts);
209 } 209 }
210 int stackEnd = symbolsSize(); 210 int stackEnd = symbolsSize();
211 popSymbols( stackEnd - stackStart ); 211 popSymbols( stackEnd - stackStart );
212 if( stmts.isEmpty() ) 212 if( stmts.length() == 0 )
213 return Stmt.EMPTY; 213 return EMPTY_STMT;
214 if( stmts.size()==1 && stackStart==stackEnd ) 214 String code = stmts.toString();
215 return stmts.get(0); 215 if( stackStart < stackEnd )
216 return new Block( stmts.toArray(new Stmt[0]), stackStart, stackEnd ); 216 code = ""
217 } 217 +"try {\n"
218 218 + code
219 private boolean StmtSep(List<Stmt> stmts) throws ParseException { 219 +"} finally {\n"
220 +" $luan.stackClear("+stackStart+","+stackEnd+");\n"
221 +"}\n"
222 ;
223 return new StmtString(code);
224 }
225
226 private boolean StmtSep(StringBuilder stmts) throws ParseException {
220 parser.begin(); 227 parser.begin();
221 if( parser.match( ';' ) ) 228 if( parser.match( ';' ) )
222 return parser.success(); 229 return parser.success();
223 if( EndOfLine() ) 230 if( EndOfLine() )
224 return parser.success(); 231 return parser.success();
225 parser.rollback(); 232 parser.rollback();
226 Stmt stmt = TemplateStmt(); 233 StmtString stmt = stmtStr(TemplateStmt());
227 if( stmt != null ) { 234 if( stmt != null ) {
228 stmts.add(stmt); 235 stmts.append(stmt.code);
229 return parser.success(); 236 return parser.success();
230 } 237 }
231 return parser.failure(); 238 return parser.failure();
232 } 239 }
233 240
234 private boolean EndOfLine() { 241 private boolean EndOfLine() {
235 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); 242 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' );
236 } 243 }
237 244
238 private void Stmt(List<Stmt> stmts) throws ParseException { 245 private void Stmt(StringBuilder stmts) throws ParseException {
239 if( LocalStmt(stmts) ) 246 if( LocalStmt(stmts) )
240 return; 247 return;
241 Stmt stmt; 248 StmtString stmt;
242 if( (stmt=ReturnStmt()) != null 249 if( (stmt=stmtStr(ReturnStmt())) != null
243 || (stmt=FunctionStmt()) != null 250 || (stmt=stmtStr(FunctionStmt())) != null
244 || (stmt=LocalFunctionStmt()) != null 251 || (stmt=stmtStr(LocalFunctionStmt())) != null
245 || (stmt=BreakStmt()) != null 252 || (stmt=stmtStr(BreakStmt())) != null
246 || (stmt=ForStmt()) != null 253 || (stmt=stmtStr(ForStmt())) != null
247 || (stmt=DoStmt()) != null 254 || (stmt=DoStmt()) != null
248 || (stmt=WhileStmt()) != null 255 || (stmt=WhileStmt()) != null
249 || (stmt=RepeatStmt()) != null 256 || (stmt=RepeatStmt()) != null
250 || (stmt=IfStmt()) != null 257 || (stmt=stmtStr(IfStmt())) != null
251 || (stmt=SetStmt()) != null 258 || (stmt=stmtStr(SetStmt())) != null
252 || (stmt=ExpressionsStmt()) != null 259 || (stmt=ExpressionsStmt()) != null
253 ) { 260 ) {
254 stmts.add(stmt); 261 stmts.append(stmt.code);
255 } 262 }
256 } 263 }
257 264
258 private Stmt TemplateStmt() throws ParseException { 265 private Stmt TemplateStmt() throws ParseException {
259 parser.currentIndex(); 266 parser.currentIndex();
356 if( !Keyword("in",In.NOTHING) ) 363 if( !Keyword("in",In.NOTHING) )
357 return parser.failure(null); 364 return parser.failure(null);
358 Expr expr = expr(exp(RequiredExpr(In.NOTHING))); 365 Expr expr = expr(exp(RequiredExpr(In.NOTHING)));
359 RequiredKeyword("do",In.NOTHING); 366 RequiredKeyword("do",In.NOTHING);
360 addSymbols(names); 367 addSymbols(names);
361 Stmt loop = RequiredLoopBlock(); 368 Stmt loop = stmt(RequiredLoopBlock());
362 RequiredKeyword("end",In.NOTHING); 369 RequiredKeyword("end",In.NOTHING);
363 Stmt stmt = new ForStmt( stackStart, symbolsSize() - stackStart, expr, loop ); 370 Stmt stmt = new ForStmt( stackStart, symbolsSize() - stackStart, expr, loop );
364 popSymbols( symbolsSize() - stackStart ); 371 popSymbols( symbolsSize() - stackStart );
365 return parser.success(stmt); 372 return parser.success(stmt);
366 } 373 }
367 374
368 private Stmt DoStmt() throws ParseException { 375 private StmtString DoStmt() throws ParseException {
369 parser.begin(); 376 parser.begin();
370 if( !Keyword("do",In.NOTHING) ) 377 if( !Keyword("do",In.NOTHING) )
371 return parser.failure(null); 378 return parser.failure(null);
372 Stmt stmt = RequiredBlock(); 379 StmtString stmt = RequiredBlock();
373 RequiredKeyword("end",In.NOTHING); 380 RequiredKeyword("end",In.NOTHING);
374 return parser.success(stmt); 381 return parser.success(stmt);
375 } 382 }
376 383
377 private boolean LocalStmt(List<Stmt> stmts) throws ParseException { 384 private boolean LocalStmt(StringBuilder stmts) throws ParseException {
378 parser.begin(); 385 parser.begin();
379 if( !Keyword("local",In.NOTHING) ) 386 if( !Keyword("local",In.NOTHING) )
380 return parser.failure(); 387 return parser.failure();
381 List<String> names = NameList(In.NOTHING); 388 List<String> names = NameList(In.NOTHING);
382 if( names==null ) { 389 if( names==null ) {
392 SetLocalVar[] vars = new SetLocalVar[names.size()]; 399 SetLocalVar[] vars = new SetLocalVar[names.size()];
393 int stackStart = symbolsSize(); 400 int stackStart = symbolsSize();
394 for( int i=0; i<vars.length; i++ ) { 401 for( int i=0; i<vars.length; i++ ) {
395 vars[i] = new SetLocalVar(stackStart+i); 402 vars[i] = new SetLocalVar(stackStart+i);
396 } 403 }
397 stmts.add( new SetStmt( vars, values ) ); 404 stmts.append( new StmtString(new SetStmt( vars, values )).code );
398 } 405 }
399 addSymbols(names); 406 addSymbols(names);
400 return parser.success(); 407 return parser.success();
401 } 408 }
402 409
429 if( name==null ) 436 if( name==null )
430 return parser.failure(null); 437 return parser.failure(null);
431 return parser.success(name); 438 return parser.success(name);
432 } 439 }
433 440
434 private Stmt WhileStmt() throws ParseException { 441 private StmtString WhileStmt() throws ParseException {
435 parser.begin(); 442 parser.begin();
436 if( !Keyword("while",In.NOTHING) ) 443 if( !Keyword("while",In.NOTHING) )
437 return parser.failure(null); 444 return parser.failure(null);
438 Expr cnd = expr(exp(RequiredExpr(In.NOTHING))); 445 ExpString cnd = RequiredExpr(In.NOTHING).expr();
439 RequiredKeyword("do",In.NOTHING); 446 RequiredKeyword("do",In.NOTHING);
440 Stmt loop = RequiredLoopBlock(); 447 StmtString loop = RequiredLoopBlock();
441 RequiredKeyword("end",In.NOTHING); 448 RequiredKeyword("end",In.NOTHING);
442 return parser.success( new WhileStmt(cnd,loop) ); 449 String code = ""
443 } 450 +"try {\n"
444 451 +" while( $Luan.checkBoolean(" + cnd.code + ") ) {\n"
445 private Stmt RepeatStmt() throws ParseException { 452 + loop.code
453 +" }\n"
454 +"} catch(BreakException e) {}\n"
455 ;
456 return parser.success( new StmtString(code) );
457 }
458
459 private StmtString RepeatStmt() throws ParseException {
446 parser.begin(); 460 parser.begin();
447 if( !Keyword("repeat",In.NOTHING) ) 461 if( !Keyword("repeat",In.NOTHING) )
448 return parser.failure(null); 462 return parser.failure(null);
449 Stmt loop = RequiredLoopBlock(); 463 StmtString loop =RequiredLoopBlock();
450 RequiredKeyword("until",In.NOTHING); 464 RequiredKeyword("until",In.NOTHING);
451 Expr cnd = expr(exp(RequiredExpr(In.NOTHING))); 465 ExpString cnd = RequiredExpr(In.NOTHING).expr();
452 return parser.success( new RepeatStmt(loop,cnd) ); 466 String code = ""
453 } 467 +"try {\n"
454 468 +" do {\n"
455 private Stmt RequiredLoopBlock() throws ParseException { 469 + loop.code
470 +" } while( !$Luan.checkBoolean(" + cnd.code + ") );\n"
471 +"} catch(BreakException e) {}\n"
472 ;
473 return parser.success( new StmtString(code) );
474 }
475
476 private StmtString RequiredLoopBlock() throws ParseException {
456 incLoops(); 477 incLoops();
457 Stmt stmt = RequiredBlock(); 478 StmtString stmt = RequiredBlock();
458 decLoops(); 479 decLoops();
459 return stmt; 480 return stmt;
460 } 481 }
461 482
462 private Stmt IfStmt() throws ParseException { 483 private Stmt IfStmt() throws ParseException {
468 489
469 private Stmt IfStmt2() throws ParseException { 490 private Stmt IfStmt2() throws ParseException {
470 parser.currentIndex(); 491 parser.currentIndex();
471 Expr cnd = expr(exp(RequiredExpr(In.NOTHING))); 492 Expr cnd = expr(exp(RequiredExpr(In.NOTHING)));
472 RequiredKeyword("then",In.NOTHING); 493 RequiredKeyword("then",In.NOTHING);
473 Stmt thenBlock = RequiredBlock(); 494 Stmt thenBlock = stmt(RequiredBlock());
474 Stmt elseBlock; 495 Stmt elseBlock;
475 if( Keyword("elseif",In.NOTHING) ) { 496 if( Keyword("elseif",In.NOTHING) ) {
476 elseBlock = IfStmt2(); 497 elseBlock = IfStmt2();
477 } else { 498 } else {
478 elseBlock = Keyword("else",In.NOTHING) ? RequiredBlock() : Stmt.EMPTY; 499 elseBlock = Keyword("else",In.NOTHING) ? stmt(RequiredBlock()) : Stmt.EMPTY;
479 RequiredKeyword("end",In.NOTHING); 500 RequiredKeyword("end",In.NOTHING);
480 } 501 }
481 return new IfStmt(cnd,thenBlock,elseBlock); 502 return new IfStmt(cnd,thenBlock,elseBlock);
482 } 503 }
483 504
503 // throw parser.exception("Expressions expected"); 524 // throw parser.exception("Expressions expected");
504 return parser.failure(null); 525 return parser.failure(null);
505 return parser.success( new SetStmt( vars.toArray(new Settable[0]), values ) ); 526 return parser.success( new SetStmt( vars.toArray(new Settable[0]), values ) );
506 } 527 }
507 528
508 private Stmt ExpressionsStmt() throws ParseException { 529 private StmtString ExpressionsStmt() throws ParseException {
509 parser.begin(); 530 parser.begin();
510 Expressions exp = exp(ExprZ(In.NOTHING)); 531 ExpString exp = ExprZ(In.NOTHING);
511 if( exp instanceof StmtExp ) 532 if( exp != null && exp.isStmt ) {
512 return parser.success( new ExpressionsStmt(exp) ); 533 String code = exp.code;
534 if( exp.isExpr )
535 code = "$Luan.nop(" + code + ")";
536 code += ";\n";
537 return parser.success( new StmtString(code) );
538 }
513 return parser.failure(null); 539 return parser.failure(null);
514 } 540 }
515 541
516 private Settable SettableVar() throws ParseException { 542 private Settable SettableVar() throws ParseException {
517 int start = parser.begin(); 543 int start = parser.begin();
770 Spaces(inParens); 796 Spaces(inParens);
771 frame.isVarArg = true; 797 frame.isVarArg = true;
772 } 798 }
773 RequiredMatch(')'); 799 RequiredMatch(')');
774 Spaces(in); 800 Spaces(in);
775 Stmt block = RequiredBlock(); 801 Stmt block = stmt(RequiredBlock());
776 RequiredKeyword("end",in); 802 RequiredKeyword("end",in);
777 FnDef fnDef = newFnDef(start,block); 803 FnDef fnDef = newFnDef(start,block);
778 frame = frame.parent; 804 frame = frame.parent;
779 return parser.success(fnDef); 805 return parser.success(fnDef);
780 } 806 }
1441 1467
1442 private static Expressions exp(ExpString expStr) { 1468 private static Expressions exp(ExpString expStr) {
1443 return expStr==null ? null : expStr.toExpressions(); 1469 return expStr==null ? null : expStr.toExpressions();
1444 } 1470 }
1445 1471
1472
1473 private static class StmtString {
1474 final String code;
1475
1476 StmtString(Stmt stmt) {
1477 if( stmt==null ) throw new NullPointerException();
1478 int i = $Luan.addStmt(stmt);
1479 code = "$Luan.getStmt(" + i + ").eval($luan);\n";
1480 }
1481
1482 StmtString(String code) {
1483 this.code = code;
1484 }
1485
1486 Stmt toStmt() {
1487 String className = "EXP" + ++classCounter;
1488 String classCode = ""
1489 +"package luan.impl;\n"
1490 +"import luan.LuanException;\n"
1491 +"\n"
1492 +"public class " + className +" implements Stmt {\n"
1493 +" @Override public void eval(LuanStateImpl $luan) throws LuanException {\n"
1494 +" Object $cnd;\n"
1495 +" " + code
1496 +" }\n"
1497 +"}\n"
1498 ;
1499 //System.out.println(code);
1500 try {
1501 Class cls = LuanJavaCompiler.compile("luan.impl."+className,code,classCode);
1502 return (Stmt)cls.newInstance();
1503 } catch(ClassNotFoundException e) {
1504 throw new RuntimeException(e);
1505 } catch(InstantiationException e) {
1506 throw new RuntimeException(e);
1507 } catch(IllegalAccessException e) {
1508 throw new RuntimeException(e);
1509 }
1510 }
1511 }
1512
1513 private static StmtString EMPTY_STMT = new StmtString("");
1514
1515 private static Stmt stmt(StmtString stmtStr) {
1516 return stmtStr==null ? null : stmtStr.toStmt();
1517 }
1518
1519 private static StmtString stmtStr(Stmt stmt) {
1520 return stmt==null ? null : new StmtString(stmt);
1521 }
1522
1446 } 1523 }