]> gitweb.ps.run Git - toc/blob - src/repr_get.h
type modifiers, parenthesized expressions, chained access expressions
[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);\r
8 Function            getFunction(TocParser::FuncContext * ctx);\r
9 Struct              getStruct(TocParser::StructDeclContext * ctx);\r
10 Program             getProgram(TocParser::ProgContext * ctx);\r
11 UnaryOperatorType   getUnaryOperatorType(const std::string & s);\r
12 BinaryOperatorType  getBinaryOperatorType(const std::string & s);\r
13 UnaryOperatorExpr   getUnaryOperatorExpr(TocParser::OpExprContext * ctx);\r
14 BinaryOperatorExpr  getBinaryOperatorExpr(TocParser::OpExprContext * ctx);\r
15 TernaryOperatorExpr getTernaryOperatorExpr(TocParser::OpExprContext * ctx);\r
16 Expr                getExpr(TocParser::NonOpExprContext * ctx);\r
17 Expr                getExpr(TocParser::NonAccessExprContext * ctx);\r
18 Expr                getExpr(TocParser::ExprContext * ctx);\r
19 Stmt                getStmt(TocParser::StmtContext * ctx);\r
20 \r
21 Type getType(TocParser::TypeContext * ctx) {\r
22   Type result;\r
23   result.name = ctx->typeName()->NAME()->toString();\r
24   for (auto m : ctx->typeModifier()) {\r
25     bool isPointer = m->getText() == "*";\r
26     bool isStaticArray = m->INT_LIT() != nullptr;\r
27 \r
28     result.modifiers.emplace_back(\r
29       isPointer ? TypeModifierType::Pointer : TypeModifierType::Array,\r
30       isStaticArray,\r
31       isStaticArray ? atoi(m->INT_LIT()->toString().c_str()) : -1\r
32     );\r
33   }\r
34   return result;\r
35 }\r
36 Variable getVariable(TocParser::VarContext * ctx) {\r
37   Variable result;\r
38   result.name = ctx->varName()->NAME()->toString();\r
39   result.type = getType(ctx->type());\r
40   return result;\r
41 }\r
42 Body getBody(TocParser::BodyContext * ctx) {\r
43   Body result;\r
44   for (auto s : ctx->stmt()) {\r
45     if (s->varDecl() != nullptr) {\r
46       result.variables.push_back(getVariable(s->varDecl()->var()));\r
47       if (s->varDecl()->var()->expr() != nullptr)\r
48         result.statements.push_back(getStmt(s));\r
49     }\r
50     else {\r
51       result.statements.push_back(getStmt(s));\r
52     }\r
53   }\r
54   return result;\r
55 }\r
56 Function getFunction(TocParser::FuncContext * ctx) {\r
57   Function result;\r
58   result.name = ctx->funcName()->NAME()->toString();\r
59   result.returnType = getType(ctx->type());\r
60   if (!ctx->parameter()->var().empty()) {\r
61     for (auto p : ctx->parameter()->var())\r
62       result.parameters.push_back(getVariable(p));\r
63   }\r
64   result.body = getBody(ctx->body());\r
65   return result;\r
66 }\r
67 Struct getStruct(TocParser::StructDeclContext * ctx) {\r
68   Struct result;\r
69   result.name = ctx->structName()->NAME()->toString();\r
70   for (auto m : ctx->structMember()) {\r
71     if (m->structVar() != nullptr) {\r
72       result.members.push_back(getVariable(m->structVar()->var()));\r
73     }\r
74     if (m->structMethod() != nullptr) {\r
75       result.methods.push_back(getFunction(m->structMethod()->func()));\r
76     }\r
77   }\r
78   return result;\r
79 }\r
80 Program getProgram(TocParser::ProgContext * ctx) {\r
81   Program result;\r
82   for (auto d : ctx->decl()) {\r
83     if (d->varDecl() != nullptr) {\r
84       result.variables.push_back(getVariable(d->varDecl()->var()));\r
85     }\r
86     if (d->funcDecl() != nullptr) {\r
87       result.functions.push_back(getFunction(d->funcDecl()->func()));\r
88     }\r
89     if (d->structDecl() != nullptr) {\r
90       result.structs.push_back(getStruct(d->structDecl()));\r
91     }\r
92   }\r
93   return result;\r
94 }\r
95 UnaryOperatorType getUnaryOperatorType(const std::string & s) {\r
96   for (int i = 0; i < (int)UnaryOperatorType::COUNT; i++) {\r
97     if (UnaryOperatorTypeStrings[i] == s) {\r
98       return (UnaryOperatorType)i;\r
99     }\r
100   }\r
101   return UnaryOperatorType::COUNT;\r
102 }\r
103 BinaryOperatorType getBinaryOperatorType(const std::string & s) {\r
104   for (int i = 0; i < (int)BinaryOperatorType::COUNT; i++) {\r
105     if (BinaryOperatorTypeStrings[i] == s) {\r
106       return (BinaryOperatorType)i;\r
107     }\r
108   }\r
109   return BinaryOperatorType::COUNT;\r
110 }\r
111 UnaryOperatorExpr getUnaryOperatorExpr(TocParser::OpExprContext * ctx) {\r
112   UnaryOperatorExpr result;\r
113   if (ctx->prefixOp() != nullptr)\r
114     result.expr = std::make_unique<Expr>(getExpr(ctx->prefixOp()->nonOpExpr()));\r
115   else\r
116     result.expr = std::make_unique<Expr>(getExpr(ctx->postfixOp()->nonOpExpr()));\r
117 \r
118   std::string op;\r
119   if (ctx->prefixOp() != nullptr)\r
120     op = ctx->prefixOp()->prefix_op()->getText();\r
121   else\r
122     op = ctx->postfixOp()->postfix_op()->getText();\r
123 \r
124   // TODO: postfix type\r
125 \r
126   result.type = getUnaryOperatorType(op);\r
127 \r
128   return result;\r
129 }\r
130 BinaryOperatorExpr getBinaryOperatorExpr(TocParser::OpExprContext * ctx) {\r
131   BinaryOperatorExpr result;\r
132   result.lexpr = std::make_unique<Expr>(getExpr(ctx->binaryOp()->nonOpExpr(0)));\r
133   result.rexpr = std::make_unique<Expr>(getExpr(ctx->binaryOp()->nonOpExpr(1)));\r
134   \r
135   std::string op = ctx->binaryOp()->binary_op(0)->getText();\r
136 \r
137   result.type = getBinaryOperatorType(op);\r
138 \r
139   return result;\r
140 }\r
141 TernaryOperatorExpr getTernaryOperatorExpr(TocParser::OpExprContext * ctx) {\r
142   TernaryOperatorExpr result;\r
143   result.lexpr = std::make_unique<Expr>(getExpr(ctx->ternaryOp()->nonOpExpr()));\r
144   result.rexprTrue = std::make_unique<Expr>(getExpr(ctx->ternaryOp()->expr(0)));\r
145   result.rexprFalse = std::make_unique<Expr>(getExpr(ctx->ternaryOp()->expr(1)));\r
146   return result;\r
147 }\r
148 Expr getExpr(TocParser::NonOpExprContext * ctx) {\r
149   Expr result;\r
150   result.parenthesized = false;\r
151   if (ctx->funcExpr() != nullptr) {\r
152     result.type = ExprType::Func;\r
153     result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString();\r
154     for (auto e : ctx->funcExpr()->expr())\r
155       result._func.arguments.push_back(getExpr(e));\r
156   }\r
157   if (ctx->litExpr() != nullptr) {\r
158     result.type = ExprType::Lit;\r
159     if (ctx->litExpr()->INT_LIT() != nullptr) {\r
160       result._lit.type = LitType::Int;\r
161       result._lit._int = atoi(ctx->litExpr()->INT_LIT()->toString().c_str());\r
162     }\r
163     else if (ctx->litExpr()->DECIMAL_LIT() != nullptr) {\r
164       result._lit.type = LitType::Decimal;\r
165       result._lit._decimal = atof(ctx->litExpr()->DECIMAL_LIT()->toString().c_str());\r
166     }\r
167     else if (ctx->litExpr()->STRING_LIT() != nullptr) {\r
168       result._lit.type = LitType::String;\r
169       result._lit._string = ctx->litExpr()->STRING_LIT()->toString();\r
170     }\r
171     else if (ctx->litExpr()->BOOL_LIT() != nullptr) {\r
172       result._lit.type = LitType::Bool;\r
173       result._lit._bool = ctx->litExpr()->BOOL_LIT()->toString() == "true";\r
174     }\r
175   }\r
176   if (ctx->identifierExpr() != nullptr) {\r
177     result.type = ExprType::Identifier;\r
178     result._identifier.name = ctx->identifierExpr()->varName()->NAME()->toString();\r
179   }\r
180   if (ctx->parenExpr() != nullptr) {\r
181     result = getExpr(ctx->parenExpr()->expr());\r
182     result.parenthesized = true;\r
183   }\r
184   if (ctx->accessExpr() != nullptr) {\r
185     auto firstSub = ctx->accessExpr()->accessSubExpr(0);\r
186     if (firstSub->accessMember() != nullptr) {\r
187       result.type = ExprType::Dot;\r
188       result._dot.expr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
189       result._dot.ident.name = firstSub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
190     }\r
191     else {\r
192       result.type = ExprType::Brackets;\r
193       result._brackets.lexpr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
194       result._brackets.rexpr = std::make_unique<Expr>(getExpr(firstSub->accessBrackets()->expr()));\r
195     }\r
196     for (int i = 1; i < ctx->accessExpr()->accessSubExpr().size(); i++) {\r
197       Expr tmp = result;\r
198       auto sub = ctx->accessExpr()->accessSubExpr(i);\r
199       if (sub->accessMember() != nullptr) {\r
200         result.type = ExprType::Dot;\r
201         result._dot.expr = std::make_unique<Expr>(tmp);\r
202         result._dot.ident.name = sub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
203       }\r
204       else {\r
205         result.type = ExprType::Brackets;\r
206         result._brackets.lexpr = std::make_unique<Expr>(tmp);\r
207         result._brackets.rexpr = std::make_unique<Expr>(getExpr(sub->accessBrackets()->expr()));\r
208       }\r
209     }\r
210   }\r
211   return result;\r
212 }\r
213 Expr getExpr(TocParser::NonAccessExprContext * ctx) {\r
214   Expr result;\r
215   result.parenthesized = false;\r
216   if (ctx->funcExpr() != nullptr) {\r
217     result.type = ExprType::Func;\r
218     result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString();\r
219     for (auto e : ctx->funcExpr()->expr())\r
220       result._func.arguments.push_back(getExpr(e));\r
221   }\r
222   if (ctx->identifierExpr() != nullptr) {\r
223     result.type = ExprType::Identifier;\r
224     result._identifier.name = ctx->identifierExpr()->varName()->NAME()->toString();\r
225   }\r
226   if (ctx->parenExpr() != nullptr) {\r
227     result = getExpr(ctx->parenExpr()->expr());\r
228     result.parenthesized = true;\r
229   }\r
230   return result;\r
231 }\r
232 Expr getExpr(TocParser::ExprContext * ctx) {\r
233   Expr result;\r
234   result.parenthesized = false;\r
235   if (ctx->funcExpr() != nullptr) {\r
236     result.type = ExprType::Func;\r
237     result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString();\r
238     for (auto e : ctx->funcExpr()->expr())\r
239       result._func.arguments.push_back(getExpr(e));\r
240   }\r
241   if (ctx->litExpr() != nullptr) {\r
242     result.type = ExprType::Lit;\r
243     if (ctx->litExpr()->INT_LIT() != nullptr) {\r
244       result._lit.type = LitType::Int;\r
245       result._lit._int = atoi(ctx->litExpr()->INT_LIT()->toString().c_str());\r
246     }\r
247     else if (ctx->litExpr()->DECIMAL_LIT() != nullptr) {\r
248       result._lit.type = LitType::Decimal;\r
249       result._lit._decimal = atof(ctx->litExpr()->DECIMAL_LIT()->toString().c_str());\r
250     }\r
251     else if (ctx->litExpr()->STRING_LIT() != nullptr) {\r
252       result._lit.type = LitType::String;\r
253       result._lit._string = ctx->litExpr()->STRING_LIT()->toString();\r
254     }\r
255     else if (ctx->litExpr()->BOOL_LIT() != nullptr) {\r
256       result._lit.type = LitType::Bool;\r
257       result._lit._bool = ctx->litExpr()->BOOL_LIT()->toString() == "true";\r
258     }\r
259   }\r
260   if (ctx->identifierExpr() != nullptr) {\r
261     result.type = ExprType::Identifier;\r
262     result._identifier.name = ctx->identifierExpr()->varName()->NAME()->toString();\r
263   }\r
264   if (ctx->parenExpr() != nullptr) {\r
265     result = getExpr(ctx->parenExpr()->expr());\r
266     result.parenthesized = true;\r
267   }\r
268   if (ctx->accessExpr() != nullptr) {\r
269     auto firstSub = ctx->accessExpr()->accessSubExpr(0);\r
270     if (firstSub->accessMember() != nullptr) {\r
271       result.type = ExprType::Dot;\r
272       result._dot.expr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
273       result._dot.ident.name = firstSub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
274     }\r
275     else {\r
276       result.type = ExprType::Brackets;\r
277       result._brackets.lexpr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
278       result._brackets.rexpr = std::make_unique<Expr>(getExpr(firstSub->accessBrackets()->expr()));\r
279     }\r
280     for (int i = 1; i < ctx->accessExpr()->accessSubExpr().size(); i++) {\r
281       Expr tmp = result;\r
282       auto sub = ctx->accessExpr()->accessSubExpr(i);\r
283       if (sub->accessMember() != nullptr) {\r
284         result.type = ExprType::Dot;\r
285         result._dot.expr = std::make_unique<Expr>(tmp);\r
286         result._dot.ident.name = sub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
287       }\r
288       else {\r
289         result.type = ExprType::Brackets;\r
290         result._brackets.lexpr = std::make_unique<Expr>(tmp);\r
291         result._brackets.rexpr = std::make_unique<Expr>(getExpr(sub->accessBrackets()->expr()));\r
292       }\r
293     }\r
294   }\r
295   if (ctx->opExpr() != nullptr) {\r
296     if (ctx->opExpr()->prefixOp() != nullptr || ctx->opExpr()->postfixOp() != nullptr) {\r
297       result.type = ExprType::UnaryOperator;\r
298       result._unaryOperator = getUnaryOperatorExpr(ctx->opExpr());\r
299     }\r
300     else if (ctx->opExpr()->binaryOp() != nullptr) {\r
301       result.type = ExprType::BinaryOperator;\r
302       result._binaryOperator = getBinaryOperatorExpr(ctx->opExpr());\r
303       for (int i = 1; i < ctx->opExpr()->binaryOp()->binary_op().size(); i++) {\r
304         Expr tmp = result;\r
305         result._binaryOperator.lexpr = std::make_unique<Expr>(tmp);\r
306         result._binaryOperator.type = getBinaryOperatorType(ctx->opExpr()->binaryOp()->binary_op(i)->getText());\r
307         result._binaryOperator.rexpr = std::make_unique<Expr>(getExpr(ctx->opExpr()->binaryOp()->nonOpExpr(i+1)));\r
308       }\r
309     }\r
310     else if (ctx->opExpr()->ternaryOp() != nullptr) {\r
311       result.type = ExprType::TernaryOperator;\r
312       result._ternaryOperator = getTernaryOperatorExpr(ctx->opExpr());\r
313     }\r
314   }\r
315   return result;\r
316 }\r
317 Stmt getStmt(TocParser::StmtContext * ctx) {\r
318   Stmt result;\r
319   if (ctx->varDecl() != nullptr && ctx->varDecl()->var()->expr() != nullptr) {\r
320     result.type = StmtType::Assign;\r
321     result._assign.name = ctx->varDecl()->var()->varName()->NAME()->toString();\r
322     result._assign.expr = getExpr(ctx->varDecl()->var()->expr());\r
323   }\r
324   if (ctx->ifStmt() != nullptr) {\r
325     result.type = StmtType::If;\r
326     result._if.condition = getExpr(ctx->ifStmt()->expr());\r
327     result._if.body = getBody(ctx->ifStmt()->body());\r
328     for (auto ei : ctx->ifStmt()->elseIfStmt()) {\r
329       result._if.elses.emplace_back(\r
330         true,\r
331         std::make_unique<Expr>(getExpr(ei->expr())),\r
332         getBody(ei->body())\r
333       );\r
334     }\r
335     if (ctx->ifStmt()->elseStmt() != nullptr) {\r
336       result._if.elses.emplace_back(\r
337         false,\r
338         nullptr,\r
339         getBody(ctx->ifStmt()->elseStmt()->body())\r
340       );\r
341     }\r
342   }\r
343   if (ctx->switchStmt() != nullptr) {\r
344     result.type = StmtType::Switch;\r
345     result._switch.ident.name = ctx->switchStmt()->identifierExpr()->varName()->NAME()->toString();\r
346     for (auto c : ctx->switchStmt()->switchBody()->switchCase()) {\r
347       result._switch.cases.emplace_back(\r
348         std::make_unique<Expr>(getExpr(c->expr())),\r
349         getBody(c->body())\r
350       );\r
351     }\r
352   }\r
353   if (ctx->forStmt() != nullptr) {\r
354     result.type = StmtType::For;\r
355     if (ctx->forStmt()->varInit() != nullptr) {\r
356       result._for.varName = ctx->forStmt()->varInit()->varName()->NAME()->toString();\r
357       result._for.initValue = std::make_unique<Expr>(getExpr(ctx->forStmt()->varInit()->expr()));\r
358     }\r
359     else {\r
360       result._for.varName = ctx->forStmt()->assignStmt()->identifierExpr()->varName()->NAME()->toString();\r
361       result._for.initValue = std::make_unique<Expr>(getExpr(ctx->forStmt()->assignStmt()->expr()));\r
362     }\r
363     result._for.condition = std::make_unique<Expr>(getExpr(ctx->forStmt()->expr(0)));\r
364     result._for.action = std::make_unique<Expr>(getExpr(ctx->forStmt()->expr(1)));\r
365     result._for.body = getBody(ctx->forStmt()->body());\r
366   }\r
367   if (ctx->whileStmt() != nullptr) {\r
368     result.type = StmtType::While;\r
369     result._while.condition = getExpr(ctx->whileStmt()->expr());\r
370     result._while.body = getBody(ctx->whileStmt()->body());\r
371   }\r
372   if (ctx->assignStmt() != nullptr) {\r
373     result.type = StmtType::Assign;\r
374     result._assign.name = ctx->assignStmt()->identifierExpr()->varName()->NAME()->toString();\r
375     result._assign.expr = getExpr(ctx->assignStmt()->expr());\r
376   }\r
377   if (ctx->returnStmt() != nullptr) {\r
378     result.type = StmtType::Return;\r
379     result._return.expr = getExpr(ctx->returnStmt()->expr());\r
380   }\r
381   if (ctx->expr() != nullptr) {\r
382     result.type = StmtType::Expr;\r
383     result._expr = getExpr(ctx->expr());\r
384   }\r
385   return result;\r
386 }