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<ustringustring>.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<ustringustring> 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<ustringint>.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<ustringint> 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<intAction*>.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<intAction*> 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<ustringLexerStatement*>.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<ustringLexerStatement*> 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<ustringDeclaration*> declarationMap;
420         private Expressions* expressions;
421         private Keywords* keywords;
422         private Lexer* lexer;
423     }
424 } // namespace soulcm.scm2html