1
|
1 module sema.Visitor;
|
|
2
|
|
3 import tango.io.Stdout;
|
|
4
|
|
5 public
|
|
6 import ast.Decl,
|
|
7 ast.Stmt,
|
|
8 ast.Exp;
|
|
9
|
|
10 import lexer.Token;
|
|
11
|
|
12 class Visitor(FinalT = int, DeclT = FinalT, StmtT = DeclT, ExpT = StmtT)
|
|
13 {
|
|
14 public:
|
|
15 FinalT visit(Decl[] decls)
|
|
16 {
|
|
17 foreach (decl; decls)
|
|
18 visitDecl(decl);
|
|
19 static if (is(FinalT == void))
|
|
20 return;
|
|
21 else
|
|
22 return FinalT.init;
|
|
23 }
|
|
24
|
|
25 DeclT visitDecl(Decl decl)
|
|
26 {
|
|
27 switch(decl.declType)
|
|
28 {
|
|
29 case DeclType.FuncDecl:
|
|
30 return visitFuncDecl(cast(FuncDecl)decl);
|
|
31 case DeclType.VarDecl:
|
|
32 return visitVarDecl(cast(VarDecl)decl);
|
|
33 default:
|
|
34 throw new Exception("Unknown declaration type");
|
|
35 }
|
|
36 }
|
|
37
|
|
38 StmtT visitStmt(Stmt stmt)
|
|
39 {
|
|
40 switch(stmt.stmtType)
|
|
41 {
|
|
42 case StmtType.Return:
|
|
43 return visitReturnStmt(cast(ReturnStmt)stmt);
|
|
44 case StmtType.Decl:
|
|
45 return visitDeclStmt(cast(DeclStmt)stmt);
|
|
46 case StmtType.Exp:
|
|
47 return visitExpStmt(cast(ExpStmt)stmt);
|
|
48 default:
|
|
49 throw new Exception("Unknown statement type");
|
|
50 }
|
|
51 }
|
|
52
|
|
53 ExpT visitExp(Exp exp)
|
|
54 {
|
|
55 switch(exp.expType)
|
|
56 {
|
|
57 case ExpType.Binary:
|
|
58 return visitBinaryExp(cast(BinaryExp)exp);
|
|
59 case ExpType.IntegerLit:
|
|
60 return visitIntegerLit(cast(IntegerLit)exp);
|
|
61 case ExpType.Negate:
|
|
62 return visitNegateExp(cast(NegateExp)exp);
|
|
63 case ExpType.AssignExp:
|
|
64 return visitAssignExp(cast(AssignExp)exp);
|
|
65 case ExpType.CallExp:
|
|
66 return visitCallExp(cast(CallExp)exp);
|
|
67 case ExpType.Identifier:
|
|
68 return visitIdentifier(cast(Identifier)exp);
|
|
69 default:
|
|
70 throw new Exception("Unknown expression type");
|
|
71 }
|
|
72 }
|
|
73
|
|
74 // Declarations:
|
|
75 DeclT visitVarDecl(VarDecl d)
|
|
76 {
|
|
77 visitExp(d.type);
|
|
78 visitExp(d.identifier);
|
|
79 if (d.init)
|
|
80 visitExp(d.init);
|
|
81
|
|
82 static if (is(DeclT == void))
|
|
83 return;
|
|
84 else
|
|
85 return DeclT.init;
|
|
86 }
|
|
87
|
|
88 DeclT visitFuncDecl(FuncDecl f)
|
|
89 {
|
|
90 visitExp(f.type);
|
|
91 visitExp(f.identifier);
|
|
92 foreach (arg; f.funcArgs)
|
|
93 visitDecl(arg);
|
|
94 foreach (stmt; f.statements)
|
|
95 visitStmt(stmt);
|
|
96
|
|
97 static if (is(DeclT == void))
|
|
98 return;
|
|
99 else
|
|
100 return DeclT.init;
|
|
101 }
|
|
102
|
|
103 // Statements:
|
|
104 StmtT visitReturnStmt(ReturnStmt s)
|
|
105 {
|
|
106 visitExp(s.exp);
|
|
107 static if (is(StmtT == void))
|
|
108 return;
|
|
109 else
|
|
110 return StmtT.init;
|
|
111 }
|
|
112
|
|
113 StmtT visitDeclStmt(DeclStmt d)
|
|
114 {
|
|
115 visitDecl(d.decl);
|
|
116 static if (is(StmtT == void))
|
|
117 return;
|
|
118 else
|
|
119 return StmtT.init;
|
|
120 }
|
|
121
|
|
122 StmtT visitExpStmt(ExpStmt s)
|
|
123 {
|
|
124 visitExp(s.exp);
|
|
125 static if (is(StmtT == void))
|
|
126 return;
|
|
127 else
|
|
128 return StmtT.init;
|
|
129 }
|
|
130
|
|
131 // Expressions:
|
|
132 ExpT visitAssignExp(AssignExp exp)
|
|
133 {
|
|
134 visitExp(exp.identifier);
|
|
135 visitExp(exp.exp);
|
|
136 static if (is(ExpT == void))
|
|
137 return;
|
|
138 else
|
|
139 return ExpT.init;
|
|
140 }
|
|
141
|
|
142 ExpT visitBinaryExp(BinaryExp exp)
|
|
143 {
|
|
144 visitExp(exp.left);
|
|
145 visitExp(exp.right);
|
|
146 static if (is(ExpT == void))
|
|
147 return;
|
|
148 else
|
|
149 return ExpT.init;
|
|
150 }
|
|
151
|
|
152 ExpT visitCallExp(CallExp exp)
|
|
153 {
|
|
154 visitExp(exp.exp);
|
|
155 foreach (arg; exp.args)
|
|
156 visitExp(arg);
|
|
157 static if (is(ExpT == void))
|
|
158 return;
|
|
159 else
|
|
160 return ExpT.init;
|
|
161 }
|
|
162
|
|
163 ExpT visitNegateExp(NegateExp exp)
|
|
164 {
|
|
165 visitExp(exp.exp);
|
|
166 static if (is(ExpT == void))
|
|
167 return;
|
|
168 else
|
|
169 return ExpT.init;
|
|
170 }
|
|
171
|
|
172 ExpT visitIntegerLit(IntegerLit exp)
|
|
173 {
|
|
174 static if (is(ExpT == void))
|
|
175 return;
|
|
176 else
|
|
177 return ExpT.init;
|
|
178 }
|
|
179
|
|
180 ExpT visitIdentifier(Identifier exp)
|
|
181 {
|
|
182 static if (is(ExpT == void))
|
|
183 return;
|
|
184 else
|
|
185 return ExpT.init;
|
|
186 }
|
|
187 }
|
|
188
|