Add semantic passes

This commit is contained in:
2024-12-23 13:54:11 +01:00
parent f080b75c52
commit 4dfbcdc1e2
16 changed files with 177 additions and 48 deletions

37
include/elna/cli/cl.hpp Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include <algorithm>
#include "elna/source/symbol_table.hpp"
#include "elna/source/result.hpp"
namespace elna
{
namespace cli
{
/**
* Formats and prints the given error.
*
* \param compile_error The error to print.
*/
void print_error(const std::unique_ptr<source::error>& compile_error);
/**
* Prints the given errors to the standard output.
*
* \param begin Pointer to the first error.
* \param end Pointer pass the last error.
*/
template<typename I>
void print_errors(I begin, I end)
{
std::for_each(begin, end, &print_error);
}
/**
* Creates a symbol table with predefined symbols.
*
* \return A symbol table with predefined symbols.
*/
std::shared_ptr<source::symbol_table> add_builtin_symbols();
}
}

View File

@ -4,7 +4,9 @@
#include "elna/source/result.hpp"
#include "elna/source/types.hpp"
namespace elna::source
namespace elna
{
namespace source
{
enum class binary_operator
{
@ -481,3 +483,4 @@ namespace elna::source
unary_operator operation() const noexcept;
};
}
}

View File

@ -4,7 +4,9 @@
#include "elna/source/ast.hpp"
#include "location.hh"
namespace elna::source
namespace elna
{
namespace source
{
position make_position(const yy::location& location);
@ -14,7 +16,7 @@ namespace elna::source
public:
syntax_error(const std::string& message,
const std::filesystem::path& input_file, const yy::location& location);
const std::experimental::filesystem::path& input_file, const yy::location& location);
virtual std::string what() const override;
};
@ -22,14 +24,15 @@ namespace elna::source
class driver
{
std::list<std::unique_ptr<struct error>> m_errors;
const std::filesystem::path input_file;
const std::experimental::filesystem::path input_file;
public:
std::unique_ptr<program> tree;
driver(const std::filesystem::path& input_file);
driver(const std::experimental::filesystem::path& input_file);
void error(const yy::location& loc, const std::string& message);
const std::list<std::unique_ptr<struct error>>& errors() const noexcept;
};
}
}

View File

@ -1,10 +1,12 @@
#pragma once
#include <cstddef>
#include <filesystem>
#include <experimental/filesystem>
#include "elna/source/types.hpp"
namespace elna::source
namespace elna
{
namespace source
{
/**
* Position in the source text.
@ -24,7 +26,7 @@ namespace elna::source
class error
{
position m_position;
std::filesystem::path m_path;
std::experimental::filesystem::path m_path;
protected:
/**
@ -33,7 +35,7 @@ namespace elna::source
* \param path Source file name.
* \param position Error position in the source text.
*/
error(const std::filesystem::path& path, const position position);
error(const std::experimental::filesystem::path& path, const position position);
public:
virtual ~error() noexcept = default;
@ -48,7 +50,7 @@ namespace elna::source
std::size_t column() const noexcept;
/// Source file name.
const std::filesystem::path& path() const noexcept;
const std::experimental::filesystem::path& path() const noexcept;
};
class name_collision final : public error
@ -63,7 +65,7 @@ namespace elna::source
* \param current Current symbol position.
* \param previous Position of the previously defined symbol.
*/
name_collision(const std::string& name, const std::filesystem::path& path,
name_collision(const std::string& name, const std::experimental::filesystem::path& path,
const position current, const position previous);
std::string what() const override;
@ -90,7 +92,7 @@ namespace elna::source
* \param path Source file name.
* \param position Operation position.
*/
type_mismatch(std::shared_ptr<const type> got, operation kind, const std::filesystem::path& path,
type_mismatch(std::shared_ptr<const type> got, operation kind, const std::experimental::filesystem::path& path,
const struct position position);
std::string what() const override;
@ -100,3 +102,4 @@ namespace elna::source
operation kind;
};
}
}

View File

@ -4,12 +4,14 @@
#include "elna/source/ast.hpp"
#include "elna/source/symbol_table.hpp"
namespace elna::source
namespace elna
{
namespace source
{
class name_analysis_visitor final : public empty_visitor
{
std::shared_ptr<symbol_table> table;
const std::filesystem::path filename;
const std::experimental::filesystem::path filename;
std::list<std::unique_ptr<error>> m_errors;
const std::size_t pointer_size;
@ -21,7 +23,7 @@ namespace elna::source
* \param path Source filename.
* \param target_pointer_size Pointer size on the target platform.
*/
name_analysis_visitor(std::shared_ptr<symbol_table> table, const std::filesystem::path& filename,
name_analysis_visitor(std::shared_ptr<symbol_table> table, const std::experimental::filesystem::path& filename,
const std::size_t target_pointer_size);
/**
@ -60,7 +62,7 @@ namespace elna::source
class type_analysis_visitor final : public empty_visitor
{
std::shared_ptr<symbol_table> table;
const std::filesystem::path filename;
const std::experimental::filesystem::path filename;
const std::size_t pointer_size;
std::list<std::unique_ptr<error>> m_errors;
@ -70,7 +72,7 @@ namespace elna::source
* \param path Source filename.
* \param target_pointer_size Pointer size on the target platform.
*/
type_analysis_visitor(std::shared_ptr<symbol_table> table, const std::filesystem::path& filename,
type_analysis_visitor(std::shared_ptr<symbol_table> table, const std::experimental::filesystem::path& filename,
const std::size_t target_pointer_size);
/**
@ -92,3 +94,4 @@ namespace elna::source
void visit(assign_statement *statement) override;
};
}
}

View File

@ -5,7 +5,9 @@
#include <string>
#include <memory>
namespace elna::source
namespace elna
{
namespace source
{
class symbol_table;
@ -159,3 +161,4 @@ namespace elna::source
std::shared_ptr<symbol_table> scope();
};
}
}

View File

@ -4,7 +4,9 @@
#include <string>
#include <vector>
namespace elna::source
namespace elna
{
namespace source
{
/**
* Type representation.
@ -94,6 +96,7 @@ namespace elna::source
bool operator==(const type& lhs, const type& rhs) noexcept;
bool operator!=(const type& lhs, const type& rhs) noexcept;
inline const primitive_type boolean_type{ "Boolean", 1 };
inline const primitive_type int_type{ "Int", 4 };
extern const primitive_type boolean_type;
extern const primitive_type int_type;
}
}