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 }