ready to merge docs

This commit is contained in:
2024-08-11 08:37:17 +00:00
parent 9900d5aaf3
commit 22d18436fa
10 changed files with 346 additions and 38 deletions

View File

@ -3,6 +3,8 @@
#include <memory>
#include <variant>
#include <vector>
#include "../semantic/visitor.h"
#include "tools.h"
using IdentifierType = std::string;
struct ArrayType {
bool has_base_type;
@ -15,17 +17,15 @@ class ASTNodeVisitorBase {
virtual ~ASTNodeVisitorBase() = default;
virtual void visit(class ASTNodeBase *context) = 0;
};
enum class ASTNodeType {
};
class ASTNodeBase {
friend Visitor;
ASTNodeType type;
// std::vector<std::shared_ptr<ASTNodeBase>> children;
size_t start_line, start_char_pos, end_line, end_char_pos;
public:
virtual ~ASTNodeBase() = default;
virtual void accept(class ASTNodeVisitorBase *visitor) = 0;
// virtual void accept(class ASTNodeVisitorBase *visitor) = 0;
};
#endif

View File

@ -14,112 +14,147 @@ class Expr_ASTNode : public ASTNodeBase {
class BasicExpr_ASTNode : public Expr_ASTNode {}; // This is a virtual class
class NewArrayExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
bool has_initial_value;
std::shared_ptr<class ConstantExpr_ASTNode> initial_value;
};
class NewConstructExpr_ASTNode : public Expr_ASTNode {};
class NewExpr_ASTNode : public Expr_ASTNode {};
class NewConstructExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
};
class NewExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
};
class AccessExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> base;
IdentifierType member;
};
class MemberVariableAccessExpr_ASTNode : public AccessExpr_ASTNode {};
class MemberVariableAccessExpr_ASTNode : public AccessExpr_ASTNode {
friend Visitor;
};
class MemberFunctionAccessExpr_ASTNode : public AccessExpr_ASTNode {
friend Visitor;
std::vector<std::shared_ptr<Expr_ASTNode>> arguments;
};
class IndexExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> base;
std::vector<std::shared_ptr<Expr_ASTNode>> indices;
};
class SuffixExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> base;
};
class PrefixExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> base;
};
class OppositeExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> base;
};
class LNotExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class BNotExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class MDMExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class PMExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class RLExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class GGLLExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class NEExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class BAndExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class BXorExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class BOrExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class LAndExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class LOrExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> left;
std::shared_ptr<Expr_ASTNode> right;
};
class TernaryExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> condition;
std::shared_ptr<Expr_ASTNode> src1;
std::shared_ptr<Expr_ASTNode> src2;
};
class AssignExpr_ASTNode : public Expr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> dest;
std::shared_ptr<Expr_ASTNode> src;
};
class ThisExpr_ASTNode : public BasicExpr_ASTNode {};
class ThisExpr_ASTNode : public BasicExpr_ASTNode {
friend Visitor;
};
class ParenExpr_ASTNode : public BasicExpr_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> expr;
};
class IDExpr_ASTNode : public BasicExpr_ASTNode {
friend Visitor;
IdentifierType id;
};
class FunctionCallExpr_ASTNode : public BasicExpr_ASTNode {
friend Visitor;
IdentifierType func_name;
std::vector<std::shared_ptr<Expr_ASTNode>> arguments;
};
class FormattedStringExpr_ASTNode : public BasicExpr_ASTNode {
friend Visitor;
using SegmentType = std::variant<std::string, std::shared_ptr<Expr_ASTNode>>;
std::vector<SegmentType> segments;
};
struct NullType {};
using AtomicConstantType = std::variant<uint32_t, bool, std::string, NullType>;
struct ArrayConstantType {
friend Visitor;
std::vector<std::variant<std::shared_ptr<ArrayConstantType>, NullType, AtomicConstantType>> elements;
size_t level;
};
class ConstantExpr_ASTNode : public BasicExpr_ASTNode {
friend Visitor;
std::variant<AtomicConstantType, ArrayConstantType> value;
};

View File

