comparison src/luan/interp/LuaParser.java @ 32:c3eab5a3ce3c

implement closures git-svn-id: https://luan-java.googlecode.com/svn/trunk@33 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 14 Dec 2012 05:40:35 +0000
parents 5cf15507d77e
children 8793c71ad47a
comparison
equal deleted inserted replaced
31:5cf15507d77e 32:c3eab5a3ce3c
27 final Frame parent; 27 final Frame parent;
28 final List<String> symbols = new ArrayList<String>(); 28 final List<String> symbols = new ArrayList<String>();
29 int stackSize = 0; 29 int stackSize = 0;
30 int loops = 0; 30 int loops = 0;
31 boolean isVarArg = false; 31 boolean isVarArg = false;
32 final List<String> upValueSymbols = new ArrayList<String>();
33 final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>();
32 34
33 Frame(Frame parent) { 35 Frame(Frame parent) {
34 this.parent = parent; 36 this.parent = parent;
35 } 37 }
36 } 38
39 int stackIndex(String name) {
40 int i = symbols.size();
41 while( --i >= 0 ) {
42 if( symbols.get(i).equals(name) )
43 return i;
44 }
45 return -1;
46 }
47
48 int upValueIndex(String name) {
49 int i = upValueSymbols.size();
50 while( --i >= 0 ) {
51 if( upValueSymbols.get(i).equals(name) )
52 return i;
53 }
54 if( parent==null )
55 return -1;
56 i = parent.stackIndex(name);
57 if( i != -1 ) {
58 upValueGetters.add(new UpValue.StackGetter(i));
59 } else {
60 i = parent.upValueIndex(name);
61 if( i == -1 )
62 return -1;
63 upValueGetters.add(new UpValue.NestedGetter(i));
64 }
65 upValueSymbols.add(name);
66 return upValueSymbols.size() - 1;
67 }
68 }
69
70 static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0];
37 71
38 int nEquals; 72 int nEquals;
39 int parens = 0; 73 int parens = 0;
40 Frame frame = new Frame(null); 74 Frame frame = new Frame(null);
41 75
74 if( frame.stackSize < symbolsSize() ) 108 if( frame.stackSize < symbolsSize() )
75 frame.stackSize = symbolsSize(); 109 frame.stackSize = symbolsSize();
76 return true; 110 return true;
77 } 111 }
78 112
79 int index(String name) { 113 int stackIndex(String name) {
80 List<String> symbols = frame.symbols; 114 return frame.stackIndex(name);
81 int i = symbols.size();
82 while( --i >= 0 ) {
83 if( symbols.get(i).equals(name) )
84 return i;
85 }
86 return -1;
87 } 115 }
88 116
89 boolean popSymbols(int n) { 117 boolean popSymbols(int n) {
90 List<String> symbols = frame.symbols; 118 List<String> symbols = frame.symbols;
91 while( n-- > 0 ) { 119 while( n-- > 0 ) {
92 symbols.remove(symbols.size()-1); 120 symbols.remove(symbols.size()-1);
93 } 121 }
94 return true; 122 return true;
95 } 123 }
96 124
125 int upValueIndex(String name) {
126 return frame.upValueIndex(name);
127 }
128
97 boolean incLoops() { 129 boolean incLoops() {
98 frame.loops++; 130 frame.loops++;
99 return true; 131 return true;
100 } 132 }
101 133
102 boolean decLoops() { 134 boolean decLoops() {
103 frame.loops--; 135 frame.loops--;
104 return true; 136 return true;
105 } 137 }
106 138
139 Chunk newChunk() {
140 return new Chunk( (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
141 }
107 142
108 Rule Target() { 143 Rule Target() {
109 return Sequence( 144 return Sequence(
110 Spaces(), 145 Spaces(),
111 FirstOf( 146 FirstOf(
112 Sequence( ExpList(), EOI ), 147 Sequence( ExpList(), EOI ),
113 Sequence( 148 Sequence(
114 action( frame.isVarArg = true ), 149 action( frame.isVarArg = true ),
115 Block(), 150 Block(),
116 EOI, 151 EOI,
117 push( new Chunk( (Stmt)pop(), frame.stackSize, 0, frame.isVarArg ) ) 152 push( newChunk() )
118 ) 153 )
119 ) 154 )
120 ); 155 );
121 } 156 }
122 157
384 boolean makeSettableVar() { 419 boolean makeSettableVar() {
385 Object obj2 = pop(); 420 Object obj2 = pop();
386 if( obj2==null ) 421 if( obj2==null )
387 return false; 422 return false;
388 Object obj1 = pop(); 423 Object obj1 = pop();
389 if( obj1==null ) { 424 if( obj1!=null ) {
390 String name = (String)obj2;
391 int index = index(name);
392 if( index == -1 ) {
393 push( new SetTableEntry( EnvExpr.INSTANCE, new ConstExpr(name) ) );
394 } else {
395 push( new SetLocalVar(index) );
396 }
397 } else {
398 Expr key = expr(obj2); 425 Expr key = expr(obj2);
399 Expr table = expr(obj1); 426 Expr table = expr(obj1);
400 push( new SetTableEntry(table,key) ); 427 return push( new SetTableEntry(table,key) );
401 } 428 }
402 return true; 429 String name = (String)obj2;
430 int index = stackIndex(name);
431 if( index != -1 )
432 return push( new SetLocalVar(index) );
433 index = upValueIndex(name);
434 if( index != -1 )
435 return push( new SetUpVar(index) );
436 return push( new SetTableEntry( EnvExpr.INSTANCE, new ConstExpr(name) ) );
403 } 437 }
404 438
405 Rule Expr() { 439 Rule Expr() {
406 return FirstOf( 440 return FirstOf(
407 VarArgs(), 441 VarArgs(),
513 ), 547 ),
514 VarArgName() 548 VarArgName()
515 ) 549 )
516 ), 550 ),
517 ')', decParens(), Spaces(), Block(), Keyword("end"), 551 ')', decParens(), Spaces(), Block(), Keyword("end"),
518 push( new Chunk( (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg ) ), 552 push( newChunk() ),
519 action( frame = frame.parent ) 553 action( frame = frame.parent )
520 ); 554 );
521 } 555 }
522 556
523 Rule VarArgName() { 557 Rule VarArgName() {
615 boolean makeVarExp() { 649 boolean makeVarExp() {
616 Object obj2 = pop(); 650 Object obj2 = pop();
617 if( obj2==null ) 651 if( obj2==null )
618 return true; 652 return true;
619 Object obj1 = pop(); 653 Object obj1 = pop();
620 if( obj1==null ) { 654 if( obj1 != null )
621 String name = (String)obj2; 655 return push( new GetExpr( expr(obj1), expr(obj2) ) );
622 int index = index(name); 656 String name = (String)obj2;
623 if( index == -1 ) { 657 int index = stackIndex(name);
624 return push( new GetExpr( EnvExpr.INSTANCE, new ConstExpr(name) ) ); 658 if( index != -1 )
625 } else { 659 return push( new GetLocalVar(index) );
626 return push( new GetLocalVar(index) ); 660 index = upValueIndex(name);
627 } 661 if( index != -1 )
628 } 662 return push( new GetUpVar(index) );
629 return push( new GetExpr( expr(obj1), expr(obj2) ) ); 663 return push( new GetExpr( EnvExpr.INSTANCE, new ConstExpr(name) ) );
630 } 664 }
631 665
632 // function should be on top of the stack 666 // function should be on top of the stack
633 Rule Args() { 667 Rule Args() {
634 return Sequence( 668 return Sequence(