|
@@ -1,21 +1,23 @@
|
|
#include "AstVisitor.h"
|
|
#include "AstVisitor.h"
|
|
#include "Ast.h"
|
|
#include "Ast.h"
|
|
|
|
|
|
|
|
+#include <typeinfo>
|
|
|
|
+
|
|
#include "Util.h"
|
|
#include "Util.h"
|
|
|
|
|
|
using namespace qlow;
|
|
using namespace qlow;
|
|
|
|
|
|
|
|
|
|
-sem::Class* StructureVisitor::getType(const std::string& type, const sem::SymbolTable<sem::Class>& classes)
|
|
+sem::Class* StructureVisitor::getType(const std::string& type, sem::Scope& scope)
|
|
{
|
|
{
|
|
- auto t = classes.find(type);
|
|
+ auto t = scope.getType(type);
|
|
- if (t != classes.end())
|
|
+ if (t)
|
|
- return t->second.get();
|
|
+ return t.value().typeClass;
|
|
else
|
|
else
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Class& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Class& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto c = std::make_unique<sem::Class>();
|
|
auto c = std::make_unique<sem::Class>();
|
|
c->name = ast.name;
|
|
c->name = ast.name;
|
|
@@ -23,18 +25,22 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Class& ast, co
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureDeclaration& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
|
|
|
|
|
|
+ throw "shouldn't be called";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FieldDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FieldDeclaration& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto f = std::make_unique<sem::Field>();
|
|
auto f = std::make_unique<sem::Field>();
|
|
f->name = ast.name;
|
|
f->name = ast.name;
|
|
- f->type = getType(ast.type, classes);
|
|
+ auto type = scope.getType(ast.type);
|
|
- if (f->type == nullptr) {
|
|
+ if (type) {
|
|
|
|
+ f->type = type.value().typeClass;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE,
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE,
|
|
ast.type,
|
|
ast.type,
|
|
ast.pos
|
|
ast.pos
|
|
@@ -44,28 +50,34 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FieldDeclarati
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::MethodDefinition& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::MethodDefinition& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto m = std::make_unique<sem::Method>();
|
|
auto m = std::make_unique<sem::Method>();
|
|
m->name = ast.name;
|
|
m->name = ast.name;
|
|
- m->returnType = getType(ast.type, classes);
|
|
+ auto returnType = scope.getType(ast.type);
|
|
- m->astNode = *
|
|
+ if (returnType) {
|
|
- if (m->returnType == nullptr) {
|
|
+ m->returnType = returnType.value();
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE,
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE,
|
|
ast.type,
|
|
ast.type,
|
|
ast.pos
|
|
ast.pos
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
+ m->astNode = *
|
|
return m;
|
|
return m;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::VariableDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::VariableDeclaration& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto v = std::make_unique<sem::Variable>();
|
|
auto v = std::make_unique<sem::Variable>();
|
|
v->name = ast.name;
|
|
v->name = ast.name;
|
|
- v->type = getType(ast.type, classes);
|
|
+ auto type = scope.getType(ast.type);
|
|
- if (v->type == nullptr) {
|
|
+ if (type) {
|
|
|
|
+ v->type = type.value().typeClass;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE,
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE,
|
|
ast.type,
|
|
ast.type,
|
|
ast.pos
|
|
ast.pos
|
|
@@ -75,26 +87,29 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::VariableDeclar
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::ArgumentDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::ArgumentDeclaration& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
|
|
+ throw "shouldn't be called";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::DoEndBlock& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::DoEndBlock& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto body = std::make_unique<sem::DoEndBlock>();
|
|
auto body = std::make_unique<sem::DoEndBlock>();
|
|
for (auto& statement : ast.statements) {
|
|
for (auto& statement : ast.statements) {
|
|
|
|
|
|
if (ast::NewVariableStatement* nvs = dynamic_cast<ast::NewVariableStatement*>(statement.get()); nvs) {
|
|
if (ast::NewVariableStatement* nvs = dynamic_cast<ast::NewVariableStatement*>(statement.get()); nvs) {
|
|
- auto var = std::make_unique<sem::Variable>(getType(nvs->type, classes), nvs->name);
|
|
+ auto type = scope.getType(nvs->type);
|
|
- if (var->type == nullptr)
|
|
+
|
|
|
|
+ if (!type)
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE, nvs->type, nvs->pos);
|
|
throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE, nvs->type, nvs->pos);
|
|
-
|
|
+
|
|
|
|
+ auto var = std::make_unique<sem::Variable>(type.value().typeClass, nvs->name);
|
|
body->variables.push_back(std::move(var));
|
|
body->variables.push_back(std::move(var));
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- auto v = visit(*statement, classes);
|
|
+ auto v = statement->accept(*this, scope);
|
|
if (dynamic_cast<sem::FeatureCallExpression*>(v.get()) != nullptr) {
|
|
if (dynamic_cast<sem::FeatureCallExpression*>(v.get()) != nullptr) {
|
|
body->statements.push_back(std::make_unique<sem::FeatureCallStatement>(unique_dynamic_cast<sem::FeatureCallExpression>(std::move(v))));
|
|
body->statements.push_back(std::make_unique<sem::FeatureCallStatement>(unique_dynamic_cast<sem::FeatureCallExpression>(std::move(v))));
|
|
}
|
|
}
|
|
@@ -106,55 +121,69 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::DoEndBlock& as
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Statement& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Statement& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
|
|
+ printf("at: %d:%d to %d:%d\n", ast.pos.first_line, ast.pos.first_column, ast.pos.last_line, ast.pos.last_column);
|
|
|
|
+ printf("type: %s\n", typeid(ast).name());
|
|
|
|
+ throw "visit(Statement) shouldn't be called";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Expression& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Expression& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
|
|
+ throw "visit(Expression) shouldn't be called";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureCall& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureCall& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto fce = std::make_unique<sem::FeatureCallExpression>();
|
|
auto fce = std::make_unique<sem::FeatureCallExpression>();
|
|
-
|
|
+
|
|
|
|
+ fce->callee = scope.getMethod(ast.name);
|
|
return fce;
|
|
return fce;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::AssignmentStatement& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::AssignmentStatement& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto as = std::make_unique<sem::AssignmentStatement>();
|
|
auto as = std::make_unique<sem::AssignmentStatement>();
|
|
|
|
|
|
- as->value = unique_dynamic_cast<sem::Expression>(visit(*ast.expr, classes));
|
|
+
|
|
- as->target = unique_dynamic_cast<sem::Expression>(visit(*ast.target, classes));
|
|
+
|
|
|
|
+ as->value = unique_dynamic_cast<sem::Expression>(ast.expr->accept(*this, scope));
|
|
|
|
+ as->target = unique_dynamic_cast<sem::Expression>(ast.target->accept(*this, scope));
|
|
return as;
|
|
return as;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::NewVariableStatement& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::NewVariableStatement& ast, sem::Scope& scope)
|
|
|
|
+{
|
|
|
|
+ throw "shouldn't be called";
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::IntConst& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
|
|
+ return std::make_unique<sem::IntConst>(ast.value);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::UnaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::UnaryOperation& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto ret = std::make_unique<sem::UnaryOperation>();
|
|
auto ret = std::make_unique<sem::UnaryOperation>();
|
|
ret->op = ast.op;
|
|
ret->op = ast.op;
|
|
ret->side = ast.side;
|
|
ret->side = ast.side;
|
|
- ret->arg = unique_dynamic_cast<sem::Expression>(visit(*ast.expr, classes));
|
|
+ ret->arg = unique_dynamic_cast<sem::Expression>(ast.expr->accept(*this, scope));
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::BinaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
|
|
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::BinaryOperation& ast, sem::Scope& scope)
|
|
{
|
|
{
|
|
auto ret = std::make_unique<sem::BinaryOperation>();
|
|
auto ret = std::make_unique<sem::BinaryOperation>();
|
|
ret->op = ast.op;
|
|
ret->op = ast.op;
|
|
- ret->left = unique_dynamic_cast<sem::Expression>(visit(*ast.left, classes));
|
|
+ ret->left = unique_dynamic_cast<sem::Expression>(ast.left->accept(*this, scope));
|
|
- ret->right = unique_dynamic_cast<sem::Expression>(visit(*ast.right, classes));
|
|
+ ret->right = unique_dynamic_cast<sem::Expression>(ast.right->accept(*this, scope));
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|