Mercurial Hosting > luan
annotate core/src/luan/impl/ThemeParser.java @ 635:c83b8cefd922
better error handling in theme code
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 01 Mar 2016 07:01:58 -0700 |
parents | 3dde072c3420 |
children | 859c0dedc8b6 |
rev | line source |
---|---|
584 | 1 package luan.impl; |
2 | |
3 import java.util.Map; | |
4 import java.util.HashMap; | |
5 import java.util.List; | |
6 import java.util.ArrayList; | |
635
c83b8cefd922
better error handling in theme code
Franklin Schmidt <fschmidt@gmail.com>
parents:
634
diff
changeset
|
7 import luan.Luan; |
584 | 8 import luan.LuanSource; |
9 import luan.LuanTable; | |
10 import luan.LuanElement; | |
11 import luan.LuanState; | |
12 import luan.LuanFunction; | |
13 import luan.LuanException; | |
14 import luan.modules.PackageLuan; | |
15 | |
16 | |
17 public final class ThemeParser { | |
18 | |
19 public static LuanFunction compile(LuanState luan,LuanSource source) throws LuanException { | |
20 try { | |
21 FnDef fnDef = new ThemeParser(source).parse(); | |
22 final LuanStateImpl luanImpl = (LuanStateImpl)luan; | |
23 return new Closure(luanImpl,fnDef); | |
24 } catch(ParseException e) { | |
25 //e.printStackTrace(); | |
26 throw new LuanException(luan, e.getFancyMessage() ); | |
27 } | |
28 } | |
29 | |
30 private static final class Frame { | |
31 final Frame parent; | |
32 final List<String> symbols = new ArrayList<String>(); | |
33 int stackSize = 0; | |
34 final boolean isVarArg; | |
35 final List<String> upValueSymbols = new ArrayList<String>(); | |
36 final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>(); | |
37 | |
38 Frame() { | |
39 this.parent = null; | |
40 isVarArg = true; | |
41 } | |
42 | |
43 Frame(Frame parent) { | |
44 this.parent = parent; | |
45 isVarArg = false; | |
46 if( upValueIndex(MOD) != 0 ) | |
47 throw new RuntimeException(); | |
48 } | |
49 | |
50 int stackIndex(String name) { | |
51 int i = symbols.size(); | |
52 while( --i >= 0 ) { | |
53 if( symbols.get(i).equals(name) ) | |
54 return i; | |
55 } | |
56 return -1; | |
57 } | |
58 | |
59 int upValueIndex(String name) { | |
60 int i = upValueSymbols.size(); | |
61 while( --i >= 0 ) { | |
62 if( upValueSymbols.get(i).equals(name) ) | |
63 return i; | |
64 } | |
65 if( parent==null ) | |
66 return -1; | |
67 i = parent.stackIndex(name); | |
68 if( i != -1 ) { | |
69 upValueGetters.add(new UpValue.StackGetter(i)); | |
70 } else { | |
71 i = parent.upValueIndex(name); | |
72 if( i == -1 ) | |
73 return -1; | |
74 upValueGetters.add(new UpValue.NestedGetter(i)); | |
75 } | |
76 upValueSymbols.add(name); | |
77 return upValueSymbols.size() - 1; | |
78 } | |
79 | |
80 void addUpValueGetter(String name,UpValue.Getter upValueGetter) { | |
81 upValueSymbols.add(name); | |
82 upValueGetters.add(upValueGetter); | |
83 } | |
84 } | |
85 | |
86 private static final String IO = "-IO-"; | |
87 private static final String MOD = "-MOD-"; | |
88 private static final String ENV = "-ENV-"; | |
594 | 89 private static final String INDENT = "-INDENT-"; |
584 | 90 private static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0]; |
91 | |
92 private final LuanSource source; | |
93 private final Parser parser; | |
94 private Frame frame = new Frame(); | |
95 | |
96 private ThemeParser(LuanSource source) { | |
97 this.source = source; | |
98 this.parser = new Parser(this.source); | |
99 } | |
100 | |
101 private LuanElement se(int start) { | |
102 return se(start,null); | |
103 } | |
104 | |
105 private LuanElement se(int start,String text) { | |
106 return new LuanElement(source,start,parser.currentIndex(),text); | |
107 } | |
108 | |
109 private int symbolsSize() { | |
110 return frame.symbols.size(); | |
111 } | |
112 | |
113 private void addSymbol(String name) { | |
114 frame.symbols.add(name); | |
115 if( frame.stackSize < symbolsSize() ) | |
116 frame.stackSize = symbolsSize(); | |
117 } | |
118 | |
119 private FnDef newFnDef(int start,Stmt stmt) { | |
120 return new FnDef( se(start), stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); | |
121 } | |
122 | |
123 private int stackIndex(String name) { | |
124 return frame.stackIndex(name); | |
125 } | |
126 | |
594 | 127 private void popSymbols(int n) { |
128 List<String> symbols = frame.symbols; | |
129 while( n-- > 0 ) { | |
130 symbols.remove(symbols.size()-1); | |
131 } | |
132 } | |
133 | |
584 | 134 private int upValueIndex(String name) { |
135 return frame.upValueIndex(name); | |
136 } | |
137 | |
138 private ParseException exception(String msg) { | |
139 parser.failure(); | |
140 return parser.exception(msg); | |
141 } | |
142 | |
143 private Expr env() { | |
144 return new GetLocalVar(null,stackIndex(ENV)); | |
145 } | |
146 | |
147 private FnDef parse() throws ParseException { | |
148 List<Stmt> stmts = new ArrayList<Stmt>(); | |
149 int stackStart = symbolsSize(); | |
150 { | |
151 addSymbol(IO); | |
152 LuanElement se = se(0,"require 'luan:Io'"); | |
153 FnCall requireCall = new FnCall( se, new ConstExpr(se,PackageLuan.requireFn), new ConstExpr(se,"luan:Io") ); | |
154 SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(IO)), new ExpressionsExpr(requireCall) ); | |
155 stmts.add(setStmt); | |
156 } | |
157 { | |
158 addSymbol(MOD); | |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
159 LuanElement se = se(0,"local M = {['-INDENT-']=''}"); |
594 | 160 TableExpr.Field indent = new TableExpr.Field(new ConstExpr(null,INDENT),new ConstExpr(null,"")); |
161 TableExpr tableExpr = new TableExpr( se, new TableExpr.Field[]{indent}, ExpList.emptyExpList ); | |
584 | 162 SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(MOD)), tableExpr ); |
163 stmts.add(setStmt); | |
164 } | |
165 while( !parser.endOfInput() ) { | |
166 Stmt def = parseDef(); | |
167 if( def != null ) { | |
168 stmts.add(def); | |
169 } else { | |
170 parser.anyChar(); | |
171 } | |
172 } | |
173 stmts.add( new ReturnStmt(null,new GetLocalVar(null,stackIndex(MOD))) ); | |
174 Stmt block = new Block( stmts.toArray(new Stmt[0]), stackStart, symbolsSize() ); | |
175 FnDef fnDef = newFnDef(0,block); | |
176 return fnDef; | |
177 } | |
178 | |
179 private Stmt parseDef() throws ParseException { | |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
180 int start = parser.begin(); |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
181 if( !parser.match("{define:") ) |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
182 return parser.failure(null); |
594 | 183 String name = parseName(); |
184 if( name==null ) | |
600
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
185 throw parser.exception("invalid block name"); |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
186 if( !parser.match('}') ) |
600
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
187 throw parser.exception("unclosed define tag"); |
594 | 188 String spaces = ""; |
600
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
189 boolean indent = BlankLine(); |
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
190 if( indent ) { |
594 | 191 int startSpaces = parser.currentIndex(); |
192 InlineSpaces(); | |
193 spaces = parser.textFrom(startSpaces); | |
194 } | |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
195 Expr table = new GetLocalVar(null,stackIndex(MOD)); |
594 | 196 Settable fnName = new SetTableEntry(se(start),table,new ConstExpr(null,name)); |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
197 frame = new Frame(frame); |
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
198 addSymbol(ENV); |
600
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
199 Stmt block = parseBody("define:"+name,spaces,indent); |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
200 FnDef fnDef = newFnDef(start,block); |
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
201 frame = frame.parent; |
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
202 Stmt rtn = new SetStmt(fnName,fnDef); |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
203 return parser.success(rtn); |
584 | 204 } |
205 | |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
206 private Stmt parseBody(String tagName,final String spaces,boolean afterIndent) throws ParseException { |
584 | 207 List<Stmt> stmts = new ArrayList<Stmt>(); |
208 int stackStart = symbolsSize(); | |
594 | 209 int start = parser.currentIndex(); |
210 { | |
211 addSymbol(INDENT); | |
212 final Expr env = env(); | |
213 Expr exp = new ExprImpl(se(start,"indent")) { | |
214 @Override public Object eval(LuanStateImpl luan) throws LuanException { | |
635
c83b8cefd922
better error handling in theme code
Franklin Schmidt <fschmidt@gmail.com>
parents:
634
diff
changeset
|
215 Object obj = env.eval(luan); |
c83b8cefd922
better error handling in theme code
Franklin Schmidt <fschmidt@gmail.com>
parents:
634
diff
changeset
|
216 if( !(obj instanceof LuanTable) ) |
c83b8cefd922
better error handling in theme code
Franklin Schmidt <fschmidt@gmail.com>
parents:
634
diff
changeset
|
217 throw new LuanException(luan,"bad argument (table expected, got "+Luan.type(obj)+")"); |
c83b8cefd922
better error handling in theme code
Franklin Schmidt <fschmidt@gmail.com>
parents:
634
diff
changeset
|
218 LuanTable tbl = (LuanTable)obj; |
594 | 219 String indent = (String)tbl.get(luan,INDENT); |
220 if( indent==null ) throw new NullPointerException(); | |
221 return indent; | |
222 } | |
223 }; | |
224 // Expr exp = new IndexExpr( se(start,"indent"), env(), new ConstExpr(null,INDENT) ); | |
225 SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(INDENT)), exp ); | |
226 stmts.add(setStmt); | |
227 } | |
228 int end = start; | |
229 while( !matchEndTag(tagName) ) { | |
584 | 230 if( parser.endOfInput() ) |
231 throw exception("unclosed block"); | |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
232 Stmt block = parseBlock(spaces,afterIndent); |
584 | 233 if( block != null ) { |
594 | 234 addText(start,end,stmts,false); |
235 start = parser.currentIndex(); | |
584 | 236 stmts.add(block); |
594 | 237 afterIndent = false; |
584 | 238 continue; |
239 } | |
594 | 240 { |
241 String extraSpaces = null; | |
242 if( afterIndent ) { | |
243 int startSpaces = parser.currentIndex(); | |
244 InlineSpaces(); | |
245 extraSpaces = parser.textFrom(startSpaces); | |
246 end = parser.currentIndex(); | |
247 } | |
248 Stmt simpleTag = parseSimpleTag(extraSpaces); | |
249 if( simpleTag != null ) { | |
250 addText(start,end,stmts,false); | |
251 start = parser.currentIndex(); | |
252 stmts.add(simpleTag); | |
253 afterIndent = false; | |
254 continue; | |
255 } | |
256 if( extraSpaces!=null && extraSpaces.length() > 0 ) | |
257 continue; | |
258 } | |
259 if( EndOfLine() ) { | |
260 end = parser.currentIndex(); | |
261 afterIndent = false; | |
262 if( parser.match(spaces) ) { | |
263 addText(start,end,stmts,true); | |
264 start = parser.currentIndex(); | |
265 afterIndent = true; | |
266 } | |
584 | 267 continue; |
268 } | |
269 parser.anyChar(); | |
594 | 270 end = parser.currentIndex(); |
271 afterIndent = false; | |
584 | 272 } |
594 | 273 addText(start,end,stmts,false); |
274 Stmt block = new Block( stmts.toArray(new Stmt[0]), stackStart, symbolsSize() ); | |
275 popSymbols(1); | |
584 | 276 return block; |
277 } | |
278 | |
594 | 279 private boolean matchEndTag(String tagName) { |
280 parser.begin(); | |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
281 /* |
600
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
282 if( tagName.startsWith("define:") ) |
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
283 EndOfLine(); |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
284 */ |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
285 if( EndOfLine() ) |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
286 InlineSpaces(); |
600
b926e53910dd
change theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
595
diff
changeset
|
287 return parser.match("{/") && parser.match(tagName) && parser.match('}') ? parser.success() : parser.failure(); |
584 | 288 } |
289 | |
594 | 290 private void addText(int start,int end,List<Stmt> stmts,boolean indent) { |
291 List<Expressions> args = new ArrayList<Expressions>(); | |
292 if( start < end ) { | |
293 String text = parser.text.substring(start,end); | |
294 args.add( new ConstExpr(null,text) ); | |
295 } | |
296 if( indent ) { | |
297 args.add( new GetLocalVar(null,stackIndex(INDENT)) ); | |
298 } | |
299 if( !args.isEmpty() ) { | |
300 Expr io = new GetUpVar(null,upValueIndex(IO)); | |
301 Expr stdoutExp = new IndexExpr( se(start,"stdout"), io, new ConstExpr(null,"stdout") ); | |
302 Expr writeExp = new IndexExpr( se(start,"write"), stdoutExp, new ConstExpr(null,"write") ); | |
303 FnCall writeCall = new FnCall( se(start), writeExp, ExpList.build(args) ); | |
304 stmts.add( new ExpressionsStmt(writeCall) ); | |
305 } | |
306 } | |
307 | |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
308 private Stmt parseBlock(String spaces,boolean afterIndent) throws ParseException { |
584 | 309 int start = parser.begin(); |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
310 String tagSpaces = null; |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
311 if( afterIndent ) { |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
312 tagSpaces = spaces; |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
313 } else if( EndOfLine() ) { |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
314 int startSpaces = parser.currentIndex(); |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
315 InlineSpaces(); |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
316 tagSpaces = parser.textFrom(startSpaces); |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
317 } |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
318 if( !parser.match("{block:") ) |
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
319 return parser.failure(null); |
594 | 320 String name = parseName(); |
321 if( name==null ) | |
322 throw exception("invalid block name"); | |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
323 if( !parser.match('}') ) |
594 | 324 return null; |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
325 if( tagSpaces != null ) { |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
326 parser.begin(); |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
327 InlineSpaces(); |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
328 if( EndOfLine() ) { |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
329 int startSpaces = parser.currentIndex(); |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
330 InlineSpaces(); |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
331 String line1Spaces = parser.textFrom(startSpaces); |
608 | 332 if( line1Spaces.startsWith(tagSpaces) ) { |
333 String newSpaces = spaces + line1Spaces.substring(tagSpaces.length()); | |
334 if( line1Spaces.startsWith(newSpaces) ) | |
335 spaces = newSpaces; | |
336 } | |
607
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
337 } |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
338 parser.failure(); // rollback |
c5ad80f869da
improve theming indentation
Franklin Schmidt <fschmidt@gmail.com>
parents:
600
diff
changeset
|
339 } |
584 | 340 frame = new Frame(frame); |
341 addSymbol(ENV); | |
594 | 342 Stmt block = parseBody("block:"+name,spaces,false); |
584 | 343 FnDef fnDef = newFnDef(start,block); |
344 frame = frame.parent; | |
345 // String rtn = "<% env." + tag.name + "(" + (tag.attrs.isEmpty() ? "nil" : table(tag.attrs)) + ",env,function(env) %>" + block + "<% end) %>"; | |
346 Expr env = env(); | |
594 | 347 Expr fn = new IndexExpr( se(start,"block:"+name), env, new ConstExpr(null,name) ); |
584 | 348 List<Expressions> args = new ArrayList<Expressions>(); |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
349 args.add( env ); |
584 | 350 args.add( fnDef ); |
351 FnCall fnCall = new FnCall( se(start), fn, ExpList.build(args) ); | |
352 Stmt rtn = new ExpressionsStmt(fnCall); | |
353 return parser.success(rtn); | |
354 } | |
355 | |
594 | 356 private Stmt parseSimpleTag(String spaces) throws ParseException { |
584 | 357 int start = parser.begin(); |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
358 if( !parser.match('{') ) |
584 | 359 return parser.failure(null); |
360 String name = parseName(); | |
361 if( name==null ) | |
362 return parser.failure(null); | |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
363 if( !parser.match('}') ) |
584 | 364 return parser.failure(null); |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
365 // rtn = "<% env." + name + (attrs.isEmpty() ? "()" : table(attrs)) + " %>"; |
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
366 Expr env = env(); |
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
367 Expr fn = new IndexExpr( se(start,name), env, new ConstExpr(null,name) ); |
594 | 368 if( spaces!=null && spaces.length() > 0 ) { |
369 final Expr oldEnv = env; | |
370 final Expr oldIndentExpr = new GetLocalVar(null,stackIndex(INDENT)); | |
371 final String addSpaces = spaces; | |
372 env = new ExprImpl(se(start,"indent_env")) { | |
373 @Override public Object eval(LuanStateImpl luan) throws LuanException { | |
374 LuanTable mt = new LuanTable(); | |
375 mt.rawPut("__index",oldEnv.eval(luan)); | |
376 LuanTable tbl = new LuanTable(); | |
377 tbl.setMetatable(mt); | |
378 String oldIndent = (String)oldIndentExpr.eval(luan); | |
379 String newIndent = oldIndent + addSpaces; | |
380 tbl.rawPut(INDENT,newIndent); | |
381 return tbl; | |
382 } | |
383 }; | |
384 } | |
595
8370c4009cce
remove theme attributes
Franklin Schmidt <fschmidt@gmail.com>
parents:
594
diff
changeset
|
385 FnCall fnCall = new FnCall( se(start), fn, env ); |
584 | 386 Stmt rtn = new ExpressionsStmt(fnCall); |
387 return parser.success(rtn); | |
388 } | |
389 | |
594 | 390 private void InlineSpaces() { |
391 while( parser.anyOf(" \t") ); | |
392 } | |
393 | |
394 private boolean BlankLine() { | |
395 parser.begin(); | |
396 while( parser.anyOf(" \t") ); | |
397 return EndOfLine() ? parser.success() : parser.failure(); | |
398 } | |
399 | |
400 private boolean EndOfLine() { | |
401 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); | |
402 } | |
403 | |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
404 private String parseName() throws ParseException { |
584 | 405 int start = parser.begin(); |
616
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
406 if( parser.match('/') ) |
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
407 throw exception("bad closing tag"); |
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
408 if( parser.match("define:") ) |
56b0b9018319
improve ThemeParser error handling
Franklin Schmidt <fschmidt@gmail.com>
parents:
608
diff
changeset
|
409 throw exception("unexpected definition"); |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
410 if( !NameChar() ) |
584 | 411 return parser.failure(null); |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
412 while( NameChar() ); |
584 | 413 String match = parser.textFrom(start); |
414 return parser.success(match); | |
415 } | |
416 | |
593
92c9fa5e39e6
remove theme "Get" and "Set", and add "define"
Franklin Schmidt <fschmidt@gmail.com>
parents:
587
diff
changeset
|
417 private boolean NameChar() { |
587 | 418 return parser.inCharRange('a', 'z') || parser.inCharRange('A', 'Z') |
634
3dde072c3420
allow "." in theme function name
Franklin Schmidt <fschmidt@gmail.com>
parents:
616
diff
changeset
|
419 || parser.inCharRange('0', '9') || parser.anyOf("-_."); |
584 | 420 } |
421 | |
422 } |