]> gitweb.ps.run Git - toc/blobdiff - src/repr_get.h
comments
[toc] / src / repr_get.h
index 54aea6fafa012897e1793a4ac57256bd89f590b0..373b366ae3849da99bb4c7a1441986bf65c34efd 100644 (file)
@@ -2,13 +2,15 @@
 \r
 #include "repr.h"\r
 \r
+// Transform ANTLR-generated types to corresponding IR types recursively\r
+\r
 Type                getType(TocParser::TypeContext * ctx);\r
 Variable            getVariable(TocParser::VarContext * ctx);\r
-Body                getBody(TocParser::BodyContext * ctx);\r
-Function            getFunction(TocParser::FuncContext * ctx);\r
-Struct              getStruct(TocParser::StructDeclContext * ctx);\r
-Namespace           getNamespace(TocParser::NamespaceDeclContext * ctx);\r
-Program             getProgram(TocParser::ProgContext * ctx);\r
+Body                getBody(TocParser::BodyContext * ctx, std::shared_ptr<Context> parent);\r
+Function            getFunction(TocParser::FuncContext * ctx, std::shared_ptr<Context> parent);\r
+Struct              getStruct(TocParser::StructDeclContext * ctx, std::shared_ptr<Context> parent);\r
+Namespace           getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptr<Context> parent);\r
+Program             getProgram(TocParser::ProgContext * ctx, std::shared_ptr<Context> parent);\r
 \r
 \r
 Expr                getExpr(TocParser::FuncExprContext * ctx);\r
@@ -24,7 +26,12 @@ Expr                getExpr(TocParser::BracketExprContext * ctx);
 Expr                getExpr(TocParser::IdentifierExprContext * ctx);\r
 Expr                getExpr(TocParser::ExprContext * ctx);\r
 \r
-Stmt                getStmt(TocParser::StmtContext * ctx);\r
+Stmt                getStmt(TocParser::StmtContext * ctx, std::shared_ptr<Context> parent);\r
+\r
+// all of these functions get the relevant information\r
+// from the parse tree and call each other for sub expressions\r
+// the getVariable is called for variable declarations and parameter definitions\r
+// for example, because they have the same rule in the grammar file\r
 \r
 Type getType(TocParser::TypeContext * ctx)\r
 {\r
@@ -43,6 +50,13 @@ Type getType(TocParser::TypeContext * ctx)
       isStaticArray ? atoi(m->INT_LIT()->toString().c_str()) : -1\r
     );\r
   }\r
+  if (ctx->genericInstantiation() != nullptr)\r
+  {\r
+    for (auto g : ctx->genericInstantiation()->type())\r
+    {\r
+      result.genericInstantiation.push_back(getType(g));\r
+    }\r
+  }\r
   return result;\r
 }\r
 Variable getVariable(TocParser::VarContext * ctx)\r
@@ -52,41 +66,68 @@ Variable getVariable(TocParser::VarContext * ctx)
   result.type = getType(ctx->type());\r
   return result;\r
 }\r
-Body getBody(TocParser::BodyContext * ctx)\r
+Body getBody(TocParser::BodyContext * ctx, std::shared_ptr<Context> parent)\r
 {\r
   Body result;\r
+  result.ctx = std::make_unique<Context>();\r
+  result.ctx->parent = parent;\r
   for (auto s : ctx->stmt())\r
   {\r
     if (s->varDecl() != nullptr)\r
     {\r
-      result.variables.push_back(getVariable(s->varDecl()->var()));\r
+      result.ctx->variables.push_back(getVariable(s->varDecl()->var()));\r
       if (s->varDecl()->var()->expr() != nullptr)\r
-        result.statements.push_back(getStmt(s));\r
+        result.statements.push_back(getStmt(s, result.ctx));\r
     }\r
     else\r
     {\r
-      result.statements.push_back(getStmt(s));\r
+      result.statements.push_back(getStmt(s, result.ctx));\r
     }\r
   }\r
   return result;\r
 }\r
-Function getFunction(TocParser::FuncContext * ctx)\r
+Function getFunction(TocParser::FuncContext * ctx, std::shared_ptr<Context> parent)\r
 {\r
   Function result;\r
   result.name = ctx->funcName()->NAME()->toString();\r
   result.returnType = getType(ctx->type());\r
+  if (ctx->genericDecl() != nullptr)\r
+  {\r
+    for (auto t : ctx->genericDecl()->typeName())\r
+    {\r
+      result.genericTypeNames.push_back(t->getText());\r
+    }\r
+  }\r
+\r
   if (!ctx->parameter()->var().empty())\r
   {\r
     for (auto p : ctx->parameter()->var())\r
       result.parameters.push_back(getVariable(p));\r
   }\r
-  result.body = getBody(ctx->body());\r
+\r
+  if (ctx->body() != nullptr)\r
+  {\r
+    result.body = getBody(ctx->body(), parent);\r
+    result.defined = true;\r
+  }\r
+  else\r
+  {\r
+    result.defined = false;\r
+  }\r
   return result;\r
 }\r
