Mercurial Hosting > luan
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() { |