]> gitweb.ps.run Git - toc/blobdiff - src/repr_get.h
structs and functions in ctx
[toc] / src / repr_get.h
index 70ae3b1c2a2fe77bfca563d4160a9e45ec4b6e11..7436dde1e553874a206590e8a9d222e681b86379 100644 (file)
@@ -4,24 +4,36 @@
 \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
-Program             getProgram(TocParser::ProgContext * ctx);\r
-UnaryOperatorType   getUnaryOperatorType(const std::string & s);\r
-BinaryOperatorType  getBinaryOperatorType(const std::string & s);\r
-UnaryOperatorExpr   getUnaryOperatorExpr(TocParser::OpExprContext * ctx);\r
-BinaryOperatorExpr  getBinaryOperatorExpr(TocParser::OpExprContext * ctx);\r
-TernaryOperatorExpr getTernaryOperatorExpr(TocParser::OpExprContext * ctx);\r
-Expr                getExpr(TocParser::NonOpExprContext * ctx);\r
-Expr                getExpr(TocParser::NonAccessExprContext * 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
+Expr                getExpr(TocParser::MethodExprContext * ctx);\r
+Expr                getExpr(TocParser::LitExprContext * ctx);\r
+Expr                getExpr(TocParser::ParenExprContext * ctx);\r
+Expr                getExpr(TocParser::DotExprContext * ctx);\r
+Expr                getExpr(TocParser::PrefixOpExprContext * ctx);\r
+Expr                getExpr(TocParser::PostfixOpExprContext * ctx);\r
+Expr                getExpr(TocParser::BinaryOpExprContext * ctx);\r
+Expr                getExpr(TocParser::TernaryOpExprContext * ctx);\r
+Expr                getExpr(TocParser::BracketExprContext * ctx);\r
+Expr                getExpr(TocParser::IdentifierExprContext * ctx);\r
 Expr                getExpr(TocParser::ExprContext * ctx);\r
-Stmt                getStmt(TocParser::StmtContext * ctx);\r
 \r
-Type getType(TocParser::TypeContext * ctx) {\r
+Stmt                getStmt(TocParser::StmtContext * ctx, std::shared_ptr<Context> parent);\r
+\r
+Type getType(TocParser::TypeContext * ctx)\r
+{\r
   Type result;\r
+  for (auto n : ctx->namespaceSpecifier())\r
+    result.namespacePrefixes.push_back(n->typeName()->getText());\r
   result.name = ctx->typeName()->NAME()->toString();\r
-  for (auto m : ctx->typeModifier()) {\r
+  for (auto m : ctx->typeModifier())\r
+  {\r
     bool isPointer = m->getText() == "*";\r
     bool isStaticArray = m->INT_LIT() != nullptr;\r
 \r
@@ -31,354 +43,425 @@ 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
+Variable getVariable(TocParser::VarContext * ctx)\r
+{\r
   Variable result;\r
   result.name = ctx->varName()->NAME()->toString();\r
   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
-  for (auto s : ctx->stmt()) {\r
-    if (s->varDecl() != nullptr) {\r
-      result.variables.push_back(getVariable(s->varDecl()->var()));\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.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
-      result.statements.push_back(getStmt(s));\r
+    else\r
+    {\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->parameter()->var().empty()) {\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
-  for (auto m : ctx->structMember()) {\r
-    if (m->structVar() != nullptr) {\r
-      result.members.push_back(getVariable(m->structVar()->var()));\r
+  if (ctx->genericDecl() != nullptr)\r
+  {\r
+    for (auto t : ctx->genericDecl()->typeName())\r
+    {\r
+      result.genericTypeNames.push_back(t->getText());\r
     }\r
-    if (m->structMethod() != nullptr) {\r
-      result.methods.push_back(getFunction(m->structMethod()->func()));\r
+  }\r
+\r
+  for (auto m : ctx->structMember())\r
+  {\r
+    if (m->structVar() != nullptr)\r
+    {\r
+      result.members.push_back({\r
+        getVariable(m->structVar()->var()),\r
+        m->privateDecl() != nullptr\r
+      });\r
+    }\r
+    if (m->structMethod() != nullptr)\r
+    {\r
+      result.methods.push_back({\r
+        getFunction(m->structMethod()->func(), parent),\r
+        m->privateDecl() != nullptr\r
+      });\r
     }\r
   }\r
   return result;\r
 }\r
-Program getProgram(TocParser::ProgContext * ctx) {\r
-  Program result;\r
-  for (auto d : ctx->decl()) {\r
-    if (d->varDecl() != nullptr) {\r
-      result.variables.push_back(getVariable(d->varDecl()->var()));\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
+  for (auto d : ctx->decl())\r
+  {\r
+    if (d->varDecl() != nullptr)\r
+    {\r
+      result.ctx->variables.push_back(getVariable(d->varDecl()->var()));\r
     }\r
-    if (d->funcDecl() != nullptr) {\r
-      result.functions.push_back(getFunction(d->funcDecl()->func()));\r
+    if (d->funcDecl() != nullptr)\r
+    {\r
+      result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
     }\r
-    if (d->structDecl() != nullptr) {\r
-      result.structs.push_back(getStruct(d->structDecl()));\r
+    if (d->structDecl() != nullptr)\r
+    {\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(), result.ctx));\r
     }\r
   }\r
   return result;\r
 }\r
-UnaryOperatorType getUnaryOperatorType(const std::string & s) {\r
-  for (int i = 0; i < (int)UnaryOperatorType::COUNT; i++) {\r
-    if (UnaryOperatorTypeStrings[i] == s) {\r
-      return (UnaryOperatorType)i;\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.ctx->variables.push_back(getVariable(d->varDecl()->var()));\r
+    }\r
+    if (d->funcDecl() != nullptr)\r
+    {\r
+      result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
+    }\r
+    if (d->structDecl() != nullptr)\r
+    {\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(), result.ctx));\r
     }\r
   }\r
-  return UnaryOperatorType::COUNT;\r
+  return result;\r
 }\r
-BinaryOperatorType getBinaryOperatorType(const std::string & s) {\r
-  for (int i = 0; i < (int)BinaryOperatorType::COUNT; i++) {\r
-    if (BinaryOperatorTypeStrings[i] == s) {\r
-      return (BinaryOperatorType)i;\r
+template<typename OpType>\r
+OpType getOperatorType(const std::string & s, std::string typeStrings[])\r
+{\r
+  for (int i = 0; i < (int)OpType::COUNT; i++)\r
+  {\r
+    if (typeStrings[i] == s)\r
+    {\r
+      return (OpType)i;\r
     }\r
   }\r
-  return BinaryOperatorType::COUNT;\r
+  return OpType::COUNT;\r
 }\r
-UnaryOperatorExpr getUnaryOperatorExpr(TocParser::OpExprContext * ctx) {\r
-  UnaryOperatorExpr result;\r
-  if (ctx->prefixOp() != nullptr)\r
-    result.expr = std::make_unique<Expr>(getExpr(ctx->prefixOp()->nonOpExpr()));\r
-  else\r
-    result.expr = std::make_unique<Expr>(getExpr(ctx->postfixOp()->nonOpExpr()));\r
 \r
-  std::string op;\r
-  if (ctx->prefixOp() != nullptr)\r
-    op = ctx->prefixOp()->prefix_op()->getText();\r
-  else\r
-    op = ctx->postfixOp()->postfix_op()->getText();\r
 \r
-  // TODO: postfix type\r
 \r
-  result.type = getUnaryOperatorType(op);\r
 \r
-  return result;\r
-}\r
-BinaryOperatorExpr getBinaryOperatorExpr(TocParser::OpExprContext * ctx) {\r
-  BinaryOperatorExpr result;\r
-  result.lexpr = std::make_unique<Expr>(getExpr(ctx->binaryOp()->nonOpExpr(0)));\r
-  result.rexpr = std::make_unique<Expr>(getExpr(ctx->binaryOp()->nonOpExpr(1)));\r
-  \r
-  std::string op = ctx->binaryOp()->binary_op(0)->getText();\r
 \r
-  result.type = getBinaryOperatorType(op);\r
 \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+Expr getExpr(TocParser::FuncExprContext * ctx)\r
+{\r
+  Expr result;\r
+  result.type = ExprType::Func;\r
+  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
 }\r
-TernaryOperatorExpr getTernaryOperatorExpr(TocParser::OpExprContext * ctx) {\r
-  TernaryOperatorExpr result;\r
-  result.lexpr = std::make_unique<Expr>(getExpr(ctx->ternaryOp()->nonOpExpr()));\r
-  result.rexprTrue = std::make_unique<Expr>(getExpr(ctx->ternaryOp()->expr(0)));\r
-  result.rexprFalse = std::make_unique<Expr>(getExpr(ctx->ternaryOp()->expr(1)));\r
+Expr getExpr(TocParser::MethodExprContext * ctx)\r
+{\r
+  Expr result;\r
+  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
 }\r
-Expr getExpr(TocParser::NonOpExprContext * ctx) {\r
+Expr getExpr(TocParser::LitExprContext * ctx)\r
+{\r
   Expr result;\r
-  result.parenthesized = false;\r
-  if (ctx->funcExpr() != nullptr) {\r
-    result.type = ExprType::Func;\r
-    result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString();\r
-    for (auto e : ctx->funcExpr()->expr())\r
-      result._func.arguments.push_back(getExpr(e));\r
-  }\r
-  if (ctx->litExpr() != nullptr) {\r
-    result.type = ExprType::Lit;\r
-    if (ctx->litExpr()->INT_LIT() != nullptr) {\r
-      result._lit.type = LitType::Int;\r
-      result._lit._int = atoi(ctx->litExpr()->INT_LIT()->toString().c_str());\r
-    }\r
-    else if (ctx->litExpr()->DECIMAL_LIT() != nullptr) {\r
-      result._lit.type = LitType::Decimal;\r
-      result._lit._decimal = atof(ctx->litExpr()->DECIMAL_LIT()->toString().c_str());\r
-    }\r
-    else if (ctx->litExpr()->STRING_LIT() != nullptr) {\r
-      result._lit.type = LitType::String;\r
-      result._lit._string = ctx->litExpr()->STRING_LIT()->toString();\r
-    }\r
-    else if (ctx->litExpr()->BOOL_LIT() != nullptr) {\r
-      result._lit.type = LitType::Bool;\r
-      result._lit._bool = ctx->litExpr()->BOOL_LIT()->toString() == "true";\r
-    }\r
+  result.type = ExprType::Lit;\r
+  if (ctx->literal()->INT_LIT() != nullptr)\r
+  {\r
+    result._lit.type = LitType::Int;\r
+    result._lit._int = atoi(ctx->literal()->INT_LIT()->toString().c_str());\r
   }\r
-  if (ctx->identifierExpr() != nullptr) {\r
-    result.type = ExprType::Identifier;\r
-    result._identifier.name = ctx->identifierExpr()->varName()->NAME()->toString();\r
+  else if (ctx->literal()->DECIMAL_LIT() != nullptr)\r
+  {\r
+    result._lit.type = LitType::Decimal;\r
+    result._lit._decimal = atof(ctx->literal()->DECIMAL_LIT()->toString().c_str());\r
   }\r
-  if (ctx->parenExpr() != nullptr) {\r
-    result = getExpr(ctx->parenExpr()->expr());\r
-    result.parenthesized = true;\r
+  else if (ctx->literal()->StringLit() != nullptr)\r
+  {\r
+    result._lit.type = LitType::String;\r
+    result._lit._string = ctx->literal()->StringLit()->toString();\r
   }\r
-  if (ctx->accessExpr() != nullptr) {\r
-    auto firstSub = ctx->accessExpr()->accessSubExpr(0);\r
-    if (firstSub->accessMember() != nullptr) {\r
-      result.type = ExprType::Dot;\r
-      result._dot.expr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
-      result._dot.ident.name = firstSub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
-    }\r
-    else {\r
-      result.type = ExprType::Brackets;\r
-      result._brackets.lexpr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
-      result._brackets.rexpr = std::make_unique<Expr>(getExpr(firstSub->accessBrackets()->expr()));\r
-    }\r
-    for (int i = 1; i < ctx->accessExpr()->accessSubExpr().size(); i++) {\r
-      Expr tmp = result;\r
-      auto sub = ctx->accessExpr()->accessSubExpr(i);\r
-      if (sub->accessMember() != nullptr) {\r
-        result.type = ExprType::Dot;\r
-        result._dot.expr = std::make_unique<Expr>(tmp);\r
-        result._dot.ident.name = sub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
-      }\r
-      else {\r
-        result.type = ExprType::Brackets;\r
-        result._brackets.lexpr = std::make_unique<Expr>(tmp);\r
-        result._brackets.rexpr = std::make_unique<Expr>(getExpr(sub->accessBrackets()->expr()));\r
-      }\r
-    }\r
+  else if (ctx->literal()->BOOL_LIT() != nullptr)\r
+  {\r
+    result._lit.type = LitType::Bool;\r
+    result._lit._bool = ctx->literal()->BOOL_LIT()->toString() == "true";\r
   }\r
   return result;\r
 }\r
-Expr getExpr(TocParser::NonAccessExprContext * ctx) {\r
+Expr getExpr(TocParser::ParenExprContext * ctx)\r
+{\r
   Expr result;\r
-  result.parenthesized = false;\r
-  if (ctx->funcExpr() != nullptr) {\r
-    result.type = ExprType::Func;\r
-    result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString();\r
-    for (auto e : ctx->funcExpr()->expr())\r
-      result._func.arguments.push_back(getExpr(e));\r
-  }\r
-  if (ctx->identifierExpr() != nullptr) {\r
-    result.type = ExprType::Identifier;\r
-    result._identifier.name = ctx->identifierExpr()->varName()->NAME()->toString();\r
-  }\r
-  if (ctx->parenExpr() != nullptr) {\r
-    result = getExpr(ctx->parenExpr()->expr());\r
-    result.parenthesized = true;\r
-  }\r
+  result.type = ExprType::Paren;\r
+  result._paren.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
   return result;\r
 }\r
-Expr getExpr(TocParser::ExprContext * ctx) {\r
+Expr getExpr(TocParser::DotExprContext * ctx)\r
+{\r
   Expr result;\r
-  result.parenthesized = false;\r
-  if (ctx->funcExpr() != nullptr) {\r
-    result.type = ExprType::Func;\r
-    result._func.functionName = ctx->funcExpr()->funcName()->NAME()->toString();\r
-    for (auto e : ctx->funcExpr()->expr())\r
-      result._func.arguments.push_back(getExpr(e));\r
-  }\r
-  if (ctx->litExpr() != nullptr) {\r
-    result.type = ExprType::Lit;\r
-    if (ctx->litExpr()->INT_LIT() != nullptr) {\r
-      result._lit.type = LitType::Int;\r
-      result._lit._int = atoi(ctx->litExpr()->INT_LIT()->toString().c_str());\r
-    }\r
-    else if (ctx->litExpr()->DECIMAL_LIT() != nullptr) {\r
-      result._lit.type = LitType::Decimal;\r
-      result._lit._decimal = atof(ctx->litExpr()->DECIMAL_LIT()->toString().c_str());\r
-    }\r
-    else if (ctx->litExpr()->STRING_LIT() != nullptr) {\r
-      result._lit.type = LitType::String;\r
-      result._lit._string = ctx->litExpr()->STRING_LIT()->toString();\r
-    }\r
-    else if (ctx->litExpr()->BOOL_LIT() != nullptr) {\r
-      result._lit.type = LitType::Bool;\r
-      result._lit._bool = ctx->litExpr()->BOOL_LIT()->toString() == "true";\r
-    }\r
-  }\r
-  if (ctx->identifierExpr() != nullptr) {\r
-    result.type = ExprType::Identifier;\r
-    result._identifier.name = ctx->identifierExpr()->varName()->NAME()->toString();\r
-  }\r
-  if (ctx->parenExpr() != nullptr) {\r
-    result = getExpr(ctx->parenExpr()->expr());\r
-    result.parenthesized = true;\r
-  }\r
-  if (ctx->accessExpr() != nullptr) {\r
-    auto firstSub = ctx->accessExpr()->accessSubExpr(0);\r
-    if (firstSub->accessMember() != nullptr) {\r
-      result.type = ExprType::Dot;\r
-      result._dot.expr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
-      result._dot.ident.name = firstSub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
-    }\r
-    else {\r
-      result.type = ExprType::Brackets;\r
-      result._brackets.lexpr = std::make_unique<Expr>(getExpr(ctx->accessExpr()->nonAccessExpr()));\r
-      result._brackets.rexpr = std::make_unique<Expr>(getExpr(firstSub->accessBrackets()->expr()));\r
-    }\r
-    for (int i = 1; i < ctx->accessExpr()->accessSubExpr().size(); i++) {\r
-      Expr tmp = result;\r
-      auto sub = ctx->accessExpr()->accessSubExpr(i);\r
-      if (sub->accessMember() != nullptr) {\r
-        result.type = ExprType::Dot;\r
-        result._dot.expr = std::make_unique<Expr>(tmp);\r
-        result._dot.ident.name = sub->accessMember()->identifierExpr()->varName()->NAME()->toString();\r
-      }\r
-      else {\r
-        result.type = ExprType::Brackets;\r
-        result._brackets.lexpr = std::make_unique<Expr>(tmp);\r
-        result._brackets.rexpr = std::make_unique<Expr>(getExpr(sub->accessBrackets()->expr()));\r
-      }\r
-    }\r
-  }\r
-  if (ctx->opExpr() != nullptr) {\r
-    if (ctx->opExpr()->prefixOp() != nullptr || ctx->opExpr()->postfixOp() != nullptr) {\r
-      result.type = ExprType::UnaryOperator;\r
-      result._unaryOperator = getUnaryOperatorExpr(ctx->opExpr());\r
-    }\r
-    else if (ctx->opExpr()->binaryOp() != nullptr) {\r
-      result.type = ExprType::BinaryOperator;\r
-      result._binaryOperator = getBinaryOperatorExpr(ctx->opExpr());\r
-      for (int i = 1; i < ctx->opExpr()->binaryOp()->binary_op().size(); i++) {\r
-        Expr tmp = result;\r
-        result._binaryOperator.lexpr = std::make_unique<Expr>(tmp);\r
-        result._binaryOperator.type = getBinaryOperatorType(ctx->opExpr()->binaryOp()->binary_op(i)->getText());\r
-        result._binaryOperator.rexpr = std::make_unique<Expr>(getExpr(ctx->opExpr()->binaryOp()->nonOpExpr(i+1)));\r
-      }\r
-    }\r
-    else if (ctx->opExpr()->ternaryOp() != nullptr) {\r
-      result.type = ExprType::TernaryOperator;\r
-      result._ternaryOperator = getTernaryOperatorExpr(ctx->opExpr());\r
-    }\r
-  }\r
+  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
+{\r
+  Expr result;\r
+  result.type = ExprType::PrefixOp;\r
+  result._prefixOp.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
+  result._prefixOp.type = getOperatorType<PrefixOperatorType>(\r
+    ctx->prefix_op()->getText(),\r
+    PrefixOperatorTypeStrings);\r
+  return result;\r
+}\r
+Expr getExpr(TocParser::PostfixOpExprContext * ctx)\r
+{\r
+  Expr result;\r
+  result.type = ExprType::PostfixOp;\r
+  result._postfixOp.expr = std::make_unique<Expr>(getExpr(ctx->expr()));\r
+  result._postfixOp.type = getOperatorType<PostfixOperatorType>(\r
+    ctx->postfix_op()->getText(),\r
+    PostfixOperatorTypeStrings);\r
+  return result;\r
+}\r
+Expr getExpr(TocParser::BinaryOpExprContext * ctx)\r
+{\r
+  Expr result;\r
+  result.type = ExprType::BinaryOp;\r
+  result._binaryOp.lexpr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
+  result._binaryOp.rexpr = std::make_unique<Expr>(getExpr(ctx->expr(1)));\r
+  result._binaryOp.type = getOperatorType<BinaryOperatorType>(\r
+    ctx->binary_op()->getText(),\r
+    BinaryOperatorTypeStrings);\r
   return result;\r
 }\r
-Stmt getStmt(TocParser::StmtContext * ctx) {\r
+Expr getExpr(TocParser::TernaryOpExprContext * ctx)\r
+{\r
+  Expr result;\r
+  result.type = ExprType::TernaryOp;\r
+  result._ternaryOp.lexpr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
+  result._ternaryOp.rexprTrue = std::make_unique<Expr>(getExpr(ctx->expr(1)));\r
+  result._ternaryOp.rexprFalse = std::make_unique<Expr>(getExpr(ctx->expr(2)));\r
+  return result;\r
+}\r
+Expr getExpr(TocParser::BracketExprContext * ctx)\r
+{\r
+  Expr result;\r
+  result.type = ExprType::Bracket;\r
+  result._brackets.lexpr = std::make_unique<Expr>(getExpr(ctx->expr(0)));\r
+  result._brackets.rexpr = std::make_unique<Expr>(getExpr(ctx->expr(1)));\r
+  return result;\r
+}\r
+Expr getExpr(TocParser::IdentifierExprContext * ctx)\r
+{\r
+  Expr result;\r
+  result.type = ExprType::Identifier;\r
+  for (auto n : ctx->namespaceSpecifier())\r
+    result._identifier.namespacePrefixes.push_back(n->typeName()->getText());\r
+  result._identifier.identifier = ctx->varName()->getText();\r
+  return result;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+Expr getExpr(TocParser::ExprContext * ctx)\r
+{\r
+  Expr result;\r
+  if (dynamic_cast<TocParser::FuncExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::FuncExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::MethodExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::MethodExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::LitExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::LitExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::ParenExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::ParenExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::DotExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::DotExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::PrefixOpExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::PrefixOpExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::PostfixOpExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::PostfixOpExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::BinaryOpExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::BinaryOpExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::TernaryOpExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::TernaryOpExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::BracketExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::BracketExprContext *>(ctx));\r
+  if (dynamic_cast<TocParser::IdentifierExprContext *>(ctx) != nullptr)\r
+    result = getExpr(dynamic_cast<TocParser::IdentifierExprContext *>(ctx));\r
+  return result;\r
+}\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
+  if (ctx->varDecl() != nullptr && ctx->varDecl()->var()->expr() != nullptr)\r
+  {\r
     result.type = StmtType::Assign;\r
-    result._assign.name = ctx->varDecl()->var()->varName()->NAME()->toString();\r
-    result._assign.expr = getExpr(ctx->varDecl()->var()->expr());\r
+    result._assign.lexpr.type = ExprType::Identifier;\r
+    result._assign.lexpr._identifier.identifier = ctx->varDecl()->var()->varName()->getText();\r
+    result._assign.rexpr = getExpr(ctx->varDecl()->var()->expr());\r
   }\r
-  if (ctx->ifStmt() != nullptr) {\r
+  if (ctx->ifStmt() != nullptr)\r
+  {\r
     result.type = StmtType::If;\r
     result._if.condition = getExpr(ctx->ifStmt()->expr());\r
-    result._if.body = getBody(ctx->ifStmt()->body());\r
-    for (auto ei : ctx->ifStmt()->elseIfStmt()) {\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
+    if (ctx->ifStmt()->elseStmt() != nullptr)\r
+    {\r
       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
-  if (ctx->switchStmt() != nullptr) {\r
+  if (ctx->switchStmt() != nullptr)\r
+  {\r
     result.type = StmtType::Switch;\r
-    result._switch.ident.name = ctx->switchStmt()->identifierExpr()->varName()->NAME()->toString();\r
-    for (auto c : ctx->switchStmt()->switchBody()->switchCase()) {\r
+    result._switch.ident = std::make_unique<Expr>(getExpr(ctx->switchStmt()->expr()));\r
+    for (auto c : ctx->switchStmt()->switchBody()->switchCase())\r
+    {\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
-  if (ctx->forStmt() != nullptr) {\r
+  if (ctx->forStmt() != nullptr)\r
+  {\r
     result.type = StmtType::For;\r
-    if (ctx->forStmt()->varInit() != nullptr) {\r
-      result._for.varName = ctx->forStmt()->varInit()->varName()->NAME()->toString();\r
-      result._for.initValue = std::make_unique<Expr>(getExpr(ctx->forStmt()->varInit()->expr()));\r
-    }\r
-    else {\r
-      result._for.varName = ctx->forStmt()->assignStmt()->identifierExpr()->varName()->NAME()->toString();\r
-      result._for.initValue = std::make_unique<Expr>(getExpr(ctx->forStmt()->assignStmt()->expr()));\r
-    }\r
+    result._for.init = std::make_unique<AssignStmt>();\r
+    result._for.init->lexpr.type = ExprType::Identifier;\r
+    result._for.init->lexpr._identifier.identifier = ctx->forStmt()->varInit()->varName()->getText();\r
+    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
+  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
+  if (ctx->assignStmt() != nullptr)\r
+  {\r
     result.type = StmtType::Assign;\r
-    result._assign.name = ctx->assignStmt()->identifierExpr()->varName()->NAME()->toString();\r
-    result._assign.expr = getExpr(ctx->assignStmt()->expr());\r
+    result._assign.lexpr = getExpr(ctx->assignStmt()->expr(0));\r
+    result._assign.rexpr = getExpr(ctx->assignStmt()->expr(1));\r
   }\r
-  if (ctx->returnStmt() != nullptr) {\r
+  if (ctx->returnStmt() != nullptr)\r
+  {\r
     result.type = StmtType::Return;\r
     result._return.expr = getExpr(ctx->returnStmt()->expr());\r
   }\r
-  if (ctx->expr() != nullptr) {\r
+  if (ctx->expr() != nullptr)\r
+  {\r
     result.type = StmtType::Expr;\r
     result._expr = getExpr(ctx->expr());\r
   }\r