-Struct getStruct(TocParser::StructDeclContext * ctx)\r
+Struct getStruct(TocParser::StructDeclContext * ctx, std::shared_ptr<Context> parent)\r
 {\r
   Struct result;\r
   result.name = ctx->structName()->NAME()->toString();\r
+  if (ctx->genericDecl() != nullptr)\r
+  {\r
+    for (auto t : ctx->genericDecl()->typeName())\r
+    {\r
+      result.genericTypeNames.push_back(t->getText());\r
+    }\r
+  }\r
+\r
   for (auto m : ctx->structMember())\r
   {\r
     if (m->structVar() != nullptr)\r
@@ -99,58 +140,61 @@ Struct getStruct(TocParser::StructDeclContext * ctx)
     if (m->structMethod() != nullptr)\r
     {\r
       result.methods.push_back({\r
-        getFunction(m->structMethod()->func()),\r
+        getFunction(m->structMethod()->func(), parent),\r
         m->privateDecl() != nullptr\r
       });\r
     }\r
   }\r
   return result;\r
 }\r
-Namespace getNamespace(TocParser::NamespaceDeclContext * ctx)\r
+Namespace getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptr<Context> parent)\r
 {\r
   Namespace result;\r
+  result.ctx = std::make_unique<Context>();\r
   result.name = ctx->typeName()->getText();\r
+  result.ctx->name = result.name;\r
   for (auto d : ctx->decl())\r
   {\r
     if (d->varDecl() != nullptr)\r
     {\r
-      result.variables.push_back(getVariable(d->varDecl()->var()));\r
+      result.ctx->variables.push_back(getVariable(d->varDecl()->var()));\r
     }\r
     if (d->funcDecl() != nullptr)\r
     {\r
-      result.functions.push_back(getFunction(d->funcDecl()->func()));\r
+      result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
     }\r
     if (d->structDecl() != nullptr)\r
     {\r
-      result.structs.push_back(getStruct(d->structDecl()));\r
+      result.ctx->structs.push_back(getStruct(d->structDecl(), result.ctx));\r
     }\r
     if (d->namespaceDecl() != nullptr)\r
     {\r
-      result.namespaces.push_back(getNamespace(d->namespaceDecl()));\r
+      result.ctx->namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx));\r
     }\r
   }\r
   return result;\r
 }\r
-Program getProgram(TocParser::ProgContext * ctx)\r
+Program getProgram(TocParser::ProgContext * ctx, std::shared_ptr<Context> parent)\r
 {\r
   Program result;\r
+  result.ctx = std::make_unique<Context>();\r
   for (auto d : ctx->decl())\r
   {\r
     if (d->varDecl() != nullptr)\r
     {\r
-      result.variables.push_back(getVariable(d->varDecl()->var()));\r
+      result.ctx->variables.push_back(getVariable(d->varDecl()->var()));\r
     }\r
     if (d->funcDecl() != nullptr)\r
     {\r
-      result.functions.push_back(getFunction(d->funcDecl()->func()));\r
+      result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
     }\r
     if (d->structDecl() != nullptr)\r
     {\r
-      result.structs.push_back(getStruct(d->structDecl()));\r
+      result.ctx->structs.push_back(getStruct(d->structDecl(), result.ctx));\r
     }\r
     if (d->namespaceDecl() != nullptr)\r
     {\r
-      result.namespaces.push_back(getNamespace(d->namespaceDecl()));\r
+      result.ctx->namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx));\r
     }\r
   }\r
   return result;\r
@@ -179,7 +223,11 @@ OpType getOperatorType(const std::string & s, std::string typeStrings[])
 \r
 \r
 \r
-\r
+// Expressions are somewhat of an exception, because some of their\r
+// grammar rules are recursive, so they have to be defined\r
+// in a single rule using Labels (https://github.com/antlr/antlr4/blob/master/doc/parser-rules.md#alternative-labels)\r
+// Because this results in a polymorphic type, getExpr for the base expression type\r
+// is always called and from there the polymorphic type is determined at runtime\r
 Expr getExpr(TocParser::FuncExprContext * ctx)\r
 {\r
   Expr result;\r
@@ -187,6 +235,13 @@ Expr getExpr(TocParser::FuncExprContext * ctx)
   for (auto n : ctx->namespaceSpecifier())\r
     result._func.namespacePrefixes.push_back(n->typeName()->getText());\r
   result._func.functionName = ctx->funcName()->NAME()->toString();\r
+  if (ctx->genericInstantiation() != nullptr)\r
+  {\r
+    for (auto g : ctx->genericInstantiation()->type())\r
+    {\r
+      result._func.genericInstantiation.push_back(getType(g));\r
+    }\r
+  }\r
   for (auto e : ctx->expr())\r
     result._func.arguments.push_back(getExpr(e));\r
   return result;\r
@@ -197,6 +252,13 @@ Expr getExpr(TocParser::MethodExprContext * ctx)
   result.type = ExprType::Method;\r
   result._method.expr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
   result._method.methodName = ctx->funcName()->NAME()->toString();\r
+  if (ctx->genericInstantiation() != nullptr)\r
+  {\r
+    for (auto g : ctx->genericInstantiation()->type())\r
+    {\r
+      result._method.genericInstantiation.push_back(getType(g));\r
+    }\r
+  }\r
   for (int i = 1; i < ctx->expr().size(); i++)\r
     result._method.arguments.push_back(getExpr(ctx->expr(i)));\r
   return result;\r
@@ -215,10 +277,10 @@ Expr getExpr(TocParser::LitExprContext * ctx)
     result._lit.type = LitType::Decimal;\r
     result._lit._decimal = atof(ctx->literal()->DECIMAL_LIT()->toString().c_str());\r
   }\r