@ -8,34 +8,43 @@ class Statement_ASTNode : public ASTNodeBase {
virtual ~Statement_ASTNode() = default;
};
class EmptyStatement_ASTNode : public Statement_ASTNode {};
class EmptyStatement_ASTNode : public Statement_ASTNode {
friend Visitor;
};
class DefinitionStatement_ASTNode : public Statement_ASTNode {
ExprTypeInfo type;
friend Visitor;
ExprTypeInfo var_type;
std::vector<std::pair<IdentifierType, std::shared_ptr<Expr_ASTNode>>> vars;
};
class ExprStatement_ASTNode : public Statement_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> expr;
};
class IfStatement_ASTNode : public Statement_ASTNode {
friend Visitor;
bool has_else_clause;
std::shared_ptr<Expr_ASTNode> condition;
std::shared_ptr<Statement_ASTNode> if_clause;
std::shared_ptr<Statement_ASTNode> else_clause;
};
class WhileStatement_ASTNode : public Statement_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> condition;
std::shared_ptr<Statement_ASTNode> loop_body;
};
class ForStatement_ASTNode : public Statement_ASTNode {
friend Visitor;
std::shared_ptr<Statement_ASTNode> initial;
std::shared_ptr<Expr_ASTNode> condition;
std::shared_ptr<Statement_ASTNode> update;
std::shared_ptr<Statement_ASTNode> loop_body;
};
class JmpStatement_ASTNode : public Statement_ASTNode {
friend Visitor;
std::shared_ptr<Expr_ASTNode> return_value;
};
class SuiteStatement_ASTNode : public Statement_ASTNode {
friend Visitor;
std::vector<std::shared_ptr<Statement_ASTNode>> statements;
};

View File

@ -7,21 +7,35 @@
#include "expr_astnode.h"
#include "statement_astnode.h"
class FuncDef_ASTNode : public ASTNodeBase {
friend Visitor;
bool is_constructor;
IdentifierType func_name;
ExprTypeInfo return_type;
std::vector<std::pair<IdentifierType, ExprTypeInfo>> params;
std::shared_ptr<SuiteStatement_ASTNode> func_body;
public:
FuncDef_ASTNode() = default;
};
class Constructor_ASTNode : public FuncDef_ASTNode {};
class ClassVariable_ASTNode : public DefinitionStatement_ASTNode {};
class ClassDef_ASTNode : public ASTNodeBase {
friend Visitor;
private:
using ClassElement = std::variant<std::shared_ptr<Constructor_ASTNode>, std::shared_ptr<ClassVariable_ASTNode>,
std::shared_ptr<FuncDef_ASTNode>>;
std::vector<ClassElement> elements;
std::string class_name;
std::vector<std::shared_ptr<DefinitionStatement_ASTNode>> member_variables;
std::vector<std::shared_ptr<FuncDef_ASTNode>> member_functions;
std::shared_ptr<FuncDef_ASTNode> constructor;
public:
ClassDef_ASTNode() = default;
};
class Program_ASTNode : public ASTNodeBase {
using ProgramElement = std::variant<std::shared_ptr<FuncDef_ASTNode>, std::shared_ptr<ClassDef_ASTNode>,
std::shared_ptr<DefinitionStatement_ASTNode>>;
std::vector<ProgramElement> elements;
friend Visitor;
std::vector<std::shared_ptr<DefinitionStatement_ASTNode>> global_variables;
std::vector<std::shared_ptr<ClassDef_ASTNode>> classes;
std::vector<std::shared_ptr<FuncDef_ASTNode>> functions;
public:
Program_ASTNode() = default;
};
#endif

View File

@ -4,15 +4,6 @@
#include "ast/ast.h"
#include "visitor.h"
class SemanticError : public std::exception {
std::string msg;
int error_code;
public:
SemanticError(const std::string &msg, int error_code) : msg(msg), error_code(error_code) {}
const char *what() const noexcept override { return msg.c_str(); }
int GetErrorCode() const { return error_code; }
};
std::shared_ptr<ASTNodeBase> BuildAST(Visitor *visitor, antlr4::tree::ParseTree *tree);
void SemanticCheck(std::istream &fin, std::shared_ptr<ASTNodeBase> &ast);
#endif

View File

