comparison src/luan/interp/LuaParser.java @ 19:a7c13c6017f7

add GenericForStmt git-svn-id: https://luan-java.googlecode.com/svn/trunk@20 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 02 Dec 2012 10:08:24 +0000
parents 3971113699b8
children d85510d92eee
comparison
equal deleted inserted replaced
18:3971113699b8 19:a7c13c6017f7
43 } 43 }
44 44
45 int index(String name) { 45 int index(String name) {
46 int i = symbols.size(); 46 int i = symbols.size();
47 while( --i >= 0 ) { 47 while( --i >= 0 ) {
48 System.out.println("index ["+name+"] ["+symbols.get(i)+"] "+symbols.get(i).equals(name));
49 if( symbols.get(i).equals(name) ) 48 if( symbols.get(i).equals(name) )
50 return i; 49 return i;
51 } 50 }
52 return -1; 51 return -1;
53 } 52 }
54 53
54 boolean popSymbols(int n) {
55 while( n-- > 0 ) {
56 symbols.remove(symbols.size()-1);
57 }
58 return true;
59 }
60
55 public Rule Target() { 61 public Rule Target() {
56 return Sequence( 62 return Sequence(
57 Spaces(), 63 Spaces(),
58 FirstOf( 64 FirstOf(
59 Sequence( ExpList(), EOI ), 65 Sequence( ExpList(), EOI ),
69 ); 75 );
70 } 76 }
71 77
72 Rule Block() { 78 Rule Block() {
73 Var<List<Stmt>> stmts = new Var<List<Stmt>>(new ArrayList<Stmt>()); 79 Var<List<Stmt>> stmts = new Var<List<Stmt>>(new ArrayList<Stmt>());
74 Var<Integer> stackCount = new Var<Integer>(0); 80 Var<Integer> stackStart = new Var<Integer>(symbols.size());
75 return Sequence( 81 return Sequence(
76 Optional( Stmt(stmts,stackCount) ), 82 Optional( Stmt(stmts) ),
77 ZeroOrMore( 83 ZeroOrMore(
78 StmtSep(), 84 StmtSep(),
79 Optional( Stmt(stmts,stackCount) ) 85 Optional( Stmt(stmts) )
80 ), 86 ),
81 push( newBlock(stmts.get(),stackCount.get()) ) 87 push( newBlock(stmts.get(),stackStart.get()) )
82 ); 88 );
83 } 89 }
84 90
85 Stmt newBlock(List<Stmt> stmts,int stackN) { 91 Stmt newBlock(List<Stmt> stmts,int stackStart) {
86 if( stackSize < symbols.size() ) 92 if( stackSize < symbols.size() )
87 stackSize = symbols.size(); 93 stackSize = symbols.size();
88 for( int i=0; i<stackN; i++ ) { 94 int stackEnd = symbols.size();
89 symbols.remove(symbols.size()-1); // pop 95 popSymbols( stackEnd - stackStart );
90 }
91 if( stmts.isEmpty() ) 96 if( stmts.isEmpty() )
92 return Stmt.EMPTY; 97 return Stmt.EMPTY;
93 if( stmts.size()==1 && stackN==0 ) 98 if( stmts.size()==1 && stackStart==stackEnd )
94 return stmts.get(0); 99 return stmts.get(0);
95 return new Block( stmts.toArray(new Stmt[0]), symbols.size(), symbols.size()+stackN ); 100 return new Block( stmts.toArray(new Stmt[0]), stackStart, stackEnd );
96 } 101 }
97 102
98 Rule StmtSep() { 103 Rule StmtSep() {
99 return Sequence( 104 return Sequence(
100 FirstOf( 105 FirstOf(
110 115
111 Rule EndOfLine() { 116 Rule EndOfLine() {
112 return FirstOf("\r\n", '\r', '\n'); 117 return FirstOf("\r\n", '\r', '\n');
113 } 118 }
114 119
115 Rule Stmt(Var<List<Stmt>> stmts,Var<Integer> stackCount) { 120 Rule Stmt(Var<List<Stmt>> stmts) {
116 return FirstOf( 121 return FirstOf(
117 LocalStmt(stmts,stackCount), 122 LocalStmt(stmts),
118 Sequence( 123 Sequence(
119 FirstOf( 124 FirstOf(
125 GenericForStmt(),
120 NumericForStmt(), 126 NumericForStmt(),
121 DoStmt(), 127 DoStmt(),
122 WhileStmt(), 128 WhileStmt(),
123 RepeatStmt(), 129 RepeatStmt(),
124 IfStmt(), 130 IfStmt(),
128 stmts.get().add( (Stmt)pop() ) 134 stmts.get().add( (Stmt)pop() )
129 ) 135 )
130 ); 136 );
131 } 137 }
132 138
139 Rule GenericForStmt() {
140 Var<Integer> stackStart = new Var<Integer>(symbols.size());
141 return Sequence(
142 Keyword("for"), NameList(), Keyword("in"), Expr(), Keyword("do"), Block(), Keyword("end"),
143 push( new GenericForStmt( stackStart.get(), symbols.size() - stackStart.get(), expr(pop(1)), (Stmt)pop() ) ),
144 popSymbols( symbols.size() - stackStart.get() )
145 );
146 }
147
133 Rule NumericForStmt() { 148 Rule NumericForStmt() {
134 return Sequence( 149 return Sequence(
135 Keyword("for"), Name(), '=', Spaces(), Expr(), ',', Spaces(), Expr(), 150 Keyword("for"), Name(), '=', Spaces(), Expr(), ',', Spaces(), Expr(),
136 push( new ConstExpr(new LuaNumber(1)) ), // default step 151 push( new ConstExpr(new LuaNumber(1)) ), // default step
137 Optional( 152 Optional(
140 Expr() 155 Expr()
141 ), 156 ),
142 symbols.add( (String)pop(3) ), // add "for" var to symbols 157 symbols.add( (String)pop(3) ), // add "for" var to symbols
143 Keyword("do"), Block(), Keyword("end"), 158 Keyword("do"), Block(), Keyword("end"),
144 push( new NumericForStmt( symbols.size()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ), 159 push( new NumericForStmt( symbols.size()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ),
145 action( symbols.remove(symbols.size()-1) ) // pop 160 popSymbols(1)
146 ); 161 );
147 } 162 }
148 163
149 Rule DoStmt() { 164 Rule DoStmt() {
150 return Sequence( 165 return Sequence(
151 Keyword("do"), Block(), Keyword("end") 166 Keyword("do"), Block(), Keyword("end")
152 ); 167 );
153 } 168 }
154 169
155 Rule LocalStmt(Var<List<Stmt>> stmts,Var<Integer> stackCount) { 170 Rule LocalStmt(Var<List<Stmt>> stmts) {
156 Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); 171 Var<Integer> stackStart = new Var<Integer>(symbols.size());
157 return Sequence( 172 return Sequence(
158 Keyword("local"), 173 Keyword("local"), NameList(),
174 Optional(
175 '=', Spaces(), ExpList(),
176 stmts.get().add( newSetLocalStmt(stackStart.get()) )
177 )
178 );
179 }
180
181 Rule NameList() {
182 return Sequence(
159 Name(), 183 Name(),
160 newName(names.get(),stackCount), 184 symbols.add( (String)pop() ),
161 ZeroOrMore( 185 ZeroOrMore(
162 ',', Spaces(), Name(), 186 ',', Spaces(), Name(),
163 newName(names.get(),stackCount) 187 symbols.add( (String)pop() )
164 ), 188 )
165 Optional( 189 );
166 '=', Spaces(), 190 }
167 ExpList(), 191
168 stmts.get().add( newSetLocalStmt(names.get()) ) 192 SetStmt newSetLocalStmt(int stackStart) {
169 )
170 );
171 }
172
173 boolean newName(List<String> names,Var<Integer> stackCount) {
174 String name = (String)pop();
175 names.add(name);
176 symbols.add(name);
177 stackCount.set( stackCount.get() + 1 );
178 return true;
179 }
180
181 SetStmt newSetLocalStmt(List<String> names) {
182 Expressions values = (Expressions)pop(); 193 Expressions values = (Expressions)pop();
183 SetLocalVar[] vars = new SetLocalVar[names.size()]; 194 SetLocalVar[] vars = new SetLocalVar[symbols.size()-stackStart];
184 for( int i=0; i<vars.length; i++ ) { 195 for( int i=0; i<vars.length; i++ ) {
185 vars[i] = new SetLocalVar(index(names.get(i))); 196 vars[i] = new SetLocalVar(stackStart+i);
186 } 197 }
187 return new SetStmt( vars, values ); 198 return new SetStmt( vars, values );
188 } 199 }
189 200
190 Rule WhileStmt() { 201 Rule WhileStmt() {