-  else if (ctx->literal()->STRING_LIT() != nullptr)\r
+  else if (ctx->literal()->StringLit() != nullptr)\r
   {\r
     result._lit.type = LitType::String;\r
-    result._lit._string = ctx->literal()->STRING_LIT()->toString();\r
+    result._lit._string = ctx->literal()->StringLit()->toString();\r
   }\r
   else if (ctx->literal()->BOOL_LIT() != nullptr)\r
   {\r
@@ -240,6 +302,7 @@ Expr getExpr(TocParser::DotExprContext * ctx)
   result.type = ExprType::Dot;\r
   result._dot.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
   result._dot.identifier = ctx->varName()->getText();\r
+  result._dot.isPointer = ctx->arrow() != nullptr;\r
   return result;\r
 }\r
 Expr getExpr(TocParser::PrefixOpExprContext * ctx)\r
@@ -309,7 +372,9 @@ Expr getExpr(TocParser::IdentifierExprContext * ctx)
 \r
 \r
 \r
-\r
+// this is always called for Expression rules\r
+// attempt dynamic_cast at runtime and call corresponding\r
+// function\r
 Expr getExpr(TocParser::ExprContext * ctx)\r
 {\r
   Expr result;\r
@@ -337,7 +402,7 @@ Expr getExpr(TocParser::ExprContext * ctx)
     result = getExpr(dynamic_cast<TocParser::IdentifierExprContext *>(ctx));\r
   return result;\r
 }\r
-Stmt getStmt(TocParser::StmtContext * ctx)\r
+Stmt getStmt(TocParser::StmtContext * ctx, std::shared_ptr<Context> parent)\r
 {\r
   Stmt result;\r
   if (ctx->varDecl() != nullptr && ctx->varDecl()->var()->expr() != nullptr)\r
@@ -351,13 +416,13 @@ Stmt getStmt(TocParser::StmtContext * ctx)
   {\r
     result.type = StmtType::If;\r
     result._if.condition = getExpr(ctx->ifStmt()->expr());\r
-    result._if.body = getBody(ctx->ifStmt()->body());\r
+    result._if.body = getBody(ctx->ifStmt()->body(), parent);\r
     for (auto ei : ctx->ifStmt()->elseIfStmt())\r
     {\r
       result._if.elses.emplace_back(\r
         true,\r
         std::make_unique<Expr>(getExpr(ei->expr())),\r
-        getBody(ei->body())\r
+        getBody(ei->body(), parent)\r
       );\r
     }\r
     if (ctx->ifStmt()->elseStmt() != nullptr)\r
@@ -365,7 +430,7 @@ Stmt getStmt(TocParser::StmtContext * ctx)
       result._if.elses.emplace_back(\r
         false,\r
         nullptr,\r
-        getBody(ctx->ifStmt()->elseStmt()->body())\r
+        getBody(ctx->ifStmt()->elseStmt()->body(), parent)\r
       );\r
     }\r
   }\r
@@ -377,7 +442,7 @@ Stmt getStmt(TocParser::StmtContext * ctx)
     {\r
       result._switch.cases.emplace_back(\r
         std::make_unique<Expr>(getExpr(c->expr())),\r
-        getBody(c->body())\r
+        getBody(c->body(), parent)\r
       );\r
     }\r
   }\r
@@ -390,13 +455,13 @@ Stmt getStmt(TocParser::StmtContext * ctx)
     result._for.init->rexpr = getExpr(ctx->forStmt()->varInit()->expr());\r
     result._for.condition = std::make_unique<Expr>(getExpr(ctx->forStmt()->expr(0)));\r
     result._for.action = std::make_unique<Expr>(getExpr(ctx->forStmt()->expr(1)));\r
-    result._for.body = getBody(ctx->forStmt()->body());\r
+    result._for.body = getBody(ctx->forStmt()->body(), parent);\r
   }\r
   if (ctx->whileStmt() != nullptr)\r
   {\r
     result.type = StmtType::While;\r
     result._while.condition = getExpr(ctx->whileStmt()->expr());\r
-    result._while.body = getBody(ctx->whileStmt()->body());\r
+    result._while.body = getBody(ctx->whileStmt()->body(), parent);\r
   }\r
   if (ctx->assignStmt() != nullptr)\r
   {\r