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