@ -1,9 +1,13 @@
#ifndef VISITOR_H
#define VISITOR_H
#include <stack>
#include <vector>
#include "MXParserVisitor.h"
#include "tools.h"
class Visitor : public MXParserVisitor {
std::vector<ASTNodeType> nodetype_stk;
public:
std::any visitMxprog(MXParser::MxprogContext *context) override;
std::any visitFunction_def(MXParser::Function_defContext *context) override;

61
include/tools.h Normal file
View File

@ -0,0 +1,61 @@
#pragma once
#include <stdexcept>
enum class ASTNodeType {
// Expression nodes
NewArrayExpr,
NewConstructExpr,
NewExpr,
MemberVariableAccessExpr,
MemberFunctionAccessExpr,
IndexExpr,
SuffixExpr,
PrefixExpr,
OppositeExpr,
LNotExpr,
BNotExpr,
MDMExpr,
PMExpr,
RLExpr,
GGLLExpr,
NEExpr,
BAndExpr,
BXorExpr,
BOrExpr,
LAndExpr,
LOrExpr,
TernaryExpr,
AssignExpr,
ThisExpr,
ParenExpr,
IDExpr,
FunctionCallExpr,
FormattedStringExpr,
ConstantExpr,
// Statement nodes
EmptyStatement,
DefinitionStatement,
ExprStatement,
IfStatement,
WhileStatement,
ForStatement,
JmpStatement,
SuiteStatement,
// Structural nodes
FuncDef,
Constructor,
ClassVariable,
ClassDef,
Program
};
class SemanticError : public std::exception {
std::string msg;
int error_code;
public:
SemanticError(const std::string &msg, int error_code) : msg(msg), error_code(error_code) {}
const char *what() const noexcept override { return msg.c_str(); }
int GetErrorCode() const { return error_code; }
};

View File

@ -1,3 +1,6 @@
include_directories(${CMAKE_SOURCE_DIR}/include/ast)
file(GLOB AST_SOURCES "*.cpp")
add_library(ast STATIC ${AST_SOURCES})
add_library(ast STATIC ${AST_SOURCES})
target_include_directories(ast PUBLIC /usr/include/antlr4-runtime/)
target_include_directories(ast PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../semantic/antlr-generated)
target_link_libraries(ast PUBLIC antlr4-runtime)

View File

@ -13,13 +13,15 @@ class MXErrorListener : public antlr4::BaseErrorListener {
MXErrorListener() : no_problem(true) {}
void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line,
size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override {
std::cout << "line " << line << ":" << charPositionInLine << " AT "
<< offendingSymbol->getText() << ": " << msg << std::endl;
std::cout << "line " << line << ":" << charPositionInLine << " AT " << offendingSymbol->getText() << ": " << msg
<< std::endl;
no_problem = false;
}
bool IsOk() { return no_problem; }
};
std::shared_ptr<ASTNodeBase> BuildAST(Visitor *visitor, antlr4::tree::ParseTree *tree) { ; }
std::shared_ptr<ASTNodeBase> BuildAST(Visitor *visitor, antlr4::tree::ParseTree *tree) {
return std::any_cast<std::shared_ptr<Program_ASTNode>>(visitor->visit(tree));
}
std::shared_ptr<ASTNodeBase> CheckAndDecorate(std::shared_ptr<ASTNodeBase> src) { ; }
void SemanticCheck(std::istream &fin, std::shared_ptr<ASTNodeBase> &ast_out) {

View File

@ -1,16 +1,205 @@
#include "visitor.h"
#include <stdexcept>
#include <type_traits>
#include "MXParser.h"
#include "MXParserVisitor.h"
#include "ast/ast.h"
std::any Visitor::visitMxprog(MXParser::MxprogContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitFunction_def(MXParser::Function_defContext *context) {
throw std::runtime_error("Not implemented");
std::any Visitor::visitMxprog(MXParser::MxprogContext *context) {
auto program = std::make_shared<Program_ASTNode>();
program->type = ASTNodeType::Program;
program->start_line = context->getStart()->getLine();
program->start_char_pos = context->getStart()->getCharPositionInLine();
program->end_line = context->getStop()->getLine();
program->end_char_pos = context->getStop()->getCharPositionInLine();
nodetype_stk.push_back(ASTNodeType::Program);
for (auto def : context->children) {
if (auto classDefContext = dynamic_cast<MXParser::Class_defContext *>(def)) {
auto classNode = std::any_cast<std::shared_ptr<ClassDef_ASTNode>>(visit(classDefContext));
program->classes.push_back(classNode);
} else if (auto defineStmtContext = dynamic_cast<MXParser::Define_statementContext *>(def)) {
auto defineNode = std::any_cast<std::shared_ptr<DefinitionStatement_ASTNode>>(visit(defineStmtContext));
program->global_variables.push_back(defineNode);
} else if (auto funcDefContext = dynamic_cast<MXParser::Function_defContext *>(def)) {
auto funcNode = std::any_cast<std::shared_ptr<FuncDef_ASTNode>>(visit(funcDefContext));
program->functions.push_back(funcNode);
} else if (auto EOFToken = dynamic_cast<antlr4::tree::TerminalNode *>(def)) {
if (EOFToken == context->EOF()) break;
throw std::runtime_error("unknown subnode occurred in visitMxprog");
} else {
throw std::runtime_error("unknown subnode occurred in visitMxprog");
}
}
nodetype_stk.pop_back();
return program;
}
std::any Visitor::visitFunction_def(MXParser::Function_defContext *context) {
auto func = std::make_shared<FuncDef_ASTNode>();
func->type = ASTNodeType::FuncDef;
func->is_constructor = false;
func->start_line = context->getStart()->getLine();
func->start_char_pos = context->getStart()->getCharPositionInLine();
func->end_line = context->getStop()->getLine();
func->end_char_pos = context->getStop()->getCharPositionInLine();
nodetype_stk.push_back(ASTNodeType::FuncDef);
std::string return_type_str;
if (auto type_context = dynamic_cast<MXParser::TypeContext *>(context->children[0])) {
// return type
return_type_str = type_context->getText();
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "return_type_str=" << return_type_str << std::endl;
} else
throw std::runtime_error("unknown subnode occurred in visitFunction_def");
int return_dimensions = 0;
for (size_t i = 1; i < context->children.size(); i++) {
if (dynamic_cast<antlr4::tree::TerminalNode *>(context->children[i]) != nullptr &&
dynamic_cast<antlr4::tree::TerminalNode *>(context->children[i])->getSymbol()->getType() == MXParser::ID) {
break;
}
return_dimensions++;
}
return_dimensions >>= 1;
if (return_dimensions == 0) {
func->return_type = return_type_str;
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded return type is [none-array]" << return_type_str
<< std::endl;
} else {
func->return_type = ArrayType{true, return_type_str, static_cast<size_t>(return_dimensions)};
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded return type is [array]" << return_type_str
<< " with dimensions=" << return_dimensions << std::endl;
}
func->func_name = context->children[1 + 2 * return_dimensions]->getText();
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "func_name=" << func->func_name << std::endl;
size_t cur = 3 + 2 * return_dimensions;
bool is_first_para = true;
while (true) {
if (cur >= context->children.size()) throw std::runtime_error("something strange happened in visitFunction_def");
auto ptr = dynamic_cast<antlr4::tree::TerminalNode *>(context->children[cur]);
if (ptr != nullptr && ptr->getSymbol()->getType() == MXParser::RPAREN) break;
if (is_first_para) goto cancel_first;
if (ptr->getSymbol()->getType() != MXParser::COMMA)
throw std::runtime_error("something strange happened in visitFunction_def");
cur++;
cancel_first:
is_first_para = false;
std::string cur_para_type_base_str = context->children[cur]->getText();
int cur_para_dimensions = 0;
while (dynamic_cast<antlr4::tree::TerminalNode *>(context->children[cur + 1]) != nullptr &&
(dynamic_cast<antlr4::tree::TerminalNode *>(context->children[cur + 1])->getSymbol()->getType() ==
MXParser::LBRACKET ||
dynamic_cast<antlr4::tree::TerminalNode *>(context->children[cur + 1])->getSymbol()->getType() ==
MXParser::RBRACKET)) {
cur_para_dimensions++;
cur++;
}
cur++;
cur_para_dimensions >>= 1;
std::string cur_para_name = context->children[cur]->getText();
ExprTypeInfo cur_para_type;
if (cur_para_dimensions == 0) {
cur_para_type = cur_para_type_base_str;
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded parameter type is [none-array]"
<< cur_para_type_base_str << std::endl;
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded parameter name is " << cur_para_name
<< std::endl;
} else {
cur_para_type = ArrayType{true, cur_para_type_base_str, static_cast<size_t>(cur_para_dimensions)};
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded parameter type is [array]"
<< cur_para_type_base_str << " with dimensions=" << cur_para_dimensions << std::endl;
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded parameter name is " << cur_para_name
<< std::endl;
}
func->params.push_back(std::make_pair(cur_para_name, cur_para_type));
cur++;
}
func->func_body = std::any_cast<std::shared_ptr<SuiteStatement_ASTNode>>(visit(context->suite()));
nodetype_stk.pop_back();
return func;
}
std::any Visitor::visitClass_def(MXParser::Class_defContext *context) {
auto class_def = std::make_shared<ClassDef_ASTNode>();
class_def->type = ASTNodeType::ClassDef;
class_def->start_line = context->getStart()->getLine();
class_def->start_char_pos = context->getStart()->getCharPositionInLine();
class_def->end_line = context->getStop()->getLine();
class_def->end_char_pos = context->getStop()->getCharPositionInLine();
nodetype_stk.push_back(ASTNodeType::ClassDef);
class_def->class_name = context->ID()->getText();
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "building a class named " << class_def->class_name
<< std::endl;
std::vector<MXParser::Class_constructorContext *> constructors = context->class_constructor();
if (constructors.size() > 1) throw SemanticError("Multiple constructor found for class " + class_def->class_name, 2);
if (constructors.size() > 0)
class_def->constructor = std::any_cast<std::shared_ptr<FuncDef_ASTNode>>(visit(constructors[0]));
std::vector<MXParser::Function_defContext *> functions = context->function_def();
for (auto func : functions) {
auto func_node = std::any_cast<std::shared_ptr<FuncDef_ASTNode>>(visit(func));
class_def->member_functions.push_back(func_node);
}
nodetype_stk.pop_back();
return class_def;
}
std::any Visitor::visitClass_def(MXParser::Class_defContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitClass_var_def(MXParser::Class_var_defContext *context) {
throw std::runtime_error("Not implemented");
auto member_var_def = std::make_shared<DefinitionStatement_ASTNode>();
member_var_def->type = ASTNodeType::ClassVariable;
member_var_def->start_line = context->getStart()->getLine();
member_var_def->start_char_pos = context->getStart()->getCharPositionInLine();
member_var_def->end_line = context->getStop()->getLine();
member_var_def->end_char_pos = context->getStop()->getCharPositionInLine();
nodetype_stk.push_back(ASTNodeType::ClassVariable);
std::string define_type_base;
if (auto type_context = dynamic_cast<MXParser::TypeContext *>(context->children[0])) {
define_type_base = type_context->getText();
} else
throw std::runtime_error("unknown subnode occurred in visitClass_var_def");
int define_dimensions = 0;
for (size_t i = 1; i < context->children.size(); i++) {
if (dynamic_cast<antlr4::tree::TerminalNode *>(context->children[i]) != nullptr &&
dynamic_cast<antlr4::tree::TerminalNode *>(context->children[i])->getSymbol()->getType() == MXParser::ID) {
break;
}
define_dimensions++;
}
define_dimensions >>= 1;
if (define_dimensions == 0) {
member_var_def->var_type = define_type_base;
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded member variable type is [none-array]"
<< define_type_base << std::endl;
} else {
member_var_def->var_type = ArrayType{true, define_type_base, static_cast<size_t>(define_dimensions)};
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded member variable type is [array]"
<< define_type_base << " with dimensions=" << define_dimensions << std::endl;
}
auto identifiers = context->ID();
for (auto id : identifiers) {
member_var_def->vars.push_back(std::make_pair(id->getText(), nullptr));
std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded member variable name is " << id->getText()
<< std::endl;
}
nodetype_stk.pop_back();
return member_var_def;
}
std::any Visitor::visitClass_constructor(MXParser::Class_constructorContext *context) {
throw std::runtime_error("Not implemented");
auto construct_func = std::make_shared<FuncDef_ASTNode>();
construct_func->type = ASTNodeType::Constructor;
construct_func->is_constructor = false;
construct_func->start_line = context->getStart()->getLine();
construct_func->start_char_pos = context->getStart()->getCharPositionInLine();
construct_func->end_line = context->getStop()->getLine();
construct_func->end_char_pos = context->getStop()->getCharPositionInLine();
nodetype_stk.push_back(ASTNodeType::Constructor);
construct_func->func_body = std::any_cast<std::shared_ptr<SuiteStatement_ASTNode>>(visit(context->suite()));
nodetype_stk.pop_back();
return construct_func;
}
std::any Visitor::visitSuite(MXParser::SuiteContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitEmpty_statement(MXParser::Empty_statementContext *context) {