Mercurial Hosting > luan
comparison core/src/luan/impl/ThemeParser.java @ 593:92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 31 Aug 2015 10:16:57 -0600 |
parents | fa281ee942c8 |
children | e91e476186c7 |
comparison
equal
deleted
inserted
replaced
592:1c64b1fd882b | 593:92c9fa5e39e6 |
---|---|
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 private Stmt parseDef() throws ParseException { | 179 private Stmt parseDef() throws ParseException { |
180 int start = parser.begin(); | 180 int start = parser.begin(); |
181 if( !parser.match("{define:") ) | |
182 return parser.failure(null); | |
181 Tag tag = parseBlockTag(); | 183 Tag tag = parseBlockTag(); |
182 if( tag == null ) | 184 if( tag == null ) |
183 return parser.failure(null); | 185 return parser.failure(null); |
184 parser.match('\r'); parser.match('\n'); // ignore newline | 186 parser.match('\r'); parser.match('\n'); // ignore newline |
185 Stmt rtn = null; | 187 if( !tag.attrs.isEmpty() ) |
186 if( tag.name.equals("Set") ) { | 188 throw exception("this block should have no attributes"); |
187 String name = tag.attrs.remove("name"); | 189 Expr table = new GetLocalVar(null,stackIndex(MOD)); |
188 if( name == null ) | 190 Settable fnName = new SetTableEntry(se(start),table,new ConstExpr(null,tag.name)); |
189 throw exception("block:Set missing required attribute 'name'"); | 191 frame = new Frame(frame); |
190 if( !tag.attrs.isEmpty() ) | 192 addSymbol(ENV); |
191 throw exception("block:Set has unrecognized attributes: "+tag.attrs); | 193 Stmt block = parseBody("define",tag); |
192 if( !validateName(name) ) | 194 FnDef fnDef = newFnDef(start,block); |
193 throw exception("invalid Set name: "+name); | 195 frame = frame.parent; |
194 addSymbol( name ); | 196 Stmt rtn = new SetStmt(fnName,fnDef); |
195 frame = new Frame(frame); | |
196 addSymbol(ENV); | |
197 Stmt block = parseBody(tag); | |
198 FnDef fnDef = newFnDef(start,block); | |
199 frame = frame.parent; | |
200 rtn = new SetStmt( new SetLocalVar(symbolsSize()-1), fnDef ); | |
201 } else { | |
202 if( !tag.attrs.isEmpty() ) | |
203 throw exception("this block should have no attributes"); | |
204 Expr table = new GetLocalVar(null,stackIndex(MOD)); | |
205 Settable fnName = new SetTableEntry(se(start),table,new ConstExpr(null,tag.name)); | |
206 frame = new Frame(frame); | |
207 addSymbol(ENV); | |
208 Stmt block = parseBody(tag); | |
209 FnDef fnDef = newFnDef(start,block); | |
210 frame = frame.parent; | |
211 rtn = new SetStmt(fnName,fnDef); | |
212 } | |
213 return parser.success(rtn); | 197 return parser.success(rtn); |
214 } | 198 } |
215 | 199 |
216 private Stmt parseBody(Tag tag) throws ParseException { | 200 private Stmt parseBody(String type,Tag tag) throws ParseException { |
217 String endTag = "{/block:" + tag.name + "}"; | 201 String endTag = "{/"+type+":" + tag.name + "}"; |
218 List<Stmt> stmts = new ArrayList<Stmt>(); | 202 List<Stmt> stmts = new ArrayList<Stmt>(); |
219 int stackStart = symbolsSize(); | 203 int stackStart = symbolsSize(); |
220 StringBuilder sb = new StringBuilder(); | 204 StringBuilder sb = new StringBuilder(); |
221 int start = -1; | 205 int start = -1; |
222 while( !parser.match(endTag) ) { | 206 while( !parser.match(endTag) ) { |
255 sb.setLength(0); | 239 sb.setLength(0); |
256 } | 240 } |
257 | 241 |
258 private Stmt parseBlock() throws ParseException { | 242 private Stmt parseBlock() throws ParseException { |
259 int start = parser.begin(); | 243 int start = parser.begin(); |
244 if( !parser.match("{block:") ) | |
245 return parser.failure(null); | |
260 Tag tag = parseBlockTag(); | 246 Tag tag = parseBlockTag(); |
261 if( tag == null ) | 247 if( tag == null ) |
262 return parser.failure(null); | 248 return parser.failure(null); |
263 if( tag.name.equals("Set") ) | 249 if( tag.name.equals("Set") ) |
264 throw exception("block:Set not allowed here"); | 250 throw exception("block:Set not allowed here"); |
265 frame = new Frame(frame); | 251 frame = new Frame(frame); |
266 addSymbol(ENV); | 252 addSymbol(ENV); |
267 Stmt block = parseBody(tag); | 253 Stmt block = parseBody("block",tag); |
268 FnDef fnDef = newFnDef(start,block); | 254 FnDef fnDef = newFnDef(start,block); |
269 frame = frame.parent; | 255 frame = frame.parent; |
270 // String rtn = "<% env." + tag.name + "(" + (tag.attrs.isEmpty() ? "nil" : table(tag.attrs)) + ",env,function(env) %>" + block + "<% end) %>"; | 256 // String rtn = "<% env." + tag.name + "(" + (tag.attrs.isEmpty() ? "nil" : table(tag.attrs)) + ",env,function(env) %>" + block + "<% end) %>"; |
271 Expr env = env(); | 257 Expr env = env(); |
272 Expr fn = new IndexExpr( se(start,"block:"+tag.name), env, new ConstExpr(null,tag.name) ); | 258 Expr fn = new IndexExpr( se(start,"block:"+tag.name), env, new ConstExpr(null,tag.name) ); |
273 List<Expressions> args = new ArrayList<Expressions>(); | 259 List<Expressions> args = new ArrayList<Expressions>(); |
260 args.add( env ); | |
274 args.add( tag.attrs.isEmpty() ? new ConstExpr(null,null) : table(tag.attrs) ); | 261 args.add( tag.attrs.isEmpty() ? new ConstExpr(null,null) : table(tag.attrs) ); |
275 args.add( env ); | |
276 args.add( fnDef ); | 262 args.add( fnDef ); |
277 FnCall fnCall = new FnCall( se(start), fn, ExpList.build(args) ); | 263 FnCall fnCall = new FnCall( se(start), fn, ExpList.build(args) ); |
278 Stmt rtn = new ExpressionsStmt(fnCall); | 264 Stmt rtn = new ExpressionsStmt(fnCall); |
279 return parser.success(rtn); | 265 return parser.success(rtn); |
280 } | 266 } |
281 | 267 |
282 private Tag parseBlockTag() throws ParseException { | 268 private Tag parseBlockTag() throws ParseException { |
283 parser.begin(); | |
284 if( !parser.match("{block:") ) | |
285 return parser.failure(null); | |
286 String name = parseName(); | 269 String name = parseName(); |
287 if( name==null ) | 270 if( name==null ) |
288 throw exception("invalid block name"); | 271 throw exception("invalid block name"); |
289 Map<String,String> attrs = parseAttrs(); | 272 Map<String,String> attrs = parseAttrs(); |
290 if( !parser.match("}") ) | 273 if( !parser.match("}") ) |
291 return parser.failure(null); | 274 return null; |
292 Tag tag = new Tag(name,attrs); | 275 Tag tag = new Tag(name,attrs); |
293 return parser.success(tag); | 276 return tag; |
294 } | 277 } |
295 | 278 |
296 private Stmt parseSimpleTag() throws ParseException { | 279 private Stmt parseSimpleTag() throws ParseException { |
297 int start = parser.begin(); | 280 int start = parser.begin(); |
298 if( !parser.match("{") ) | 281 if( !parser.match("{") ) |
301 if( name==null ) | 284 if( name==null ) |
302 return parser.failure(null); | 285 return parser.failure(null); |
303 Map<String,String> attrs = parseAttrs(); | 286 Map<String,String> attrs = parseAttrs(); |
304 if( !parser.match("}") ) | 287 if( !parser.match("}") ) |
305 return parser.failure(null); | 288 return parser.failure(null); |
306 FnCall fnCall; | 289 // rtn = "<% env." + name + (attrs.isEmpty() ? "()" : table(attrs)) + " %>"; |
307 if( name.equals("Get") ) { | 290 Expr env = env(); |
308 name = attrs.remove("name"); | 291 Expr fn = new IndexExpr( se(start,name), env, new ConstExpr(null,name) ); |
309 if( name == null ) | 292 List<Expressions> args = new ArrayList<Expressions>(); |
310 throw exception("Get missing required attribute 'name'"); | 293 args.add( env ); |
311 if( !attrs.isEmpty() ) | 294 if( !attrs.isEmpty() ) |
312 throw exception("Get has unrecognized attributes: "+attrs); | 295 args.add( table(attrs) ); |
313 if( !validateName(name) ) | 296 FnCall fnCall = new FnCall( se(start), fn, ExpList.build(args) ); |
314 throw exception("invalid Get name: "+name); | |
315 // rtn = "<% " + name + "(env) %>"; | |
316 int index = upValueIndex(name); | |
317 if( index == -1 ) | |
318 throw exception("name '"+name+"' not defined"); | |
319 Expr fn = new GetUpVar(se(start,name),index); | |
320 fnCall = new FnCall( se(start), fn, env() ); | |
321 } else { | |
322 // rtn = "<% env." + name + (attrs.isEmpty() ? "()" : table(attrs)) + " %>"; | |
323 Expr fn = new IndexExpr( se(start,name), env(), new ConstExpr(null,name) ); | |
324 Expressions args = attrs.isEmpty() ? ExpList.emptyExpList : table(attrs); | |
325 fnCall = new FnCall( se(start), fn, args ); | |
326 } | |
327 Stmt rtn = new ExpressionsStmt(fnCall); | 297 Stmt rtn = new ExpressionsStmt(fnCall); |
328 return parser.success(rtn); | 298 return parser.success(rtn); |
329 } | 299 } |
330 | 300 |
331 private TableExpr table(Map<String,String> attrs) { | 301 private TableExpr table(Map<String,String> attrs) { |
369 private void Spaces() { | 339 private void Spaces() { |
370 while( parser.anyOf(" \t\r\n") ); | 340 while( parser.anyOf(" \t\r\n") ); |
371 } | 341 } |
372 | 342 |
373 private String parseName() { | 343 private String parseName() { |
374 return parseName(parser); | |
375 } | |
376 | |
377 private static boolean validateName(String name) { | |
378 return name.equals(parseName(new Parser(new LuanSource("NAME",name)))); | |
379 } | |
380 | |
381 private static String parseName(Parser parser) { | |
382 int start = parser.begin(); | 344 int start = parser.begin(); |
383 if( !NameChar(parser) ) | 345 if( !NameChar() ) |
384 return parser.failure(null); | 346 return parser.failure(null); |
385 while( NameChar(parser) ); | 347 while( NameChar() ); |
386 String match = parser.textFrom(start); | 348 String match = parser.textFrom(start); |
387 return parser.success(match); | 349 return parser.success(match); |
388 } | 350 } |
389 | 351 |
390 private static boolean NameChar(Parser parser) { | 352 private boolean NameChar() { |
391 return parser.inCharRange('a', 'z') || parser.inCharRange('A', 'Z') | 353 return parser.inCharRange('a', 'z') || parser.inCharRange('A', 'Z') |
392 || parser.inCharRange('0', '9') || parser.anyOf("-_"); | 354 || parser.inCharRange('0', '9') || parser.anyOf("-_"); |
393 } | 355 } |
394 | 356 |
395 } | 357 } |