1 using System;
2 using System.Collections;
3 using Cm.Ast;
4
5
6
7
8
9 namespace soulcm.scmpg
10 {
11 public class ArrayGeneratorVisitor : Visitor
12 {
13 public ArrayGeneratorVisitor(Cm.Ast.NamespaceNode* ns_, int& sn_, const Uuid& moduleId_) :
14 ns(ns_), sn(sn_), moduleId(moduleId_)
15 {
16 }
17 public override void Visit(StringParser& parser)
18 {
19 UniquePtr<Cm.Ast.ArrayLiteralNode> arrayLiteral(new Cm.Ast.ArrayLiteralNode(System.Lex.Span(), moduleId));
20 string s = "s" + ToString(sn++);
21 parser.SetArrayName(s);
22 long n = 1;
23 if (parser.Str().IsEmpty())
24 {
25 arrayLiteral->AddValue(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, cast<int>(0)));
26 }
27 else
28 {
29 n = parser.Str().Length();
30 for (uchar c : parser.Str())
31 {
32 arrayLiteral->AddValue(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, cast<int>(c)));
33 }
34 }
35 UniquePtr<Cm.Ast.ConstantNode> arrayConstant(new Cm.Ast.ConstantNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.ArrayNode(System.Lex.Span(), moduleId, new Cm.Ast.IntNode(System.Lex.Span(), moduleId), new Cm.Ast.LongLiteralNode(System.Lex.Span(), moduleId, n)), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, ToUtf32(s)), arrayLiteral.Release()));
36 int index = 0;
37 for (int i = 0; i < ns->Members().Count(); ++i;)
38 {
39 if (ns->Members()[i]->GetNodeType() == NodeType.namespaceImportNode) ++index;
40 }
41 ns->Members().Insert(index, arrayConstant.Release());
42 }
43 public override void Visit(CharSetParser& parser)
44 {
45 UniquePtr<Cm.Ast.ArrayLiteralNode> arrayLiteral(new Cm.Ast.ArrayLiteralNode(System.Lex.Span(), moduleId));
46 string s = "s" + ToString(sn++);
47 parser.SetArrayName(s);
48 bool first = true;
49 for (const System.Parsing.Range& range : parser.Set().Ranges())
50 {
51 Cm.Ast.StructuredLiteralNode* value = new Cm.Ast.StructuredLiteralNode(System.Lex.Span(), moduleId);
52 value->AddMember(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, range.first));
53 value->AddMember(new Cm.Ast.IntLiteralNode(System.Lex.Span(), moduleId, range.last));
54 arrayLiteral->AddValue(value);
55 }
56 UniquePtr<Cm.Ast.ConstantNode> arrayConstant(new Cm.Ast.ConstantNode(System.Lex.Span(), moduleId, Specifiers.public_, new Cm.Ast.ArrayNode(System.Lex.Span(), moduleId, new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, u"Range"), new Cm.Ast.LongLiteralNode(System.Lex.Span(), moduleId, parser.Set().Ranges().Count())), new Cm.Ast.IdentifierNode(System.Lex.Span(), moduleId, ToUtf32(s)), arrayLiteral.Release()));
57 int index = 0;
58 for (int i = 0; i < ns->Members().Count(); ++i;)
59 {
60 if (ns->Members()[i]->GetNodeType() == NodeType.namespaceImportNode || ns->Members()[i]->GetNodeType() == NodeType.constantNode) ++index;
61 }
62 ns->Members().Insert(index, arrayConstant.Release());
63 }
64 public override void Visit(OptionalParser& parser)
65 {
66 parser.Child()->Accept(*this);
67 }
68 public override void Visit(KleeneParser& parser)
69 {
70 parser.Child()->Accept(*this);
71 }
72 public override void Visit(PositiveParser& parser)
73 {
74 parser.Child()->Accept(*this);
75 }
76 public override void Visit(ExpectationParser& parser)
77 {
78 parser.Child()->Accept(*this);
79 }
80 public override void Visit(GroupingParser& parser)
81 {
82 parser.Child()->Accept(*this);
83 }
84 public override void Visit(SequenceParser& parser)
85 {
86 parser.Left()->Accept(*this);
87 parser.Right()->Accept(*this);
88 }
89 public override void Visit(AlternativeParser& parser)
90 {
91 parser.Left()->Accept(*this);
92 parser.Right()->Accept(*this);
93 }
94 public override void Visit(DifferenceParser& parser)
95 {
96 parser.Left()->Accept(*this);
97 parser.Right()->Accept(*this);
98 }
99 public override void Visit(ListParser& parser)
100 {
101 parser.Child()->Accept(*this);
102 }
103 public override void Visit(ActionParser& parser)
104 {
105 parser.Child()->Accept(*this);
106 }
107 public override void Visit(RuleParser& parser)
108 {
109 parser.Definition()->Accept(*this);
110 }
111 public override void Visit(GrammarParser& parser)
112 {
113 for (const UniquePtr<RuleParser>& rule : parser.Rules())
114 {
115 rule->Accept(*this);
116 }
117 }
118 public override void Visit(ParserFile& parserFile)
119 {
120 for (const UniquePtr<GrammarParser>& parser : parserFile.Parsers())
121 {
122 parser->Accept(*this);
123 }
124 }
125 private Cm.Ast.NamespaceNode* ns;
126 private int& sn;
127 private Uuid moduleId;
128 }
129 }