annotate core/src/luan/impl/ThemeParser.java @ 586:a140be489a72

minor
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 24 Aug 2015 02:17:46 -0600
parents 0742ac78fa69
children fa281ee942c8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
584
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
1 package luan.impl;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
2
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
3 import java.util.Map;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
4 import java.util.HashMap;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
5 import java.util.List;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
6 import java.util.ArrayList;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
7 import luan.LuanSource;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
8 import luan.LuanTable;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
9 import luan.LuanElement;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
10 import luan.LuanState;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
11 import luan.LuanFunction;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
12 import luan.LuanException;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
13 import luan.modules.PackageLuan;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
14
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
15
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
16 public final class ThemeParser {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
17
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
18 public static LuanFunction compile(LuanState luan,LuanSource source) throws LuanException {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
19 try {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
20 FnDef fnDef = new ThemeParser(source).parse();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
21 final LuanStateImpl luanImpl = (LuanStateImpl)luan;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
22 return new Closure(luanImpl,fnDef);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
23 } catch(ParseException e) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
24 //e.printStackTrace();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
25 throw new LuanException(luan, e.getFancyMessage() );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
26 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
27 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
28
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
29 private static final class Frame {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
30 final Frame parent;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
31 final List<String> symbols = new ArrayList<String>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
32 int stackSize = 0;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
33 final boolean isVarArg;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
34 final List<String> upValueSymbols = new ArrayList<String>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
35 final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
36
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
37 Frame() {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
38 this.parent = null;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
39 isVarArg = true;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
40 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
41
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
42 Frame(Frame parent) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
43 this.parent = parent;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
44 isVarArg = false;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
45 if( upValueIndex(MOD) != 0 )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
46 throw new RuntimeException();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
47 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
48
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
49 int stackIndex(String name) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
50 int i = symbols.size();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
51 while( --i >= 0 ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
52 if( symbols.get(i).equals(name) )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
53 return i;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
54 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
55 return -1;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
56 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
57
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
58 int upValueIndex(String name) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
59 int i = upValueSymbols.size();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
60 while( --i >= 0 ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
61 if( upValueSymbols.get(i).equals(name) )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
62 return i;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
63 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
64 if( parent==null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
65 return -1;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
66 i = parent.stackIndex(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
67 if( i != -1 ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
68 upValueGetters.add(new UpValue.StackGetter(i));
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
69 } else {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
70 i = parent.upValueIndex(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
71 if( i == -1 )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
72 return -1;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
73 upValueGetters.add(new UpValue.NestedGetter(i));
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
74 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
75 upValueSymbols.add(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
76 return upValueSymbols.size() - 1;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
77 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
78
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
79 void addUpValueGetter(String name,UpValue.Getter upValueGetter) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
80 upValueSymbols.add(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
81 upValueGetters.add(upValueGetter);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
82 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
83 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
84
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
85 private static final String IO = "-IO-";
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
86 private static final String MOD = "-MOD-";
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
87 private static final String ENV = "-ENV-";
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
88 private static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0];
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
89
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
90 private final LuanSource source;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
91 private final Parser parser;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
92 private Frame frame = new Frame();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
93
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
94 private ThemeParser(LuanSource source) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
95 this.source = source;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
96 this.parser = new Parser(this.source);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
97 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
98
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
99 private LuanElement se(int start) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
100 return se(start,null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
101 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
102
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
103 private LuanElement se(int start,String text) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
104 return new LuanElement(source,start,parser.currentIndex(),text);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
105 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
106
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
107 private int symbolsSize() {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
108 return frame.symbols.size();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
109 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
110
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
111 private void addSymbol(String name) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
112 frame.symbols.add(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
113 if( frame.stackSize < symbolsSize() )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
114 frame.stackSize = symbolsSize();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
115 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
116
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
117 private FnDef newFnDef(int start,Stmt stmt) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
118 return new FnDef( se(start), stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
119 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
120
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
121 private int stackIndex(String name) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
122 return frame.stackIndex(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
123 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
124
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
125 private int upValueIndex(String name) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
126 return frame.upValueIndex(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
127 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
128
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
129 private ParseException exception(String msg) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
130 parser.failure();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
131 return parser.exception(msg);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
132 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
133
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
134 private Expr env() {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
135 return new GetLocalVar(null,stackIndex(ENV));
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
136 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
137
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
138 private FnDef parse() throws ParseException {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
139 List<Stmt> stmts = new ArrayList<Stmt>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
140 int stackStart = symbolsSize();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
141 {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
142 addSymbol(IO);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
143 LuanElement se = se(0,"require 'luan:Io'");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
144 FnCall requireCall = new FnCall( se, new ConstExpr(se,PackageLuan.requireFn), new ConstExpr(se,"luan:Io") );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
145 SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(IO)), new ExpressionsExpr(requireCall) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
146 stmts.add(setStmt);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
147 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
148 {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
149 addSymbol(MOD);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
150 LuanElement se = se(0,"local M = {}");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
151 TableExpr tableExpr = new TableExpr( se, new TableExpr.Field[0], ExpList.emptyExpList );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
152 SetStmt setStmt = new SetStmt( new SetLocalVar(stackIndex(MOD)), tableExpr );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
153 stmts.add(setStmt);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
154 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
155 while( !parser.endOfInput() ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
156 Stmt def = parseDef();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
157 if( def != null ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
158 stmts.add(def);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
159 } else {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
160 parser.anyChar();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
161 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
162 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
163 stmts.add( new ReturnStmt(null,new GetLocalVar(null,stackIndex(MOD))) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
164 Stmt block = new Block( stmts.toArray(new Stmt[0]), stackStart, symbolsSize() );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
165 FnDef fnDef = newFnDef(0,block);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
166 return fnDef;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
167 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
168
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
169 private static class Tag {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
170 final String name;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
171 final Map<String,String> attrs;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
172
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
173 Tag(String name,Map<String,String> attrs) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
174 this.name = name;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
175 this.attrs = attrs;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
176 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
177 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
178
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
179 private Stmt parseDef() throws ParseException {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
180 int start = parser.begin();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
181 Tag tag = parseBlockTag();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
182 if( tag == null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
183 return parser.failure(null);
586
Franklin Schmidt <fschmidt@gmail.com>
parents: 584
diff changeset
184 parser.match('\r'); parser.match('\n'); // ignore newline
584
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
185 Stmt rtn = null;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
186 if( tag.name.equals("Set") ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
187 String name = tag.attrs.remove("name");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
188 if( name == null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
189 throw exception("block:Set missing required attribute 'name'");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
190 if( !tag.attrs.isEmpty() )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
191 throw exception("block:Set has unrecognized attributes: "+tag.attrs);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
192 if( !validateName(name) )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
193 throw exception("invalid Set name: "+name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
194 addSymbol( name );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
195 frame = new Frame(frame);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
196 addSymbol(ENV);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
197 Stmt block = parseBody(tag);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
198 FnDef fnDef = newFnDef(start,block);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
199 frame = frame.parent;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
200 rtn = new SetStmt( new SetLocalVar(symbolsSize()-1), fnDef );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
201 } else {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
202 if( !tag.attrs.isEmpty() )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
203 throw exception("this block should have no attributes");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
204 Expr table = new GetLocalVar(null,stackIndex(MOD));
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
205 Settable fnName = new SetTableEntry(se(start),table,new ConstExpr(null,tag.name));
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
206 frame = new Frame(frame);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
207 addSymbol(ENV);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
208 Stmt block = parseBody(tag);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
209 FnDef fnDef = newFnDef(start,block);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
210 frame = frame.parent;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
211 rtn = new SetStmt(fnName,fnDef);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
212 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
213 return parser.success(rtn);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
214 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
215
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
216 private Stmt parseBody(Tag tag) throws ParseException {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
217 String endTag = "{/block:" + tag.name + "}";
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
218 List<Stmt> stmts = new ArrayList<Stmt>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
219 int stackStart = symbolsSize();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
220 StringBuilder sb = new StringBuilder();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
221 int start = -1;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
222 while( !parser.match(endTag) ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
223 if( parser.endOfInput() )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
224 throw exception("unclosed block");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
225 Stmt block = parseBlock();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
226 if( block != null ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
227 addText(start,stmts,sb);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
228 stmts.add(block);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
229 continue;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
230 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
231 Stmt simpleTag = parseSimpleTag();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
232 if( simpleTag != null ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
233 addText(start,stmts,sb);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
234 stmts.add(simpleTag);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
235 continue;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
236 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
237 if( sb.length() == 0 )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
238 start = parser.currentIndex();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
239 sb.append( parser.currentChar() );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
240 parser.anyChar();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
241 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
242 addText(start,stmts,sb);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
243 Stmt block = new Block( stmts.toArray(new Stmt[0]), 0, symbolsSize() );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
244 return block;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
245 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
246
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
247 private void addText(int start,List<Stmt> stmts,StringBuilder sb) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
248 if( sb.length() == 0 )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
249 return;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
250 Expr io = new GetUpVar(null,upValueIndex(IO));
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
251 Expr stdoutExp = new IndexExpr( se(start,"stdout"), io, new ConstExpr(null,"stdout") );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
252 Expr writeExp = new IndexExpr( se(start,"write"), stdoutExp, new ConstExpr(null,"write") );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
253 FnCall writeCall = new FnCall( se(start), writeExp, new ConstExpr(null,sb.toString()) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
254 stmts.add( new ExpressionsStmt(writeCall) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
255 sb.setLength(0);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
256 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
257
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
258 private Stmt parseBlock() throws ParseException {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
259 int start = parser.begin();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
260 Tag tag = parseBlockTag();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
261 if( tag == null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
262 return parser.failure(null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
263 if( tag.name.equals("Set") )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
264 throw exception("block:Set not allowed here");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
265 frame = new Frame(frame);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
266 addSymbol(ENV);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
267 Stmt block = parseBody(tag);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
268 FnDef fnDef = newFnDef(start,block);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
269 frame = frame.parent;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
270 // String rtn = "<% env." + tag.name + "(" + (tag.attrs.isEmpty() ? "nil" : table(tag.attrs)) + ",env,function(env) %>" + block + "<% end) %>";
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
271 Expr env = env();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
272 Expr fn = new IndexExpr( se(start,"block:"+tag.name), env, new ConstExpr(null,tag.name) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
273 List<Expressions> args = new ArrayList<Expressions>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
274 args.add( tag.attrs.isEmpty() ? new ConstExpr(null,null) : table(tag.attrs) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
275 args.add( env );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
276 args.add( fnDef );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
277 FnCall fnCall = new FnCall( se(start), fn, ExpList.build(args) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
278 Stmt rtn = new ExpressionsStmt(fnCall);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
279 return parser.success(rtn);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
280 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
281
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
282 private Tag parseBlockTag() throws ParseException {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
283 parser.begin();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
284 if( !parser.match("{block:") )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
285 return parser.failure(null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
286 String name = parseName();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
287 if( name==null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
288 throw exception("invalid block name");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
289 Map<String,String> attrs = parseAttrs();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
290 if( !parser.match("}") )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
291 return parser.failure(null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
292 Tag tag = new Tag(name,attrs);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
293 return parser.success(tag);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
294 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
295
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
296 private Stmt parseSimpleTag() throws ParseException {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
297 int start = parser.begin();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
298 if( !parser.match("{") )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
299 return parser.failure(null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
300 String name = parseName();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
301 if( name==null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
302 return parser.failure(null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
303 Map<String,String> attrs = parseAttrs();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
304 if( !parser.match("}") )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
305 return parser.failure(null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
306 FnCall fnCall;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
307 if( name.equals("Get") ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
308 name = attrs.remove("name");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
309 if( name == null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
310 throw exception("Get missing required attribute 'name'");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
311 if( !attrs.isEmpty() )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
312 throw exception("Get has unrecognized attributes: "+attrs);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
313 if( !validateName(name) )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
314 throw exception("invalid Get name: "+name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
315 // rtn = "<% " + name + "(env) %>";
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
316 int index = upValueIndex(name);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
317 if( index == -1 )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
318 throw exception("name '"+name+"' not defined");
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
319 Expr fn = new GetUpVar(se(start,name),index);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
320 fnCall = new FnCall( se(start), fn, env() );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
321 } else {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
322 // rtn = "<% env." + name + (attrs.isEmpty() ? "()" : table(attrs)) + " %>";
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
323 Expr fn = new IndexExpr( se(start,name), env(), new ConstExpr(null,name) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
324 Expressions args = attrs.isEmpty() ? ExpList.emptyExpList : table(attrs);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
325 fnCall = new FnCall( se(start), fn, args );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
326 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
327 Stmt rtn = new ExpressionsStmt(fnCall);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
328 return parser.success(rtn);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
329 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
330
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
331 private TableExpr table(Map<String,String> attrs) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
332 List<TableExpr.Field> fields = new ArrayList<TableExpr.Field>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
333 for( Map.Entry<String,String> entry : attrs.entrySet() ) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
334 ConstExpr key = new ConstExpr(null,entry.getKey());
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
335 ConstExpr value = new ConstExpr(null,entry.getValue());
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
336 fields.add( new TableExpr.Field(key,value) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
337 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
338 return new TableExpr( null, fields.toArray(new TableExpr.Field[0]), ExpList.emptyExpList );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
339 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
340
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
341 private Map<String,String> parseAttrs() {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
342 Map<String,String> attrs = new HashMap<String,String>();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
343 while( parseAttr(attrs) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
344 Spaces();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
345 return attrs;
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
346 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
347
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
348 private boolean parseAttr(Map<String,String> attrs) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
349 parser.begin();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
350 Spaces();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
351 String name = parseName();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
352 if( name==null )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
353 return parser.failure();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
354 Spaces();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
355 if( !parser.match('=') )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
356 return parser.failure();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
357 Spaces();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
358 if( !parser.match('"') )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
359 return parser.failure();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
360 int start = parser.currentIndex();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
361 while( parser.noneOf("\"}") );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
362 String val = parser.textFrom(start);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
363 if( !parser.match('"') )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
364 return parser.failure();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
365 attrs.put(name,val);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
366 return parser.success();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
367 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
368
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
369 private void Spaces() {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
370 while( parser.anyOf(" \t\r\n") );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
371 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
372
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
373 private String parseName() {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
374 return parseName(parser);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
375 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
376
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
377 private static boolean validateName(String name) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
378 return name.equals(parseName(new Parser(new LuanSource("NAME",name))));
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
379 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
380
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
381 private static String parseName(Parser parser) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
382 int start = parser.begin();
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
383 if( !NameFirstChar(parser) )
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
384 return parser.failure(null);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
385 while( NameChar(parser) );
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
386 String match = parser.textFrom(start);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
387 return parser.success(match);
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
388 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
389
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
390 private static boolean NameChar(Parser parser) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
391 return NameFirstChar(parser) || parser.inCharRange('0', '9');
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
392 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
393
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
394 private static boolean NameFirstChar(Parser parser) {
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
395 return parser.inCharRange('a', 'z') || parser.inCharRange('A', 'Z') || parser.match('_');
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
396 }
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
397
0742ac78fa69 add Luan.load_theme
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
398 }