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