]> gitweb.ps.run Git - toc/blob - src/repr_get.h
function resolution, pre generics
[toc] / src / repr_get.h
1 #pragma once\r
2 \r
3 #include "repr.h"\r
4 \r
5 Type                getType(TocParser::TypeContext * ctx);\r
6 Variable            getVariable(TocParser::VarContext * ctx);\r
7 Body                getBody(TocParser::BodyContext * ctx, std::shared_ptr<Context> parent);\r
8 Function            getFunction(TocParser::FuncContext * ctx, std::shared_ptr<Context> parent);\r
9 Struct              getStruct(TocParser::StructDeclContext * ctx, std::shared_ptr<Context> parent);\r
10 Namespace           getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptr<Context> parent);\r
11 Program             getProgram(TocParser::ProgContext * ctx, std::shared_ptr<Context> parent);\r
12 \r
13 \r
14 Expr                getExpr(TocParser::FuncExprContext * ctx);\r
15 Expr                getExpr(TocParser::MethodExprContext * ctx);\r
16 Expr                getExpr(TocParser::LitExprContext * ctx);\r
17 Expr                getExpr(TocParser::ParenExprContext * ctx);\r
18 Expr                getExpr(TocParser::DotExprContext * ctx);\r
19 Expr                getExpr(TocParser::PrefixOpExprContext * ctx);\r
20 Expr                getExpr(TocParser::PostfixOpExprContext * ctx);\r
21 Expr                getExpr(TocParser::BinaryOpExprContext * ctx);\r
22 Expr                getExpr(TocParser::TernaryOpExprContext * ctx);\r
23 Expr                getExpr(TocParser::BracketExprContext * ctx);\r
24 Expr                getExpr(TocParser::IdentifierExprContext * ctx);\r
25 Expr                getExpr(TocParser::ExprContext * ctx);\r
26 \r
27 Stmt                getStmt(TocParser::StmtContext * ctx, std::shared_ptr<Context> parent);\r
28 \r
29 Type getType(TocParser::TypeContext * ctx)\r
30 {\r
31   Type result;\r
32   for (auto n : ctx->namespaceSpecifier())\r
33     result.namespacePrefixes.push_back(n->typeName()->getText());\r
34   result.name = ctx->typeName()->NAME()->toString();\r
35   for (auto m : ctx->typeModifier())\r
36   {\r
37     bool isPointer = m->getText() == "*";\r
38     bool isStaticArray = m->INT_LIT() != nullptr;\r
39 \r
40     result.modifiers.emplace_back(\r
41       isPointer ? TypeModifierType::Pointer : TypeModifierType::Array,\r
42       isStaticArray,\r
43       isStaticArray ? atoi(m->INT_LIT()->toString().c_str()) : -1\r
44     );\r
45   }\r
46   return result;\r
47 }\r
48 Variable getVariable(TocParser::VarContext * ctx)\r
49 {\r
50   Variable result;\r
51   result.name = ctx->varName()->NAME()->toString();\r
52   result.type = getType(ctx->type());\r
53   return result;\r
54 }\r
55 Body getBody(TocParser::BodyContext * ctx, std::shared_ptr<Context> parent)\r
56 {\r
57   Body result;\r
58   result.ctx = std::make_unique<Context>();\r
59   result.ctx->parent = parent;\r
60   for (auto s : ctx->stmt())\r
61   {\r
62     if (s->varDecl() != nullptr)\r
63     {\r
64       result.ctx->variables.push_back(getVariable(s->varDecl()->var()));\r
65       if (s->varDecl()->var()->expr() != nullptr)\r
66         result.statements.push_back(getStmt(s, result.ctx));\r
67     }\r
68     else\r
69     {\r
70       result.statements.push_back(getStmt(s, result.ctx));\r
71     }\r
72   }\r
73   return result;\r
74 }\r
75 Function getFunction(TocParser::FuncContext * ctx, std::shared_ptr<Context> parent)\r
76 {\r
77   Function result;\r
78   result.name = ctx->funcName()->NAME()->toString();\r
79   result.returnType = getType(ctx->type());\r
80   if (!ctx->parameter()->var().empty())\r
81   {\r
82     for (auto p : ctx->parameter()->var())\r
83       result.parameters.push_back(getVariable(p));\r
84   }\r
85   if (ctx->body() != nullptr)\r
86   {\r
87     result.body = getBody(ctx->body(), parent);\r
88     result.defined = true;\r
89   }\r
90   else\r
91   {\r
92     result.defined = false;\r
93   }\r
94   return result;\r
95 }\r
96 Struct getStruct(TocParser::StructDeclContext * ctx, std::shared_ptr<Context> parent)\r
97 {\r
98   Struct result;\r
99   result.name = ctx->structName()->NAME()->toString();\r
100   for (auto m : ctx->structMember())\r
101   {\r
102     if (m->structVar() != nullptr)\r
103     {\r
104       result.members.push_back({\r
105         getVariable(m->structVar()->var()),\r
106         m->privateDecl() != nullptr\r
107       });\r
108     }\r
109     if (m->structMethod() != nullptr)\r
110     {\r
111       result.methods.push_back({\r
112         getFunction(m->structMethod()->func(), parent),\r
113         m->privateDecl() != nullptr\r
114       });\r
115     }\r
116   }\r
117   return result;\r
118 }\r
119 Namespace getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptr<Context> parent)\r
120 {\r
121   Namespace result;\r
122   result.ctx = std::make_unique<Context>();\r
123   result.name = ctx->typeName()->getText();\r
124   for (auto d : ctx->decl())\r
125   {\r
126     if (d->varDecl() != nullptr)\r
127     {\r
128       result.ctx->variables.push_back(getVariable(d->varDecl()->var()));\r
129     }\r
130     if (d->funcDecl() != nullptr)\r
131     {\r
132       result.functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
133     }\r
134     if (d->structDecl() != nullptr)\r
135     {\r
136       result.structs.push_back(getStruct(d->structDecl(), result.ctx));\r
137     }\r
138     if (d->namespaceDecl() != nullptr)\r
139     {\r
140       result.namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx));\r
141     }\r
142   }\r
143   return result;\r
144 }\r
145 Program getProgram(TocParser::ProgContext * ctx, std::shared_ptr<Context> parent)\r
146 {\r
147   Program result;\r
148   result.ctx = std::make_unique<Context>();\r
149   for (auto d : ctx->decl())\r
150   {\r
151     if (d->varDecl() != nullptr)\r
152     {\r
153       result.ctx->variables.push_back(getVariable(d->varDecl()->var()));\r
154     }\r
155     if (d->funcDecl() != nullptr)\r
156     {\r
157       result.functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
158     }\r
159     if (d->structDecl() != nullptr)\r
160     {\r
161       result.structs.push_back(getStruct(d->structDecl(), result.ctx));\r
162     }\r
163     if (d->namespaceDecl() != nullptr)\r
164     {\r
165       result.namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx));\r
166     }\r
167   }\r
168   return result;\r
169 }\r
170 template<typename OpType>\r
171 OpType getOperatorType(const std::string & s, std::string typeStrings[])\r
172 {\r
173   for (int i = 0; i < (int)OpType::COUNT; i++)\r
174   {\r
175     if (typeStrings[i] == s)\r
176     {\r
177       return (OpType)i;\r
178     }\r
179   }\r
180   return OpType::COUNT;\r
181 }\r
182 \r
183 \r
184 \r
185 \r
186 \r
187 \r
188 \r
189 \r
190 \r
191 \r
192 \r
193 \r
194 \r
195 Expr getExpr(TocParser::FuncExprContext * ctx)\r
196 {\r
197   Expr result;\r
198   result.type = ExprType::Func;\r
199   for (auto n : ctx->namespaceSpecifier())\r
200     result._func.namespacePrefixes.push_back(n->typeName()->getText());\r
201   result._func.functionName = ctx->funcName()->NAME()->toString();\r
202   for (auto e : ctx->expr())\r
203     result._func.arguments.push_back(getExpr(e));\r
204   return result;\r
205 }\r
206 Expr getExpr(TocParser::MethodExprContext * ctx)\r
207 {\r
208   Expr result;\r
209   result.type = ExprType::Method;\r
210   result._method.expr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
211   result._method.methodName = ctx->funcName()->NAME()->toString();\r
212   for (int i = 1; i < ctx->expr().size(); i++)\r
213     result._method.arguments.push_back(getExpr(ctx->expr(i)));\r
214   return result;\r
215 }\r
216 Expr getExpr(TocParser::LitExprContext * ctx)\r
217 {\r
218   Expr result;\r
219   result.type = ExprType::Lit;\r
220   if (ctx->literal()->INT_LIT() != nullptr)\r
221   {\r
222     result._lit.type = LitType::Int;\r
223     result._lit._int = atoi(ctx->literal()->INT_LIT()->toString().c_str());\r
224   }\r
225   else if (ctx->literal()->DECIMAL_LIT() != nullptr)\r
226   {\r
227     result._lit.type = LitType::Decimal;\r
228     result._lit._decimal = atof(ctx->literal()->DECIMAL_LIT()->toString().c_str());\r
229   }\r
230   else if (ctx->literal()->StringLit() != nullptr)\r
231   {\r
232     result._lit.type = LitType::String;\r
233     result._lit._string = ctx->literal()->StringLit()->toString();\r
234   }\r
235   else if (ctx->literal()->BOOL_LIT() != nullptr)\r
236   {\r
237     result._lit.type = LitType::Bool;\r
238     result._lit._bool = ctx->literal()->BOOL_LIT()->toString() == "true";\r
239   }\r
240   return result;\r
241 }\r
242 Expr getExpr(TocParser::ParenExprContext * ctx)\r
243 {\r
244   Expr result;\r
245   result.type = ExprType::Paren;\r
246   result._paren.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
247   return result;\r
248 }\r
249 Expr getExpr(TocParser::DotExprContext * ctx)\r
250 {\r
251   Expr result;\r
252   result.type = ExprType::Dot;\r
253   result._dot.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
254   result._dot.identifier = ctx->varName()->getText();\r
255   return result;\r
256 }\r
257 Expr getExpr(TocParser::PrefixOpExprContext * ctx)\r
258 {\r
259   Expr result;\r
260   result.type = ExprType::PrefixOp;\r
261   result._prefixOp.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
262   result._prefixOp.type = getOperatorType<PrefixOperatorType>(\r
263     ctx->prefix_op()->getText(),\r
264     PrefixOperatorTypeStrings);\r
265   return result;\r
266 }\r
267 Expr getExpr(TocParser::PostfixOpExprContext * ctx)\r
268 {\r
269   Expr result;\r
270   result.type = ExprType::PostfixOp;\r
271   result._postfixOp.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
272   result._postfixOp.type = getOperatorType<PostfixOperatorType>(\r
273     ctx->postfix_op()->getText(),\r
274     PostfixOperatorTypeStrings);\r
275   return result;\r
276 }\r
277 Expr getExpr(TocParser::BinaryOpExprContext * ctx)\r
278 {\r
279   Expr result;\r
280   result.type = ExprType::BinaryOp;\r
281   result._binaryOp.lexpr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
282   result._binaryOp.rexpr = std::make_unique<Expr>(getExpr(ctx->expr(1)));\r
283   result._binaryOp.type = getOperatorType<BinaryOperatorType>(\r
284     ctx->binary_op()->getText(),\r
285     BinaryOperatorTypeStrings);\r
286   return result;\r
287 }\r
288 Expr getExpr(TocParser::TernaryOpExprContext * ctx)\r
289 {\r
290   Expr result;\r
291   result.type = ExprType::TernaryOp;\r
292   result._ternaryOp.lexpr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
293   result._ternaryOp.rexprTrue = std::make_unique<Expr>(getExpr(ctx->expr(1)));\r
294   result._ternaryOp.rexprFalse = std::make_unique<Expr>(getExpr(ctx->expr(2)));\r
295   return result;\r
296 }\r
297 Expr getExpr(TocParser::BracketExprContext * ctx)\r
298 {\r
299   Expr result;\r
300   result.type = ExprType::Bracket;\r
301   result._brackets.lexpr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
302   result._brackets.rexpr = std::make_unique<Expr>(getExpr(ctx->expr(1)));\r
303   return result;\r
304 }\r
305 Expr getExpr(TocParser::IdentifierExprContext * ctx)\r
306 {\r
307   Expr result;\r
308   result.type = ExprType::Identifier;\r
309   for (auto n : ctx->namespaceSpecifier())\r
310     result._identifier.namespacePrefixes.push_back(n->typeName()->getText());\r
311   result._identifier.identifier = ctx->varName()->getText();\r
312   return result;\r
313 }\r
314 \r
315 \r
316 \r
317 \r
318 \r
319 \r
320 \r
321 \r
322 \r
323 \r
324 \r
325 Expr getExpr(TocParser::ExprContext * ctx)\r
326 {\r
327   Expr result;\r
328   if (dynamic_cast<TocParser::FuncExprContext *>(ctx) != nullptr)\r
329     result = getExpr(dynamic_cast<TocParser::FuncExprContext *>(ctx));\r
330   if (dynamic_cast<TocParser::MethodExprContext *>(ctx) != nullptr)\r
331     result = getExpr(dynamic_cast<TocParser::MethodExprContext *>(ctx));\r
332   if (dynamic_cast<TocParser::LitExprContext *>(ctx) != nullptr)\r
333     result = getExpr(dynamic_cast<TocParser::LitExprContext *>(ctx));\r
334   if (dynamic_cast<TocParser::ParenExprContext *>(ctx) != nullptr)\r
335     result = getExpr(dynamic_cast<TocParser::ParenExprContext *>(ctx));\r
336   if (dynamic_cast<TocParser::DotExprContext *>(ctx) != nullptr)\r
337     result = getExpr(dynamic_cast<TocParser::DotExprContext *>(ctx));\r
338   if (dynamic_cast<TocParser::PrefixOpExprContext *>(ctx) != nullptr)\r
339     result = getExpr(dynamic_cast<TocParser::PrefixOpExprContext *>(ctx));\r
340   if (dynamic_cast<TocParser::PostfixOpExprContext *>(ctx) != nullptr)\r
341     result = getExpr(dynamic_cast<TocParser::PostfixOpExprContext *>(ctx));\r
342   if (dynamic_cast<TocParser::BinaryOpExprContext *>(ctx) != nullptr)\r
343     result = getExpr(dynamic_cast<TocParser::BinaryOpExprContext *>(ctx));\r
344   if (dynamic_cast<TocParser::TernaryOpExprContext *>(ctx) != nullptr)\r
345     result = getExpr(dynamic_cast<TocParser::TernaryOpExprContext *>(ctx));\r
346   if (dynamic_cast<TocParser::BracketExprContext *>(ctx) != nullptr)\r
347     result = getExpr(dynamic_cast<TocParser::BracketExprContext *>(ctx));\r
348   if (dynamic_cast<TocParser::IdentifierExprContext *>(ctx) != nullptr)\r
349     result = getExpr(dynamic_cast<TocParser::IdentifierExprContext *>(ctx));\r
350   return result;\r
351 }\r
352 Stmt getStmt(TocParser::StmtContext * ctx, std::shared_ptr<Context> parent)\r
353 {\r
354   Stmt result;\r
355   if (ctx->varDecl() != nullptr && ctx->varDecl()->var()->expr() != nullptr)\r
356   {\r
357     result.type = StmtType::Assign;\r
358     result._assign.lexpr.type = ExprType::Identifier;\r
359     result._assign.lexpr._identifier.identifier = ctx->varDecl()->var()->varName()->getText();\r
360     result._assign.rexpr = getExpr(ctx->varDecl()->var()->expr());\r
361   }\r
362   if (ctx->ifStmt() != nullptr)\r
363   {\r
364     result.type = StmtType::If;\r
365     result._if.condition = getExpr(ctx->ifStmt()->expr());\r
366     result._if.body = getBody(ctx->ifStmt()->body(), parent);\r
367     for (auto ei : ctx->ifStmt()->elseIfStmt())\r
368     {\r
369       result._if.elses.emplace_back(\r
370         true,\r
371         std::make_unique<Expr>(getExpr(ei->expr())),\r
372         getBody(ei->body(), parent)\r
373       );\r
374     }\r
375     if (ctx->ifStmt()->elseStmt() != nullptr)\r
376     {\r
377       result._if.elses.emplace_back(\r
378         false,\r
379         nullptr,\r
380         getBody(ctx->ifStmt()->elseStmt()->body(), parent)\r
381       );\r
382     }\r
383   }\r
384   if (ctx->switchStmt() != nullptr)\r
385   {\r
386     result.type = StmtType::Switch;\r
387     result._switch.ident = std::make_unique<Expr>(getExpr(ctx->switchStmt()->expr()));\r
388     for (auto c : ctx->switchStmt()->switchBody()->switchCase())\r
389     {\r
390       result._switch.cases.emplace_back(\r
391         std::make_unique<Expr>(getExpr(c->expr())),\r
392         getBody(c->body(), parent)\r
393       );\r
394     }\r
395   }\r
396   if (ctx->forStmt() != nullptr)\r
397   {\r
398     result.type = StmtType::For;\r
399     result._for.init = std::make_unique<AssignStmt>();\r
400     result._for.init->lexpr.type = ExprType::Identifier;\r
401     result._for.init->lexpr._identifier.identifier = ctx->forStmt()->varInit()->varName()->getText();\r
402     result._for.init->rexpr = getExpr(ctx->forStmt()->varInit()->expr());\r
403     result._for.condition = std::make_unique<Expr>(getExpr(ctx->forStmt()->expr(0)));\r
404     result._for.action = std::make_unique<Expr>(getExpr(ctx->forStmt()->expr(1)));\r
405     result._for.body = getBody(ctx->forStmt()->body(), parent);\r
406   }\r
407   if (ctx->whileStmt() != nullptr)\r
408   {\r
409     result.type = StmtType::While;\r
410     result._while.condition = getExpr(ctx->whileStmt()->expr());\r
411     result._while.body = getBody(ctx->whileStmt()->body(), parent);\r
412   }\r
413   if (ctx->assignStmt() != nullptr)\r
414   {\r
415     result.type = StmtType::Assign;\r
416     result._assign.lexpr = getExpr(ctx->assignStmt()->expr(0));\r
417     result._assign.rexpr = getExpr(ctx->assignStmt()->expr(1));\r
418   }\r
419   if (ctx->returnStmt() != nullptr)\r
420   {\r
421     result.type = StmtType::Return;\r
422     result._return.expr = getExpr(ctx->returnStmt()->expr());\r
423   }\r
424   if (ctx->expr() != nullptr)\r
425   {\r
426     result.type = StmtType::Expr;\r
427     result._expr = getExpr(ctx->expr());\r
428   }\r
429   return result;\r
430 }