Mercurial Hosting > luan
comparison core/src/luan/impl/LuanParser.java @ 666:2f449ccf54d2
use lists to assemble source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 07 Apr 2016 23:36:56 -0600 |
parents | 41f8fdbc3a0a |
children | 08966099aa6d |
comparison
equal
deleted
inserted
replaced
665:41f8fdbc3a0a | 666:2f449ccf54d2 |
---|---|
174 return new ExpressionsExpr(exprs); | 174 return new ExpressionsExpr(exprs); |
175 } | 175 } |
176 | 176 |
177 private FnDef newFnDef(int start,StmtString stmt) { | 177 private FnDef newFnDef(int start,StmtString stmt) { |
178 if( !stmt.hasReturn ) | 178 if( !stmt.hasReturn ) |
179 stmt = new StmtString( stmt.code + "return LuanFunction.NOTHING;\n" ); | 179 stmt.list.add( "return LuanFunction.NOTHING;\n" ); |
180 return toFnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); | 180 return toFnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); |
181 } | 181 } |
182 | 182 |
183 private ExpString newFnExpStr(int start,StmtString stmt) { | 183 private ExpString newFnExpStr(int start,StmtString stmt) { |
184 if( !stmt.hasReturn ) | 184 if( !stmt.hasReturn ) |
185 stmt = new StmtString( stmt.code + "return LuanFunction.NOTHING;\n" ); | 185 stmt.list.add( "return LuanFunction.NOTHING;\n" ); |
186 return toFnExpStr( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); | 186 return toFnExpStr( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); |
187 } | 187 } |
188 | 188 |
189 FnDef Expression() throws ParseException { | 189 FnDef Expression() throws ParseException { |
190 Spaces(In.NOTHING); | 190 Spaces(In.NOTHING); |
191 int start = parser.begin(); | 191 int start = parser.begin(); |
192 ExpString expr = ExprZ(In.NOTHING); | 192 ExpString expr = ExprZ(In.NOTHING); |
193 if( expr != null && parser.endOfInput() ) { | 193 if( expr != null && parser.endOfInput() ) { |
194 String code = "return " + expr.code + ";\n"; | 194 StmtString stmt = new StmtString(); |
195 StmtString stmt = new StmtString(code); | 195 stmt.list.add( "return " ); |
196 stmt.list.addAll( expr.list ); | |
197 stmt.list.add( ";\n" ); | |
196 stmt.hasReturn = true; | 198 stmt.hasReturn = true; |
197 return parser.success(newFnDef(start,stmt)); | 199 return parser.success(newFnDef(start,stmt)); |
198 } | 200 } |
199 return parser.failure(null); | 201 return parser.failure(null); |
200 } | 202 } |
208 return parser.success(newFnDef(start,stmt)); | 210 return parser.success(newFnDef(start,stmt)); |
209 throw parser.exception(); | 211 throw parser.exception(); |
210 } | 212 } |
211 | 213 |
212 private StmtString RequiredBlock() throws ParseException { | 214 private StmtString RequiredBlock() throws ParseException { |
213 StringBuilder stmts = new StringBuilder(); | 215 StmtString stmts = new StmtString(); |
214 int stackStart = symbolsSize(); | 216 int stackStart = symbolsSize(); |
215 boolean isReturn = Stmt(stmts); | 217 boolean isReturn = Stmt(stmts); |
216 while( !isReturn && StmtSep(stmts) ) { | 218 while( !isReturn && StmtSep(stmts) ) { |
217 Spaces(In.NOTHING); | 219 Spaces(In.NOTHING); |
218 isReturn = Stmt(stmts); | 220 isReturn = Stmt(stmts); |
219 } | 221 } |
220 StmtSep(null); | 222 StmtSep(null); |
221 Spaces(In.NOTHING); | 223 Spaces(In.NOTHING); |
222 int stackEnd = symbolsSize(); | 224 int stackEnd = symbolsSize(); |
223 popSymbols( stackEnd - stackStart ); | 225 popSymbols( stackEnd - stackStart ); |
224 if( stmts.length() == 0 ) | 226 if( stmts.list.isEmpty() ) |
225 return EMPTY_STMT; | 227 return stmts; |
226 String code = stmts.toString(); | 228 String code = stmts.toString(); |
227 if( stackStart < stackEnd ) | 229 if( stackStart < stackEnd ) { |
228 code = "" | 230 stmts.list.add( 0, "try {\n" ); |
229 +"try {\n" | 231 stmts.list.add( "" |
230 + code | |
231 +"} finally {\n" | 232 +"} finally {\n" |
232 +" luan.stackClear("+stackStart+","+stackEnd+");\n" | 233 +" luan.stackClear("+stackStart+","+stackEnd+");\n" |
233 +"}\n" | 234 +"}\n" |
234 ; | 235 ); |
235 StmtString stmt = new StmtString(code); | 236 } |
236 stmt.hasReturn = isReturn; | 237 stmts.hasReturn = isReturn; |
237 return stmt; | 238 return stmts; |
238 } | 239 } |
239 | 240 |
240 private boolean StmtSep(StringBuilder stmts) throws ParseException { | 241 private boolean StmtSep(StmtString stmts) throws ParseException { |
241 parser.begin(); | 242 parser.begin(); |
242 if( parser.match( ';' ) ) | 243 if( parser.match( ';' ) ) |
243 return parser.success(); | 244 return parser.success(); |
244 if( EndOfLine() ) | 245 if( EndOfLine() ) |
245 return parser.success(); | 246 return parser.success(); |
246 if( stmts != null ) { | 247 if( stmts != null ) { |
247 // parser.rollback(); | 248 // parser.rollback(); |
248 StmtString stmt = TemplateStmt(); | 249 StmtString stmt = TemplateStmt(); |
249 if( stmt != null ) { | 250 if( stmt != null ) { |
250 stmts.append(stmt.code); | 251 stmts.list.addAll(stmt.list); |
251 return parser.success(); | 252 return parser.success(); |
252 } | 253 } |
253 } | 254 } |
254 return parser.failure(); | 255 return parser.failure(); |
255 } | 256 } |
256 | 257 |
257 private boolean EndOfLine() { | 258 private boolean EndOfLine() { |
258 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); | 259 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); |
259 } | 260 } |
260 | 261 |
261 private boolean Stmt(StringBuilder stmts) throws ParseException { | 262 private boolean Stmt(StmtString stmts) throws ParseException { |
262 if( LocalStmt(stmts) ) | 263 if( LocalStmt(stmts) ) |
263 return false; | 264 return false; |
264 StmtString stmt; | 265 StmtString stmt; |
265 if( (stmt=ReturnStmt()) != null ) { | 266 if( (stmt=ReturnStmt()) != null ) { |
266 stmts.append(stmt.code); | 267 stmts.list.addAll(stmt.list); |
267 return true; | 268 return true; |
268 } | 269 } |
269 if( (stmt=FunctionStmt()) != null | 270 if( (stmt=FunctionStmt()) != null |
270 || (stmt=LocalFunctionStmt()) != null | 271 || (stmt=LocalFunctionStmt()) != null |
271 || (stmt=BreakStmt()) != null | 272 || (stmt=BreakStmt()) != null |
275 || (stmt=RepeatStmt()) != null | 276 || (stmt=RepeatStmt()) != null |
276 || (stmt=IfStmt()) != null | 277 || (stmt=IfStmt()) != null |
277 || (stmt=SetStmt()) != null | 278 || (stmt=SetStmt()) != null |
278 || (stmt=ExpressionsStmt()) != null | 279 || (stmt=ExpressionsStmt()) != null |
279 ) { | 280 ) { |
280 stmts.append(stmt.code); | 281 stmts.list.addAll(stmt.list); |
281 } | 282 } |
282 return false; | 283 return false; |
283 } | 284 } |
284 | 285 |
285 private ExpString indexExpStr(ExpString exp1,ExpString exp2) { | 286 private ExpString indexExpStr(ExpString exp1,ExpString exp2) { |
286 String code = "luan.index(" + exp1.expr().code + "," + exp2.expr().code + ")"; | 287 ExpString exp = new ExpString(true,false); |
287 return new ExpString(code,true,false); | 288 exp.list.add( "luan.index(" ); |
289 exp.list.addAll( exp1.expr().list ); | |
290 exp.list.add( "," ); | |
291 exp.list.addAll( exp2.expr().list ); | |
292 exp.list.add( ")" ); | |
293 return exp; | |
288 } | 294 } |
289 | 295 |
290 private ExpString callExpStr(ExpString fn,ExpString args) { | 296 private ExpString callExpStr(ExpString fn,ExpString args) { |
291 String code = "Luan.checkFunction(" + fn.expr().code + ").call(luan,Luan.array(" + args.code + "))"; | 297 ExpString exp = new ExpString(false,true); |
292 return new ExpString(code,false,true); | 298 exp.list.add( "Luan.checkFunction(" ); |
299 exp.list.addAll( fn.expr().list ); | |
300 exp.list.add( ").call(luan,Luan.array(" ); | |
301 exp.list.addAll( args.list ); | |
302 exp.list.add( "))" ); | |
303 return exp; | |
293 } | 304 } |
294 | 305 |
295 private StmtString TemplateStmt() throws ParseException { | 306 private StmtString TemplateStmt() throws ParseException { |
296 ExpString exprs = TemplateExpressions(In.NOTHING); | 307 ExpString exprs = TemplateExpressions(In.NOTHING); |
297 if( exprs == null ) | 308 if( exprs == null ) |
298 return null; | 309 return null; |
299 String code = "PackageLuan.require(luan,\"luan:Io\")"; | 310 ExpString requireCall = new ExpString(true,false); |
300 ExpString requireCall = new ExpString(code,true,false); | 311 requireCall.list.add( "PackageLuan.require(luan,\"luan:Io\")" ); |
301 ExpString stdoutExp = indexExpStr( requireCall.expr(), constExpStr("stdout") ); | 312 ExpString stdoutExp = indexExpStr( requireCall.expr(), constExpStr("stdout") ); |
302 ExpString writeExp = indexExpStr( stdoutExp, constExpStr("write") ); | 313 ExpString writeExp = indexExpStr( stdoutExp, constExpStr("write") ); |
303 ExpString writeCall = callExpStr( writeExp, exprs ); | 314 ExpString writeCall = callExpStr( writeExp, exprs ); |
304 return new StmtString( writeCall.code + ";\n" ); | 315 StmtString stmt = new StmtString(); |
316 stmt.list.addAll( writeCall.list ); | |
317 stmt.list.add( ";\n" ); | |
318 return stmt; | |
305 } | 319 } |
306 | 320 |
307 private ExpString TemplateExpressions(In in) throws ParseException { | 321 private ExpString TemplateExpressions(In in) throws ParseException { |
308 if( in.template ) | 322 if( in.template ) |
309 return null; | 323 return null; |
338 private StmtString ReturnStmt() throws ParseException { | 352 private StmtString ReturnStmt() throws ParseException { |
339 parser.begin(); | 353 parser.begin(); |
340 if( !Keyword("return",In.NOTHING) ) | 354 if( !Keyword("return",In.NOTHING) ) |
341 return parser.failure(null); | 355 return parser.failure(null); |
342 ExpString exprs = ExpStringList(In.NOTHING); | 356 ExpString exprs = ExpStringList(In.NOTHING); |
343 String code = "return " + (exprs!=null ? exprs.code : "LuanFunction.NOTHING") + ";\n"; | 357 StmtString stmt = new StmtString(); |
344 return parser.success( new StmtString(code) ); | 358 stmt.list.add( "return " ); |
359 if( exprs != null ) | |
360 stmt.list.addAll( exprs.list ); | |
361 else | |
362 stmt.list.add( "LuanFunction.NOTHING" ); | |
363 stmt.list.add( ";\n" ); | |
364 return parser.success( stmt ); | |
345 } | 365 } |
346 | 366 |
347 private StmtString FunctionStmt() throws ParseException { | 367 private StmtString FunctionStmt() throws ParseException { |
348 parser.begin(); | 368 parser.begin(); |
349 if( !Keyword("function",In.NOTHING) ) | 369 if( !Keyword("function",In.NOTHING) ) |
369 return parser.failure(null); | 389 return parser.failure(null); |
370 String name = RequiredName(In.NOTHING); | 390 String name = RequiredName(In.NOTHING); |
371 addSymbol( name ); | 391 addSymbol( name ); |
372 ExpString fnDef = RequiredFunction(In.NOTHING); | 392 ExpString fnDef = RequiredFunction(In.NOTHING); |
373 Settable s = new SetLocalVar(symbolsSize()-1); | 393 Settable s = new SetLocalVar(symbolsSize()-1); |
374 String code = new SettableString(s).code + ".set(luan," + fnDef.code + ");\n"; | 394 StmtString stmt = new StmtString(); |
375 return parser.success( new StmtString(code) ); | 395 stmt.list.add( settableToString(s) ); |
396 stmt.list.add( ".set(luan," ); | |
397 stmt.list.addAll( fnDef.list ); | |
398 stmt.list.add( ");\n" ); | |
399 return parser.success( stmt ); | |
376 } | 400 } |
377 | 401 |
378 private StmtString BreakStmt() throws ParseException { | 402 private StmtString BreakStmt() throws ParseException { |
379 parser.begin(); | 403 parser.begin(); |
380 if( !Keyword("break",In.NOTHING) ) | 404 if( !Keyword("break",In.NOTHING) ) |
381 return parser.failure(null); | 405 return parser.failure(null); |
382 if( frame.loops <= 0 ) | 406 if( frame.loops <= 0 ) |
383 throw parser.exception("'break' outside of loop"); | 407 throw parser.exception("'break' outside of loop"); |
384 return parser.success( new StmtString("break;\n") ); | 408 StmtString stmt = new StmtString(); |
409 stmt.list.add( "break;\n" ); | |
410 return parser.success( stmt ); | |
385 } | 411 } |
386 | 412 |
387 int forCounter = 0; | 413 int forCounter = 0; |
388 | 414 |
389 private StmtString ForStmt() throws ParseException { | 415 private StmtString ForStmt() throws ParseException { |
406 ExpString firstVar = new ExpString(new GetLocalVar(stackStart)); | 432 ExpString firstVar = new ExpString(new GetLocalVar(stackStart)); |
407 addSymbols(names); | 433 addSymbols(names); |
408 StmtString loop = RequiredLoopBlock(); | 434 StmtString loop = RequiredLoopBlock(); |
409 RequiredKeyword("end",In.NOTHING); | 435 RequiredKeyword("end",In.NOTHING); |
410 String fnVar = "fn"+ ++forCounter; | 436 String fnVar = "fn"+ ++forCounter; |
411 String code = "" | 437 StmtString stmt = new StmtString(); |
438 stmt.list.add( "" | |
412 +"try {\n" | 439 +"try {\n" |
413 +"LuanFunction "+fnVar+" = Luan.checkFunction(" + expr.code + ");\n" | 440 +"LuanFunction "+fnVar+" = Luan.checkFunction(" |
441 ); | |
442 stmt.list.addAll( expr.list ); | |
443 stmt.list.add( "" | |
444 + ");\n" | |
414 +"while(true) {\n" | 445 +"while(true) {\n" |
415 +"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n" | 446 +"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n" |
416 +"luan.stackSet(i,null);\n" | 447 +"luan.stackSet(i,null);\n" |
417 +"}\n" | 448 +"}\n" |
418 +"LuanImpl.set(luan," + varsStr + ", "+fnVar+".call(luan) );\n" | 449 +"LuanImpl.set(luan," + varsStr + ", "+fnVar+".call(luan) );\n" |
419 +"if( " + firstVar.code + "==null ) break;\n" | 450 +"if( " |
420 + loop.code | 451 ); |
452 stmt.list.addAll( firstVar.list ); | |
453 stmt.list.add( "==null ) break;\n" ); | |
454 stmt.list.addAll( loop.list ); | |
455 stmt.list.add( "" | |
421 +"}" | 456 +"}" |
422 +"} finally {\n" | 457 +"} finally {\n" |
423 +"luan.stackClear("+stackStart+","+symbolsSize()+");\n" | 458 +"luan.stackClear("+stackStart+","+symbolsSize()+");\n" |
424 +"}\n" | 459 +"}\n" |
425 ; | 460 ); |
426 StmtString stmt = new StmtString(code); | |
427 popSymbols( symbolsSize() - stackStart ); | 461 popSymbols( symbolsSize() - stackStart ); |
428 return parser.success(stmt); | 462 return parser.success(stmt); |
429 } | 463 } |
430 | 464 |
431 private StmtString DoStmt() throws ParseException { | 465 private StmtString DoStmt() throws ParseException { |
435 StmtString stmt = RequiredBlock(); | 469 StmtString stmt = RequiredBlock(); |
436 RequiredKeyword("end",In.NOTHING); | 470 RequiredKeyword("end",In.NOTHING); |
437 return parser.success(stmt); | 471 return parser.success(stmt); |
438 } | 472 } |
439 | 473 |
440 private boolean LocalStmt(StringBuilder stmts) throws ParseException { | 474 private boolean LocalStmt(StmtString stmts) throws ParseException { |
441 parser.begin(); | 475 parser.begin(); |
442 if( !Keyword("local",In.NOTHING) ) | 476 if( !Keyword("local",In.NOTHING) ) |
443 return parser.failure(); | 477 return parser.failure(); |
444 List<String> names = NameList(In.NOTHING); | 478 List<String> names = NameList(In.NOTHING); |
445 if( names==null ) { | 479 if( names==null ) { |
456 int stackStart = symbolsSize(); | 490 int stackStart = symbolsSize(); |
457 for( int i=0; i<vars.length; i++ ) { | 491 for( int i=0; i<vars.length; i++ ) { |
458 vars[i] = new SetLocalVar(stackStart+i); | 492 vars[i] = new SetLocalVar(stackStart+i); |
459 } | 493 } |
460 String varsStr = varsToString(vars); | 494 String varsStr = varsToString(vars); |
461 String code = "LuanImpl.set(luan," + varsStr + "," + values.code + ");\n"; | 495 stmts.list.add( "LuanImpl.set(luan," + varsStr + "," ); |
462 stmts.append(code); | 496 stmts.list.addAll( values.list ); |
497 stmts.list.add( ");\n" ); | |
463 } | 498 } |
464 addSymbols(names); | 499 addSymbols(names); |
465 return parser.success(); | 500 return parser.success(); |
466 } | 501 } |
467 | 502 |
502 return parser.failure(null); | 537 return parser.failure(null); |
503 ExpString cnd = RequiredExpr(In.NOTHING).expr(); | 538 ExpString cnd = RequiredExpr(In.NOTHING).expr(); |
504 RequiredKeyword("do",In.NOTHING); | 539 RequiredKeyword("do",In.NOTHING); |
505 StmtString loop = RequiredLoopBlock(); | 540 StmtString loop = RequiredLoopBlock(); |
506 RequiredKeyword("end",In.NOTHING); | 541 RequiredKeyword("end",In.NOTHING); |
507 String code = "" | 542 StmtString stmt = new StmtString(); |
508 +"while( Luan.checkBoolean(" + cnd.code + ") ) {\n" | 543 stmt.list.add( "while( Luan.checkBoolean(" ); |
509 + loop.code | 544 stmt.list.addAll( cnd.list ); |
510 +"}\n" | 545 stmt.list.add( ") ) {\n" ); |
511 ; | 546 stmt.list.addAll( loop.list ); |
512 return parser.success( new StmtString(code) ); | 547 stmt.list.add( "}\n" ); |
548 return parser.success( stmt ); | |
513 } | 549 } |
514 | 550 |
515 private StmtString RepeatStmt() throws ParseException { | 551 private StmtString RepeatStmt() throws ParseException { |
516 parser.begin(); | 552 parser.begin(); |
517 if( !Keyword("repeat",In.NOTHING) ) | 553 if( !Keyword("repeat",In.NOTHING) ) |
518 return parser.failure(null); | 554 return parser.failure(null); |
519 StmtString loop =RequiredLoopBlock(); | 555 StmtString loop =RequiredLoopBlock(); |
520 RequiredKeyword("until",In.NOTHING); | 556 RequiredKeyword("until",In.NOTHING); |
521 ExpString cnd = RequiredExpr(In.NOTHING).expr(); | 557 ExpString cnd = RequiredExpr(In.NOTHING).expr(); |
522 String code = "" | 558 StmtString stmt = new StmtString(); |
523 +"do {\n" | 559 stmt.list.add( "do {\n" ); |
524 + loop.code | 560 stmt.list.addAll( loop.list ); |
525 +"} while( !Luan.checkBoolean(" + cnd.code + ") );\n" | 561 stmt.list.add( "} while( !Luan.checkBoolean(" ); |
526 ; | 562 stmt.list.addAll( cnd.list ); |
527 return parser.success( new StmtString(code) ); | 563 stmt.list.add( ") );\n" ); |
564 return parser.success( stmt ); | |
528 } | 565 } |
529 | 566 |
530 private StmtString RequiredLoopBlock() throws ParseException { | 567 private StmtString RequiredLoopBlock() throws ParseException { |
531 incLoops(); | 568 incLoops(); |
532 StmtString stmt = RequiredBlock(); | 569 StmtString stmt = RequiredBlock(); |
536 | 573 |
537 private StmtString IfStmt() throws ParseException { | 574 private StmtString IfStmt() throws ParseException { |
538 parser.begin(); | 575 parser.begin(); |
539 if( !Keyword("if",In.NOTHING) ) | 576 if( !Keyword("if",In.NOTHING) ) |
540 return parser.failure(null); | 577 return parser.failure(null); |
541 StringBuilder sb = new StringBuilder(); | 578 StmtString stmt = new StmtString(); |
542 ExpString cnd; | 579 ExpString cnd; |
543 StmtString block; | 580 StmtString block; |
544 cnd = RequiredExpr(In.NOTHING).expr(); | 581 cnd = RequiredExpr(In.NOTHING).expr(); |
545 RequiredKeyword("then",In.NOTHING); | 582 RequiredKeyword("then",In.NOTHING); |
546 block = RequiredBlock(); | 583 block = RequiredBlock(); |
547 sb.append( "if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); | 584 stmt.list.add( "if( Luan.checkBoolean(" ); |
585 stmt.list.addAll( cnd.list ); | |
586 stmt.list.add( ") ) {\n" ); | |
587 stmt.list.addAll( block.list ); | |
548 while( Keyword("elseif",In.NOTHING) ) { | 588 while( Keyword("elseif",In.NOTHING) ) { |
549 cnd = RequiredExpr(In.NOTHING).expr(); | 589 cnd = RequiredExpr(In.NOTHING).expr(); |
550 RequiredKeyword("then",In.NOTHING); | 590 RequiredKeyword("then",In.NOTHING); |
551 block = RequiredBlock(); | 591 block = RequiredBlock(); |
552 sb.append( "} else if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); | 592 stmt.list.add( "} else if( Luan.checkBoolean(" ); |
593 stmt.list.addAll( cnd.list ); | |
594 stmt.list.add( ") ) {\n" ); | |
595 stmt.list.addAll( block.list ); | |
553 } | 596 } |
554 if( Keyword("else",In.NOTHING) ) { | 597 if( Keyword("else",In.NOTHING) ) { |
555 block = RequiredBlock(); | 598 block = RequiredBlock(); |
556 sb.append( "} else {\n" ).append( block.code ); | 599 stmt.list.add( "} else {\n" ); |
600 stmt.list.addAll( block.list ); | |
557 } | 601 } |
558 RequiredKeyword("end",In.NOTHING); | 602 RequiredKeyword("end",In.NOTHING); |
559 sb.append( "}\n" ); | 603 stmt.list.add( "}\n" ); |
560 return parser.success( new StmtString(sb.toString()) ); | 604 return parser.success( stmt ); |
561 } | 605 } |
562 | 606 |
563 private StmtString SetStmt() throws ParseException { | 607 private StmtString SetStmt() throws ParseException { |
564 parser.begin(); | 608 parser.begin(); |
565 List<Var> vars = new ArrayList<Var>(); | 609 List<Var> vars = new ArrayList<Var>(); |
582 // throw parser.exception("Expressions expected"); | 626 // throw parser.exception("Expressions expected"); |
583 return parser.failure(null); | 627 return parser.failure(null); |
584 int n = vars.size(); | 628 int n = vars.size(); |
585 if( n == 1 ) | 629 if( n == 1 ) |
586 return parser.success( vars.get(0).set(values) ); | 630 return parser.success( vars.get(0).set(values) ); |
587 StringBuilder sb = new StringBuilder(); | 631 StmtString stmt = new StmtString(); |
588 sb.append( "t = " + values.code + ";\n" ); | 632 stmt.list.add( "t = " ); |
589 ExpString t = new ExpString("t",true,false); | 633 stmt.list.addAll( values.list ); |
590 sb.append( vars.get(0).set(new ExpString("t",true,false)).code ); | 634 stmt.list.add( ";\n" ); |
635 ExpString t = new ExpString(true,false); | |
636 t.list.add( "t" ); | |
637 stmt.list.addAll( vars.get(0).set(t).list ); | |
591 for( int i=1; i<n; i++ ) { | 638 for( int i=1; i<n; i++ ) { |
592 sb.append( vars.get(i).set(new ExpString("LuanImpl.pick(t,"+i+")",true,false)).code ); | 639 t.list.clear(); |
593 } | 640 t.list.add( "LuanImpl.pick(t,"+i+")" ); |
594 return parser.success( new StmtString(sb.toString()) ); | 641 stmt.list.addAll( vars.get(i).set(t).list ); |
642 } | |
643 return parser.success( stmt ); | |
595 } | 644 } |
596 | 645 |
597 private static String varsToString(Settable[] vars) { | 646 private static String varsToString(Settable[] vars) { |
598 StringBuilder sb = new StringBuilder(); | 647 StringBuilder sb = new StringBuilder(); |
599 sb.append( "new Settable[]{" ); | 648 sb.append( "new Settable[]{" ); |
600 for( Settable v : vars ) { | 649 for( Settable v : vars ) { |
601 sb.append( new SettableString(v).code ).append( ',' ); | 650 sb.append( settableToString(v) ).append( ',' ); |
602 } | 651 } |
603 sb.append( "}" ); | 652 sb.append( "}" ); |
604 return sb.toString(); | 653 return sb.toString(); |
605 } | 654 } |
606 | 655 |
607 private StmtString ExpressionsStmt() throws ParseException { | 656 private StmtString ExpressionsStmt() throws ParseException { |
608 parser.begin(); | 657 parser.begin(); |
609 ExpString exp = ExprZ(In.NOTHING); | 658 ExpString exp = ExprZ(In.NOTHING); |
610 if( exp != null && exp.isStmt ) { | 659 if( exp != null && exp.isStmt ) { |
611 String code = exp.code; | 660 StmtString stmt = new StmtString(); |
612 if( exp.isExpr ) | 661 if( exp.isExpr ) { |
613 code = "LuanImpl.nop(" + code + ")"; | 662 stmt.list.add( "LuanImpl.nop(" ); |
614 code += ";\n"; | 663 stmt.list.addAll( exp.list ); |
615 return parser.success( new StmtString(code) ); | 664 stmt.list.add( ")" ); |
665 } else { | |
666 stmt.list.addAll( exp.list ); | |
667 } | |
668 stmt.list.add( ";\n" ); | |
669 return parser.success( stmt ); | |
616 } | 670 } |
617 return parser.failure(null); | 671 return parser.failure(null); |
618 } | 672 } |
619 | 673 |
620 private Var SettableVar() throws ParseException { | 674 private Var SettableVar() throws ParseException { |
640 if( exp==null ) | 694 if( exp==null ) |
641 return parser.failure(null); | 695 return parser.failure(null); |
642 while( Keyword("or",in) ) { | 696 while( Keyword("or",in) ) { |
643 exp = exp.expr(); | 697 exp = exp.expr(); |
644 ExpString exp2 = required(RelExpr(in)).expr(); | 698 ExpString exp2 = required(RelExpr(in)).expr(); |
645 String code = "(LuanImpl.cnd(t = " + exp.code + ") ? t : (" + exp2.code + "))"; | 699 ExpString newExp = new ExpString(true,true); |
646 exp = new ExpString(code,true,true); | 700 newExp.list.add( "(LuanImpl.cnd(t = " ); |
701 newExp.list.addAll( exp.list ); | |
702 newExp.list.add( ") ? t : (" ); | |
703 newExp.list.addAll( exp2.list ); | |
704 newExp.list.add( "))" ); | |
705 exp = newExp; | |
647 } | 706 } |
648 return parser.success(exp); | 707 return parser.success(exp); |
649 } | 708 } |
650 | 709 |
651 private ExpString AndExpr(In in) throws ParseException { | 710 private ExpString AndExpr(In in) throws ParseException { |
654 if( exp==null ) | 713 if( exp==null ) |
655 return parser.failure(null); | 714 return parser.failure(null); |
656 while( Keyword("and",in) ) { | 715 while( Keyword("and",in) ) { |
657 exp = exp.expr(); | 716 exp = exp.expr(); |
658 ExpString exp2 = required(RelExpr(in)).expr(); | 717 ExpString exp2 = required(RelExpr(in)).expr(); |
659 String code = "(LuanImpl.cnd(t = " + exp.code + ") ? (" + exp2.code + ") : t)"; | 718 ExpString newExp = new ExpString(true,true); |
660 exp = new ExpString(code,true,true); | 719 newExp.list.add( "(LuanImpl.cnd(t = " ); |
720 newExp.list.addAll( exp.list ); | |
721 newExp.list.add( ") ? (" ); | |
722 newExp.list.addAll( exp2.list ); | |
723 newExp.list.add( ") : t)" ); | |
724 exp = newExp; | |
661 } | 725 } |
662 return parser.success(exp); | 726 return parser.success(exp); |
663 } | 727 } |
664 | 728 |
665 private ExpString RelExpr(In in) throws ParseException { | 729 private ExpString RelExpr(In in) throws ParseException { |
670 while(true) { | 734 while(true) { |
671 if( parser.match("==") ) { | 735 if( parser.match("==") ) { |
672 Spaces(in); | 736 Spaces(in); |
673 exp = exp.expr(); | 737 exp = exp.expr(); |
674 ExpString exp2 = required(ConcatExpr(in)).expr(); | 738 ExpString exp2 = required(ConcatExpr(in)).expr(); |
675 String code = "LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; | 739 ExpString newExp = new ExpString(true,false); |
676 exp = new ExpString(code,true,false); | 740 newExp.list.add( "LuanImpl.eq(luan," ); |
741 newExp.list.addAll( exp.list ); | |
742 newExp.list.add( "," ); | |
743 newExp.list.addAll( exp2.list ); | |
744 newExp.list.add( ")" ); | |
745 exp = newExp; | |
677 } else if( parser.match("~=") ) { | 746 } else if( parser.match("~=") ) { |
678 Spaces(in); | 747 Spaces(in); |
679 exp = exp.expr(); | 748 exp = exp.expr(); |
680 ExpString exp2 = required(ConcatExpr(in)).expr(); | 749 ExpString exp2 = required(ConcatExpr(in)).expr(); |
681 String code = "!LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; | 750 ExpString newExp = new ExpString(true,false); |
682 exp = new ExpString(code,true,false); | 751 newExp.list.add( "!LuanImpl.eq(luan," ); |
752 newExp.list.addAll( exp.list ); | |
753 newExp.list.add( "," ); | |
754 newExp.list.addAll( exp2.list ); | |
755 newExp.list.add( ")" ); | |
756 exp = newExp; | |
683 } else if( parser.match("<=") ) { | 757 } else if( parser.match("<=") ) { |
684 Spaces(in); | 758 Spaces(in); |
685 exp = exp.expr(); | 759 exp = exp.expr(); |
686 ExpString exp2 = required(ConcatExpr(in)).expr(); | 760 ExpString exp2 = required(ConcatExpr(in)).expr(); |
687 String code = "LuanImpl.le(luan," + exp.code + "," + exp2.code + ")"; | 761 ExpString newExp = new ExpString(true,false); |
688 exp = new ExpString(code,true,false); | 762 newExp.list.add( "LuanImpl.le(luan," ); |
763 newExp.list.addAll( exp.list ); | |
764 newExp.list.add( "," ); | |
765 newExp.list.addAll( exp2.list ); | |
766 newExp.list.add( ")" ); | |
767 exp = newExp; | |
689 } else if( parser.match(">=") ) { | 768 } else if( parser.match(">=") ) { |
690 Spaces(in); | 769 Spaces(in); |
691 exp = exp.expr(); | 770 exp = exp.expr(); |
692 ExpString exp2 = required(ConcatExpr(in)).expr(); | 771 ExpString exp2 = required(ConcatExpr(in)).expr(); |
693 String code = "LuanImpl.le(luan," + exp2.code + "," + exp.code + ")"; | 772 ExpString newExp = new ExpString(true,false); |
694 exp = new ExpString(code,true,false); | 773 newExp.list.add( "LuanImpl.le(luan," ); |
774 newExp.list.addAll( exp2.list ); | |
775 newExp.list.add( "," ); | |
776 newExp.list.addAll( exp.list ); | |
777 newExp.list.add( ")" ); | |
778 exp = newExp; | |
695 } else if( parser.match("<") ) { | 779 } else if( parser.match("<") ) { |
696 Spaces(in); | 780 Spaces(in); |
697 exp = exp.expr(); | 781 exp = exp.expr(); |
698 ExpString exp2 = required(ConcatExpr(in)).expr(); | 782 ExpString exp2 = required(ConcatExpr(in)).expr(); |
699 String code = "LuanImpl.lt(luan," + exp.code + "," + exp2.code + ")"; | 783 ExpString newExp = new ExpString(true,false); |
700 exp = new ExpString(code,true,false); | 784 newExp.list.add( "LuanImpl.lt(luan," ); |
701 } else if( parser.match(">") ) { | 785 newExp.list.addAll( exp.list ); |
786 newExp.list.add( "," ); | |
787 newExp.list.addAll( exp2.list ); | |
788 newExp.list.add( ")" ); | |
789 exp = newExp; | |
790 } else if( parser.match(">") ) { | |
702 Spaces(in); | 791 Spaces(in); |
703 exp = exp.expr(); | 792 exp = exp.expr(); |
704 ExpString exp2 = required(ConcatExpr(in)).expr(); | 793 ExpString exp2 = required(ConcatExpr(in)).expr(); |
705 String code = "LuanImpl.lt(luan," + exp2.code + "," + exp.code + ")"; | 794 ExpString newExp = new ExpString(true,false); |
706 exp = new ExpString(code,true,false); | 795 newExp.list.add( "LuanImpl.lt(luan," ); |
796 newExp.list.addAll( exp2.list ); | |
797 newExp.list.add( "," ); | |
798 newExp.list.addAll( exp.list ); | |
799 newExp.list.add( ")" ); | |
800 exp = newExp; | |
707 } else | 801 } else |
708 break; | 802 break; |
709 } | 803 } |
710 return parser.success(exp); | 804 return parser.success(exp); |
711 } | 805 } |
717 return parser.failure(null); | 811 return parser.failure(null); |
718 if( parser.match("..") ) { | 812 if( parser.match("..") ) { |
719 Spaces(in); | 813 Spaces(in); |
720 exp = exp.expr(); | 814 exp = exp.expr(); |
721 ExpString exp2 = required(ConcatExpr(in)).expr(); | 815 ExpString exp2 = required(ConcatExpr(in)).expr(); |
722 String code = "LuanImpl.concat(luan," + exp.code + "," + exp2.code + ")"; | 816 ExpString newExp = new ExpString(true,false); |
723 exp = new ExpString(code,true,false); | 817 newExp.list.add( "LuanImpl.concat(luan," ); |
818 newExp.list.addAll( exp.list ); | |
819 newExp.list.add( "," ); | |
820 newExp.list.addAll( exp2.list ); | |
821 newExp.list.add( ")" ); | |
822 exp = newExp; | |
724 } | 823 } |
725 return parser.success(exp); | 824 return parser.success(exp); |
726 } | 825 } |
727 | 826 |
728 private ExpString SumExpr(In in) throws ParseException { | 827 private ExpString SumExpr(In in) throws ParseException { |
733 while(true) { | 832 while(true) { |
734 if( parser.match('+') ) { | 833 if( parser.match('+') ) { |
735 Spaces(in); | 834 Spaces(in); |
736 exp = exp.expr(); | 835 exp = exp.expr(); |
737 ExpString exp2 = required(TermExpr(in)).expr(); | 836 ExpString exp2 = required(TermExpr(in)).expr(); |
738 String code = "LuanImpl.add(luan," + exp.code + "," + exp2.code + ")"; | 837 ExpString newExp = new ExpString(true,false); |
739 exp = new ExpString(code,true,false); | 838 newExp.list.add( "LuanImpl.add(luan," ); |
839 newExp.list.addAll( exp.list ); | |
840 newExp.list.add( "," ); | |
841 newExp.list.addAll( exp2.list ); | |
842 newExp.list.add( ")" ); | |
843 exp = newExp; | |
740 } else if( Minus() ) { | 844 } else if( Minus() ) { |
741 Spaces(in); | 845 Spaces(in); |
742 exp = exp.expr(); | 846 exp = exp.expr(); |
743 ExpString exp2 = required(TermExpr(in)).expr(); | 847 ExpString exp2 = required(TermExpr(in)).expr(); |
744 String code = "LuanImpl.sub(luan," + exp.code + "," + exp2.code + ")"; | 848 ExpString newExp = new ExpString(true,false); |
745 exp = new ExpString(code,true,false); | 849 newExp.list.add( "LuanImpl.sub(luan," ); |
850 newExp.list.addAll( exp.list ); | |
851 newExp.list.add( "," ); | |
852 newExp.list.addAll( exp2.list ); | |
853 newExp.list.add( ")" ); | |
854 exp = newExp; | |
746 } else | 855 } else |
747 break; | 856 break; |
748 } | 857 } |
749 return parser.success(exp); | 858 return parser.success(exp); |
750 } | 859 } |
762 while(true) { | 871 while(true) { |
763 if( parser.match('*') ) { | 872 if( parser.match('*') ) { |
764 Spaces(in); | 873 Spaces(in); |
765 exp = exp.expr(); | 874 exp = exp.expr(); |
766 ExpString exp2 = required(UnaryExpr(in)).expr(); | 875 ExpString exp2 = required(UnaryExpr(in)).expr(); |
767 String code = "LuanImpl.mul(luan," + exp.code + "," + exp2.code + ")"; | 876 ExpString newExp = new ExpString(true,false); |
768 exp = new ExpString(code,true,false); | 877 newExp.list.add( "LuanImpl.mul(luan," ); |
878 newExp.list.addAll( exp.list ); | |
879 newExp.list.add( "," ); | |
880 newExp.list.addAll( exp2.list ); | |
881 newExp.list.add( ")" ); | |
882 exp = newExp; | |
769 } else if( parser.match('/') ) { | 883 } else if( parser.match('/') ) { |
770 Spaces(in); | 884 Spaces(in); |
771 exp = exp.expr(); | 885 exp = exp.expr(); |
772 ExpString exp2 = required(UnaryExpr(in)).expr(); | 886 ExpString exp2 = required(UnaryExpr(in)).expr(); |
773 String code = "LuanImpl.div(luan," + exp.code + "," + exp2.code + ")"; | 887 ExpString newExp = new ExpString(true,false); |
774 exp = new ExpString(code,true,false); | 888 newExp.list.add( "LuanImpl.div(luan," ); |
889 newExp.list.addAll( exp.list ); | |
890 newExp.list.add( "," ); | |
891 newExp.list.addAll( exp2.list ); | |
892 newExp.list.add( ")" ); | |
893 exp = newExp; | |
775 } else if( Mod() ) { | 894 } else if( Mod() ) { |
776 Spaces(in); | 895 Spaces(in); |
777 exp = exp.expr(); | 896 exp = exp.expr(); |
778 ExpString exp2 = required(UnaryExpr(in)).expr(); | 897 ExpString exp2 = required(UnaryExpr(in)).expr(); |
779 String code = "LuanImpl.mod(luan," + exp.code + "," + exp2.code + ")"; | 898 ExpString newExp = new ExpString(true,false); |
780 exp = new ExpString(code,true,false); | 899 newExp.list.add( "LuanImpl.mod(luan," ); |
900 newExp.list.addAll( exp.list ); | |
901 newExp.list.add( "," ); | |
902 newExp.list.addAll( exp2.list ); | |
903 newExp.list.add( ")" ); | |
904 exp = newExp; | |
781 } else | 905 } else |
782 break; | 906 break; |
783 } | 907 } |
784 return parser.success(exp); | 908 return parser.success(exp); |
785 } | 909 } |
792 private ExpString UnaryExpr(In in) throws ParseException { | 916 private ExpString UnaryExpr(In in) throws ParseException { |
793 parser.begin(); | 917 parser.begin(); |
794 if( parser.match('#') ) { | 918 if( parser.match('#') ) { |
795 Spaces(in); | 919 Spaces(in); |
796 ExpString exp = required(UnaryExpr(in)).expr(); | 920 ExpString exp = required(UnaryExpr(in)).expr(); |
797 String code = "LuanImpl.len(luan," + exp.code + ")"; | 921 ExpString newExp = new ExpString(true,false); |
798 exp = new ExpString(code,true,false); | 922 newExp.list.add( "LuanImpl.len(luan," ); |
799 return parser.success(exp); | 923 newExp.list.addAll( exp.list ); |
924 newExp.list.add( ")" ); | |
925 return parser.success(newExp); | |
800 } | 926 } |
801 if( Minus() ) { | 927 if( Minus() ) { |
802 Spaces(in); | 928 Spaces(in); |
803 ExpString exp = required(UnaryExpr(in)).expr(); | 929 ExpString exp = required(UnaryExpr(in)).expr(); |
804 String code = "LuanImpl.unm(luan," + exp.code + ")"; | 930 ExpString newExp = new ExpString(true,false); |
805 exp = new ExpString(code,true,false); | 931 newExp.list.add( "LuanImpl.unm(luan," ); |
806 return parser.success(exp); | 932 newExp.list.addAll( exp.list ); |
933 newExp.list.add( ")" ); | |
934 return parser.success(newExp); | |
807 } | 935 } |
808 if( Keyword("not",in) ) { | 936 if( Keyword("not",in) ) { |
809 Spaces(in); | 937 Spaces(in); |
810 ExpString exp = required(UnaryExpr(in)).expr(); | 938 ExpString exp = required(UnaryExpr(in)).expr(); |
811 String code = "!Luan.checkBoolean(" + exp.code + ")"; | 939 ExpString newExp = new ExpString(true,false); |
812 exp = new ExpString(code,true,false); | 940 newExp.list.add( "!Luan.checkBoolean(" ); |
813 return parser.success(exp); | 941 newExp.list.addAll( exp.list ); |
942 newExp.list.add( ")" ); | |
943 return parser.success(newExp); | |
814 } | 944 } |
815 ExpString exp = PowExpr(in); | 945 ExpString exp = PowExpr(in); |
816 if( exp==null ) | 946 if( exp==null ) |
817 return parser.failure(null); | 947 return parser.failure(null); |
818 return parser.success(exp); | 948 return parser.success(exp); |
824 if( exp1==null ) | 954 if( exp1==null ) |
825 return parser.failure(null); | 955 return parser.failure(null); |
826 if( parser.match('^') ) { | 956 if( parser.match('^') ) { |
827 Spaces(in); | 957 Spaces(in); |
828 ExpString exp2 = required(PowExpr(in)); | 958 ExpString exp2 = required(PowExpr(in)); |
829 String code = "LuanImpl.pow(luan," + exp1.code + "," + exp2.code + ")"; | 959 ExpString newExp = new ExpString(true,false); |
830 exp1 = new ExpString(code,true,false); | 960 newExp.list.add( "LuanImpl.pow(luan," ); |
961 newExp.list.addAll( exp1.expr().list ); | |
962 newExp.list.add( "," ); | |
963 newExp.list.addAll( exp2.expr().list ); | |
964 newExp.list.add( ")" ); | |
965 exp1 = newExp; | |
831 } | 966 } |
832 return parser.success(exp1); | 967 return parser.success(exp1); |
833 } | 968 } |
834 | 969 |
835 private ExpString SingleExpr(In in) throws ParseException { | 970 private ExpString SingleExpr(In in) throws ParseException { |
904 if( exp != null ) | 1039 if( exp != null ) |
905 builder.add(exp); | 1040 builder.add(exp); |
906 if( !parser.match('}') ) | 1041 if( !parser.match('}') ) |
907 throw parser.exception("Expected table element or '}'"); | 1042 throw parser.exception("Expected table element or '}'"); |
908 Spaces(in); | 1043 Spaces(in); |
909 String code = "LuanImpl.table(" + expString(builder).code + ")"; | 1044 exp = new ExpString(true,false); |
910 return parser.success( new ExpString(code,true,false) ); | 1045 exp.list.add( "LuanImpl.table(" ); |
1046 exp.list.addAll( expString(builder).list ); | |
1047 exp.list.add( ")" ); | |
1048 return parser.success( exp ); | |
911 } | 1049 } |
912 | 1050 |
913 private boolean FieldSep() throws ParseException { | 1051 private boolean FieldSep() throws ParseException { |
914 return parser.anyOf(",;") || EndOfLine(); | 1052 return parser.anyOf(",;") || EndOfLine(); |
915 } | 1053 } |
920 if( exp==null ) | 1058 if( exp==null ) |
921 exp = NameExpr(In.NOTHING); | 1059 exp = NameExpr(In.NOTHING); |
922 if( exp!=null && parser.match('=') ) { | 1060 if( exp!=null && parser.match('=') ) { |
923 Spaces(In.NOTHING); | 1061 Spaces(In.NOTHING); |
924 ExpString val = RequiredExpr(In.NOTHING).expr(); | 1062 ExpString val = RequiredExpr(In.NOTHING).expr(); |
925 String code = "new TableField(" + exp.code + "," + val.code + ")"; | 1063 ExpString newExp = new ExpString(true,false); |
926 builder.add( new ExpString(code,true,false) ); | 1064 newExp.list.add( "new TableField(" ); |
1065 newExp.list.addAll( exp.list ); | |
1066 newExp.list.add( "," ); | |
1067 newExp.list.addAll( val.list ); | |
1068 newExp.list.add( ")" ); | |
1069 builder.add( newExp ); | |
927 return parser.success(); | 1070 return parser.success(); |
928 } | 1071 } |
929 parser.rollback(); | 1072 parser.rollback(); |
930 ExpString exprs = ExprZ(In.NOTHING); | 1073 ExpString exprs = ExprZ(In.NOTHING); |
931 if( exprs != null ) { | 1074 if( exprs != null ) { |
1043 parser.failure(null); | 1186 parser.failure(null); |
1044 throw parser.exception("name '"+name+"' not defined"); | 1187 throw parser.exception("name '"+name+"' not defined"); |
1045 } | 1188 } |
1046 | 1189 |
1047 public StmtString set(ExpString val) throws ParseException { | 1190 public StmtString set(ExpString val) throws ParseException { |
1048 String code = new SettableString(settable()).code + ".set(luan," + val.expr().code + ");\n"; | 1191 StmtString stmt = new StmtString(); |
1049 return new StmtString(code); | 1192 stmt.list.add( settableToString(settable()) + ".set(luan," ); |
1193 stmt.list.addAll( val.expr().list ); | |
1194 stmt.list.add( ");\n" ); | |
1195 return stmt; | |
1050 } | 1196 } |
1051 }; | 1197 }; |
1052 } | 1198 } |
1053 | 1199 |
1054 private Var exprVar(final ExpString expr) { | 1200 private Var exprVar(final ExpString expr) { |
1082 public Settable settable() { | 1228 public Settable settable() { |
1083 return new SetTableEntry(expr(LuanParser.exp(table)),expr(LuanParser.exp(key))); | 1229 return new SetTableEntry(expr(LuanParser.exp(table)),expr(LuanParser.exp(key))); |
1084 } | 1230 } |
1085 */ | 1231 */ |
1086 public StmtString set(ExpString val) { | 1232 public StmtString set(ExpString val) { |
1087 String code = "LuanImpl.put(luan," + table.expr().code + "," + key.expr().code + "," + val.expr().code + ");\n"; | 1233 StmtString stmt = new StmtString(); |
1088 return new StmtString(code); | 1234 stmt.list.add( "LuanImpl.put(luan," ); |
1235 stmt.list.addAll( table.expr().list ); | |
1236 stmt.list.add( "," ); | |
1237 stmt.list.addAll( key.expr().list ); | |
1238 stmt.list.add( "," ); | |
1239 stmt.list.addAll( val.expr().list ); | |
1240 stmt.list.add( ");\n" ); | |
1241 return stmt; | |
1089 } | 1242 } |
1090 }; | 1243 }; |
1091 } | 1244 } |
1092 | 1245 |
1093 private ExpString Args(In in,ExpString fn,List<ExpString> builder) throws ParseException { | 1246 private ExpString Args(In in,ExpString fn,List<ExpString> builder) throws ParseException { |
1251 "while" | 1404 "while" |
1252 )); | 1405 )); |
1253 | 1406 |
1254 private ExpString Literal(In in) throws ParseException { | 1407 private ExpString Literal(In in) throws ParseException { |
1255 parser.begin(); | 1408 parser.begin(); |
1256 if( NilLiteral(in) ) | 1409 if( NilLiteral(in) ) { |
1257 return parser.success(new ExpString("null",true,false)); | 1410 ExpString exp = new ExpString(true,false); |
1411 exp.list.add( "null" ); | |
1412 return parser.success(exp); | |
1413 } | |
1258 Boolean b = BooleanLiteral(in); | 1414 Boolean b = BooleanLiteral(in); |
1259 if( b != null ) | 1415 if( b != null ) { |
1260 return parser.success(new ExpString(b.toString(),true,false)); | 1416 ExpString exp = new ExpString(true,false); |
1417 exp.list.add( b.toString() ); | |
1418 return parser.success(exp); | |
1419 } | |
1261 Number n = NumberLiteral(in); | 1420 Number n = NumberLiteral(in); |
1262 if( n != null ) { | 1421 if( n != null ) { |
1263 String s = n.toString(); | 1422 String s = n.toString(); |
1264 if( n instanceof Long ) | 1423 if( n instanceof Long ) |
1265 s += "L"; | 1424 s += "L"; |
1266 return parser.success(new ExpString(s,true,false)); | 1425 ExpString exp = new ExpString(true,false); |
1426 exp.list.add( s ); | |
1427 return parser.success(exp); | |
1267 } | 1428 } |
1268 String s = StringLiteral(in); | 1429 String s = StringLiteral(in); |
1269 if( s != null ) | 1430 if( s != null ) |
1270 return parser.success(constExpStr(s)); | 1431 return parser.success(constExpStr(s)); |
1271 return parser.failure(null); | 1432 return parser.failure(null); |
1278 .replace("\n","\\n") | 1439 .replace("\n","\\n") |
1279 .replace("\r","\\r") | 1440 .replace("\r","\\r") |
1280 .replace("\t","\\t") | 1441 .replace("\t","\\t") |
1281 .replace("\b","\\b") | 1442 .replace("\b","\\b") |
1282 ; | 1443 ; |
1283 return new ExpString( "\""+s+"\"", true,false); | 1444 ExpString exp = new ExpString(true,false); |
1445 exp.list.add( "\""+s+"\"" ); | |
1446 return exp; | |
1284 } | 1447 } |
1285 | 1448 |
1286 private boolean NilLiteral(In in) throws ParseException { | 1449 private boolean NilLiteral(In in) throws ParseException { |
1287 return Keyword("nil",in); | 1450 return Keyword("nil",in); |
1288 } | 1451 } |
1531 | 1694 |
1532 | 1695 |
1533 private static int classCounter = 0; | 1696 private static int classCounter = 0; |
1534 | 1697 |
1535 private class ExpString { | 1698 private class ExpString { |
1536 final String code; | 1699 final List list = new ArrayList(); |
1537 final boolean isExpr; | 1700 final boolean isExpr; |
1538 final boolean isStmt; | 1701 final boolean isStmt; |
1539 | 1702 |
1540 ExpString(Expressions exp) { | 1703 ExpString(Expressions exp) { |
1541 if( exp==null ) throw new NullPointerException(); | 1704 if( exp==null ) throw new NullPointerException(); |
1542 int i = LuanImpl.addObj(exp); | 1705 int i = LuanImpl.addObj(exp); |
1543 code = "((Expressions)LuanImpl.getObj(" + i + ")).eval(luan)"; | 1706 list.add( "((Expressions)LuanImpl.getObj(" + i + ")).eval(luan)" ); |
1544 isExpr = exp instanceof Expr; | 1707 isExpr = exp instanceof Expr; |
1545 isStmt = exp instanceof StmtExp; | 1708 isStmt = exp instanceof StmtExp; |
1546 } | 1709 } |
1547 | 1710 |
1548 ExpString(String code,boolean isExpr,boolean isStmt) { | 1711 ExpString(boolean isExpr,boolean isStmt) { |
1549 this.code = code; | |
1550 this.isExpr = isExpr; | 1712 this.isExpr = isExpr; |
1551 this.isStmt = isStmt; | 1713 this.isStmt = isStmt; |
1552 } | 1714 } |
1553 | 1715 |
1554 ExpString expr() { | 1716 ExpString expr() { |
1555 return isExpr ? this : new ExpString( "Luan.first(" + code + ")", true, isStmt ); | 1717 if( isExpr ) |
1718 return this; | |
1719 ExpString exp = new ExpString(true,isStmt); | |
1720 exp.list.addAll( list ); | |
1721 return exp; | |
1556 } | 1722 } |
1557 } | 1723 } |
1558 | 1724 |
1559 private ExpString expString(List<ExpString> list) { | 1725 private ExpString expString(List<ExpString> list) { |
1726 ExpString exp = new ExpString(false,false); | |
1560 switch(list.size()) { | 1727 switch(list.size()) { |
1561 case 0: | 1728 case 0: |
1562 return new ExpString("LuanFunction.NOTHING",false,false); | 1729 exp.list.add("LuanFunction.NOTHING"); |
1730 return exp; | |
1563 case 1: | 1731 case 1: |
1564 return list.get(0); | 1732 return list.get(0); |
1565 default: | 1733 default: |
1566 int lastI = list.size() - 1; | 1734 int lastI = list.size() - 1; |
1567 StringBuilder sb = new StringBuilder(); | 1735 exp.list.add( "new Object[]{" ); |
1568 sb.append( "new Object[]{" ); | |
1569 for( int i=0; i<lastI; i++ ) { | 1736 for( int i=0; i<lastI; i++ ) { |
1570 sb.append( list.get(i).expr().code ).append( ',' ); | 1737 exp.list.addAll( list.get(i).expr().list ); |
1738 exp.list.add( "," ); | |
1571 } | 1739 } |
1572 ExpString last = list.get(lastI); | 1740 ExpString last = list.get(lastI); |
1573 if( last.isExpr ) { | 1741 if( last.isExpr ) { |
1574 sb.append( last.code ).append( '}' ); | 1742 exp.list.addAll( last.list ); |
1575 return new ExpString(sb.toString(),false,false); | 1743 exp.list.add( "}" ); |
1576 } else { | 1744 } else { |
1577 sb.append( '}' ); | 1745 exp.list.add( "}" ); |
1578 String s = "LuanImpl.concatArgs(" + sb + "," + last.code + ")"; | 1746 exp.list.add( 0, "LuanImpl.concatArgs(" ); |
1579 return new ExpString(s,false,false); | 1747 exp.list.add( "," ); |
1580 } | 1748 exp.list.addAll( last.list ); |
1749 exp.list.add( ")" ); | |
1750 } | |
1751 return exp; | |
1581 } | 1752 } |
1582 } | 1753 } |
1583 | 1754 |
1584 private static class StmtString { | 1755 private static class StmtString { |
1585 final String code; | 1756 final List list = new ArrayList(); |
1586 boolean hasReturn = false; | 1757 boolean hasReturn = false; |
1587 | 1758 } |
1588 StmtString(String code) { | |
1589 this.code = code; | |
1590 if( code.contains("LuanParser") ) throw new RuntimeException("\n"+code); | |
1591 } | |
1592 } | |
1593 | |
1594 private static StmtString EMPTY_STMT = new StmtString(""); | |
1595 | 1759 |
1596 private static FnDef toFnDef(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { | 1760 private static FnDef toFnDef(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { |
1761 StringBuilder sb = new StringBuilder(); | |
1762 for( Object o : stmt.list ) { | |
1763 if( o instanceof List ) throw new RuntimeException(); | |
1764 if( o instanceof ExpString ) throw new RuntimeException(); | |
1765 if( o instanceof StmtString ) throw new RuntimeException(); | |
1766 sb.append( o.toString() ); | |
1767 } | |
1768 String code = sb.toString(); | |
1769 //System.out.println("code:\n"+code); | |
1770 | |
1597 int i = LuanImpl.addObj(upValueGetters); | 1771 int i = LuanImpl.addObj(upValueGetters); |
1598 String className = "EXP" + ++classCounter; | 1772 String className = "EXP" + ++classCounter; |
1599 String classCode = "" | 1773 String classCode = "" |
1600 +"package luan.impl;\n" | 1774 +"package luan.impl;\n" |
1601 +"import luan.Luan;\n" | 1775 +"import luan.Luan;\n" |
1608 +" super("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+"));\n" | 1782 +" super("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+"));\n" |
1609 +" }\n" | 1783 +" }\n" |
1610 +"\n" | 1784 +"\n" |
1611 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" | 1785 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" |
1612 +" Object t;\n" | 1786 +" Object t;\n" |
1613 +" " + stmt.code | 1787 +" " + code |
1614 +" }\n" | 1788 +" }\n" |
1615 +"}\n" | 1789 +"}\n" |
1616 ; | 1790 ; |
1617 try { | 1791 try { |
1618 //System.out.println(classCode); | 1792 //System.out.println(classCode); |
1627 } | 1801 } |
1628 } | 1802 } |
1629 | 1803 |
1630 private ExpString toFnExpStr(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { | 1804 private ExpString toFnExpStr(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { |
1631 int i = LuanImpl.addObj(upValueGetters); | 1805 int i = LuanImpl.addObj(upValueGetters); |
1632 String classCode = "" | 1806 ExpString exp = new ExpString(true,false); |
1807 exp.list.add( "" | |
1633 +"\n" | 1808 +"\n" |
1634 +"new FnDef("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n" | 1809 +"new FnDef("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n" |
1635 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" | 1810 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" |
1636 +" Object t;\n" | 1811 +" Object t;\n" |
1637 +" " + stmt.code | 1812 +" " |
1813 ); | |
1814 exp.list.addAll( stmt.list ); | |
1815 exp.list.add( "" | |
1638 +" }\n" | 1816 +" }\n" |
1639 +"}.eval(luan)\n" | 1817 +"}.eval(luan)\n" |
1640 ; | 1818 ); |
1641 return new ExpString(classCode,true,false); | 1819 return exp; |
1642 } | 1820 } |
1643 | 1821 |
1644 | 1822 |
1645 private static class SettableString { | 1823 private static String settableToString(Settable settable) { |
1646 final String code; | 1824 if( settable==null ) throw new NullPointerException(); |
1647 | 1825 int i = LuanImpl.addObj(settable); |
1648 SettableString(Settable settable) { | 1826 return"((Settable)LuanImpl.getObj(" + i + "))"; |
1649 if( settable==null ) throw new NullPointerException(); | |
1650 int i = LuanImpl.addObj(settable); | |
1651 code = "((Settable)LuanImpl.getObj(" + i + "))"; | |
1652 } | |
1653 | |
1654 SettableString(String code) { | |
1655 this.code = code; | |
1656 } | |
1657 | |
1658 } | 1827 } |
1659 | 1828 |
1660 } | 1829 } |