1 using System;
2 using System.Collections;
3
4 namespace soulcm.scm2html
5 {
6 public abstract class Declaration
7 {
8 public Declaration(const ustring& name_) :
9 name(name_)
10 {
11 }
12 public virtual ~Declaration()
13 {
14 }
15 public const ustring& Name() const
16 {
17 return name;
18 }
19 private ustring name;
20 }
21
22 public class ClassMap : Declaration
23 {
24 public ClassMap(const ustring& name_) :
25 base(name_)
26 {
27 }
28 }
29
30 public class Usings : Declaration
31 {
32 public Usings() :
33 base(u"usings")
34 {
35 }
36 public const List<UniquePtr<Cm.Ast.Node>>& UsingNodes() const
37 {
38 return usingNodes;
39 }
40 public void AddMember(Cm.Ast.Node* usingNode)
41 {
42 usingNodes.Add(UniquePtr<Cm.Ast.Node>(usingNode));
43 }
44 private List<UniquePtr<Cm.Ast.Node>> usingNodes;
45 }
46
47 public class Token
48 {
49 public Token() :
50 name(), info()
51 {
52 }
53 public Token(const ustring& name_, const string& info_) :
54 name(name_), info(info_)
55 {
56 }
57 public ustring name;
58 public string info;
59 }
60
61 public class Tokens : Declaration
62 {
63 public Tokens(const ustring& name_) :
64 base(name_)
65 {
66 }
67 public void Add(const Token& token)
68 {
69 tokens.Add(token);
70 }
71 private List<Token> tokens;
72 }
73
74 public class Keyword
75 {
76 public Keyword(const ustring& kw_, const ustring& token_) :
77 kw(kw_), token(token_)
78 {
79 }
80 public ustring kw;
81 public ustring token;
82 }
83
84 public class Keywords : Declaration
85 {
86 public Keywords(const ustring& name_) :
87 base(name_)
88 {
89 }
90 public void Add(Keyword* keyword)
91 {
92 keywords.Add(UniquePtr<Keyword>(keyword));
93 keywordMap[keyword->token] = keyword->kw;
94 }
95 public ustring GetKeyword(const ustring& tokenId) const
96 {
97 Map<ustring, ustring>.ConstIterator it = keywordMap.CFind(tokenId);
98 if (it != keywordMap.CEnd())
99 {
100 return it->second;
101 }
102 else
103 {
104 return ustring();
105 }
106 }
107 private List<UniquePtr<Keyword>> keywords;
108 private Map<ustring, ustring> keywordMap;
109 }
110
111 public class Expression
112 {
113 public Expression(int index_, const ustring& id_, const ustring& value_, int line_) :
114 index(index_), id(id_), value(value_), line(line_)
115 {
116 }
117 public void Parse(LexerContext& lexerContext)
118 {
119 RegExLexer lexer(value, "", 0);
120 regEx = LexRegExParser.Parse(lexer, &lexerContext);
121 }
122 public int Index() const
123 {
124 return index;
125 }
126 public const ustring& Id() const
127 {
128 return id;
129 }
130 public const ustring& Value() const
131 {
132 return value;
133 }
134 public int Line() const
135 {
136 return line;
137 }
138 public inline nothrow RegExpression* RegEx() const
139 {
140 return regEx.Get();
141 }
142 public nothrow void SetRegEx(RegExpression* regEx_)
143 {
144 regEx.Reset(regEx_);
145 }
146 private int index;
147 private ustring id;
148 private ustring value;
149 private int line;
150 private UniquePtr<RegExpression> regEx;
151 }
152
153 public class Expressions : Declaration
154 {
155 public Expressions() :
156 base(u"expressions")
157 {
158 }
159 public void Add(Expression* expression)
160 {
161 expressions.Add(UniquePtr<Expression>(expression));
162 exprMap[expression->Id()] = expression->Index();
163 }
164 public Expression* Get(const ustring& id) const
165 {
166 Map<ustring, int>.ConstIterator it = exprMap.CFind(id);
167 if (it != exprMap.CEnd())
168 {
169 int index = it->second;
170 return expressions[index].Get();
171 }
172 else
173 {
174 throw Exception("expression \'" + ToUtf8(id) + "\' not found");
175 }
176 }
177 public void Parse(LexerContext& lexerContext)
178 {
179 for (const UniquePtr<Expression>& expr : expressions)
180 {
181 expr->Parse(lexerContext);
182 }
183 Expression* idStart = new Expression(cast<int>(expressions.Count()), u"idstart", ustring(), 0);
184 idStart->SetRegEx(new SymbolExpr(lexerContext.MakeIdStart()));
185 Add(idStart);
186 Expression* idCont = new Expression(cast<int>(expressions.Count()), u"idcont", ustring(), 0);
187 idCont->SetRegEx(new SymbolExpr(lexerContext.MakeIdCont()));
188 Add(idCont);
189 }
190 private List<UniquePtr<Expression>> expressions;
191 private Map<ustring, int> exprMap;
192 }
193
194 public class LexerVariable
195 {
196 public LexerVariable(Cm.Ast.Node* type_, const ustring& name_) :
197 type(type_), name(name_)
198 {
199 }
200 public Cm.Ast.Node* GetType() const
201 {
202 return type.Get();
203 }
204 public const ustring& Name() const
205 {
206 return name;
207 }
208 private UniquePtr<Cm.Ast.Node> type;
209 private ustring name;
210 }
211
212 class TokenIdResolverVisitor : Cm.Ast.DefaultVisitor
213 {
214 public override void Visit(ReturnStatementNode& returnStatement)
215 {
216 if (tokenId.IsEmpty())
217 {
218 if (returnStatement.Expression() != null)
219 {
220 tokenId = ToUtf32(returnStatement.Expression()->ToString());
221 }
222 }
223 }
224 public const ustring& TokenId() const
225 {
226 return tokenId;
227 }
228 private ustring tokenId;
229 }
230
231 public class LexerStatement
232 {
233 public LexerStatement(const ustring& expr_, Cm.Ast.CompoundStatementNode* stmt_, int action_, int line_) :
234 index(-1), expr(expr_), stmt(stmt_), retract(true), action(action_), line(line_)
235 {
236 TokenIdResolverVisitor visitor;
237 stmt->Accept(visitor);
238 tokenId = visitor.TokenId();
239 }
240 public void Parse(LexerContext& lexerContext)
241 {
242 RegExLexer lexer(expr, "", 0);
243 regEx = LexRegExParser.Parse(lexer, &lexerContext);
244 }
245 public void SetIndex(int index_)
246 {
247 index = index_;
248 }
249 public int Index() const
250 {
251 return index;
252 }
253 public Cm.Ast.CompoundStatementNode* Code() const
254 {
255 return stmt.Get();
256 }
257 public bool Retract() const
258 {
259 return retract;
260 }
261 public int Action() const
262 {
263 return action;
264 }
265 public int Line() const
266 {
267 return line;
268 }
269 public const ustring& TokenId() const
270 {
271 return tokenId;
272 }
273 public inline nothrow RegExpression* RegEx() const
274 {
275 return regEx.Get();
276 }
277 private int index;
278 private ustring expr;
279 private UniquePtr<Cm.Ast.CompoundStatementNode> stmt;
280 private bool retract;
281 private int action;
282 private int line;
283 private ustring tokenId;
284 private UniquePtr<RegExpression> regEx;
285 }
286
287 public class Action
288 {
289 public Action(int id_, Cm.Ast.CompoundStatementNode* stmt_) :
290 id(id_), stmt(stmt_)
291 {
292 }
293 public int Id() const
294 {
295 return id;
296 }
297 public Cm.Ast.CompoundStatementNode* Code() const
298 {
299 return stmt.Get();
300 }
301 private int id;
302 private UniquePtr<Cm.Ast.CompoundStatementNode> stmt;
303 }
304
305 public class Actions : Declaration
306 {
307 public Actions() :
308 base(u"actions")
309 {
310 }
311 public void Add(Action* action)
312 {
313 actions.Add(UniquePtr<Action>(action));
314 actionMap[action->Id()] = action;
315 }
316 public Action* Get(int id) const
317 {
318 Map<int, Action*>.ConstIterator it = actionMap.CFind(id);
319 if (it != actionMap.CEnd())
320 {
321 return it->second;
322 }
323 else
324 {
325 return null;
326 }
327 }
328 private List<UniquePtr<Action>> actions;
329 private Map<int, Action*> actionMap;
330 }
331
332 public class Lexer : Declaration
333 {
334 public Lexer(const ustring& api_, const ustring& name_) :
335 base(name_), api(api_)
336 {
337 }
338 public void AddStatement(LexerStatement* stmt)
339 {
340 stmt->SetIndex(cast<int>(statements.Count()));
341 statements.Add(UniquePtr<LexerStatement>(stmt));
342 lexerStatementMap[stmt->TokenId()] = stmt;
343 }
344 public void AddVariable(LexerVariable* variable)
345 {
346 variables.Add(UniquePtr<LexerVariable>(variable));
347 }
348 public void AddAction(Action* action)
349 {
350 actions.Add(action);
351 }
352 public inline nothrow LexerStatement* GetStatement(const ustring& tokenId) const
353 {
354 Map<ustring, LexerStatement*>.ConstIterator it = lexerStatementMap.CFind(tokenId);
355 if (it != lexerStatementMap.CEnd())
356 {
357 return it->second;
358 }
359 else
360 {
361 return null;
362 }
363 }
364 public void Parse(LexerContext& lexerContext)
365 {
366 for (const UniquePtr<LexerStatement>& stmt : statements)
367 {
368 stmt->Parse(lexerContext);
369 }
370 }
371 private ustring api;
372 private List<UniquePtr<LexerStatement>> statements;
373 private List<UniquePtr<LexerVariable>> variables;
374 private Actions actions;
375 private Map<ustring, LexerStatement*> lexerStatementMap;
376 }
377
378 public class LexerFile
379 {
380 public void Add(Declaration* declaration)
381 {
382 declarations.Add(UniquePtr<Declaration>(declaration));
383 declarationMap[declaration->Name()] = declaration;
384 if (declaration is Expressions*)
385 {
386 expressions = cast<Expressions*>(declaration);
387 }
388 else if (declaration is Keywords*)
389 {
390 keywords = cast<Keywords*>(declaration);
391 }
392 else if (declaration is Lexer*)
393 {
394 lexer = cast<Lexer*>(declaration);
395 }
396 }
397 public inline nothrow Expressions* GetExpressions()
398 {
399 return expressions;
400 }
401 public inline nothrow Keywords* GetKeywords()
402 {
403 return keywords;
404 }
405 public inline nothrow Lexer* GetLexer()
406 {
407 return lexer;
408 }
409 public void Parse(LexerContext& lexerContext)
410 {
411 expressions->Parse(lexerContext);
412 lexer->Parse(lexerContext);
413 }
414 public void Accept(Visitor& visitor)
415 {
416 visitor.Visit(*this);
417 }
418 private List<UniquePtr<Declaration>> declarations;
419 private Map<ustring, Declaration*> declarationMap;
420 private Expressions* expressions;
421 private Keywords* keywords;
422 private Lexer* lexer;
423 }
424 }