Type check pointer dereferencing
This commit is contained in:
@ -1,5 +1,4 @@
|
||||
#include "elna/source/result.hpp"
|
||||
#include "elna/source/types.hpp"
|
||||
|
||||
namespace elna::source
|
||||
{
|
||||
@ -33,4 +32,15 @@ namespace elna::source
|
||||
{
|
||||
return "Name '" + name + "' was already defined";
|
||||
}
|
||||
|
||||
type_mismatch::type_mismatch(std::shared_ptr<const type> got, operation kind, const std::filesystem::path& path,
|
||||
const struct position position)
|
||||
: error(path, position), kind(kind), got(got)
|
||||
{
|
||||
}
|
||||
|
||||
std::string type_mismatch::what() const
|
||||
{
|
||||
return "Type cannot be used here.";
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
#include "elna/source/semantic.hpp"
|
||||
#include "elna/source/types.hpp"
|
||||
#include "elna/source/result.hpp"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace elna::source
|
||||
{
|
||||
name_analysis_visitor::name_analysis_visitor(std::shared_ptr<symbol_table> table)
|
||||
: table(table)
|
||||
name_analysis_visitor::name_analysis_visitor(std::shared_ptr<symbol_table> table,
|
||||
const std::filesystem::path& filename)
|
||||
: table(table), filename(filename)
|
||||
{
|
||||
}
|
||||
|
||||
@ -63,6 +64,11 @@ namespace elna::source
|
||||
this->table = info->scope()->scope();
|
||||
}
|
||||
|
||||
const std::list<std::unique_ptr<error>>& name_analysis_visitor::errors() const noexcept
|
||||
{
|
||||
return m_errors;
|
||||
}
|
||||
|
||||
allocator_visitor::allocator_visitor(std::shared_ptr<symbol_table> table)
|
||||
: table(table)
|
||||
{
|
||||
@ -115,4 +121,69 @@ namespace elna::source
|
||||
this->argument_offset = std::max(static_cast<std::size_t>(this->argument_offset),
|
||||
call_info->parameter_stack_size());
|
||||
}
|
||||
|
||||
type_analysis_visitor::type_analysis_visitor(std::shared_ptr<symbol_table> table,
|
||||
const std::filesystem::path& filename, std::size_t target_pointer_size)
|
||||
: table(table), filename(filename), pointer_size(target_pointer_size)
|
||||
{
|
||||
}
|
||||
|
||||
void type_analysis_visitor::visit(program *program)
|
||||
{
|
||||
for (auto& definition : program->definitions())
|
||||
{
|
||||
if (dynamic_cast<procedure_definition *>(definition.get()) != nullptr)
|
||||
{
|
||||
definition->accept(this);
|
||||
}
|
||||
}
|
||||
program->body().accept(this);
|
||||
}
|
||||
|
||||
void type_analysis_visitor::visit(procedure_definition *definition)
|
||||
{
|
||||
definition->body().accept(this);
|
||||
}
|
||||
|
||||
void type_analysis_visitor::visit(integer_literal *literal)
|
||||
{
|
||||
literal->data_type = std::dynamic_pointer_cast<type_info>(table->lookup("Int"))->type();
|
||||
}
|
||||
|
||||
void type_analysis_visitor::visit(boolean_literal *literal)
|
||||
{
|
||||
literal->data_type = std::dynamic_pointer_cast<type_info>(table->lookup("Boolean"))->type();
|
||||
}
|
||||
|
||||
void type_analysis_visitor::visit(unary_expression *expression)
|
||||
{
|
||||
empty_visitor::visit(expression);
|
||||
|
||||
switch (expression->operation())
|
||||
{
|
||||
case unary_operator::reference:
|
||||
expression->data_type = std::make_shared<const pointer_type>(expression->operand().data_type,
|
||||
this->pointer_size);
|
||||
break;
|
||||
case unary_operator::dereference:
|
||||
auto operand_type = expression->operand().data_type;
|
||||
|
||||
if (auto referenced_type = std::dynamic_pointer_cast<const pointer_type>(operand_type))
|
||||
{
|
||||
expression->data_type = referenced_type;
|
||||
}
|
||||
else if (operand_type != nullptr)
|
||||
{
|
||||
auto new_error = std::make_unique<type_mismatch>(operand_type,
|
||||
type_mismatch::operation::dereference, this->filename, expression->position());
|
||||
m_errors.push_back(std::move(new_error));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const std::list<std::unique_ptr<error>>& type_analysis_visitor::errors() const noexcept
|
||||
{
|
||||
return m_errors;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,11 @@ namespace elna::source
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t type::size() const noexcept
|
||||
{
|
||||
return this->byte_size;
|
||||
}
|
||||
|
||||
primitive_type::primitive_type(const std::string& type_name, const std::size_t byte_size)
|
||||
: type(byte_size), type_name(type_name)
|
||||
{
|
||||
|
Reference in New Issue
Block a user