Implement pointers
This commit is contained in:
@ -39,11 +39,14 @@ namespace gcc
|
||||
void visit(source::char_literal *character) override;
|
||||
void visit(source::string_literal *string) override;
|
||||
void visit(source::binary_expression *expression) override;
|
||||
void visit(source::unary_expression *expression) override;
|
||||
void visit(source::constant_definition *definition) override;
|
||||
void visit(source::type_definition *definition) override;
|
||||
void visit(source::declaration *declaration) override;
|
||||
void visit(source::variable_expression *expression) override;
|
||||
void visit(source::array_access_expression *expression) override;
|
||||
void visit(source::field_access_expression *expression) override;
|
||||
void visit(source::dereference_expression *expression) override;
|
||||
void visit(source::assign_statement *statement) override;
|
||||
void visit(source::if_statement *statement) override;
|
||||
void visit(source::while_statement *statement) override;
|
||||
|
@ -23,6 +23,7 @@ namespace elna
|
||||
namespace gcc
|
||||
{
|
||||
void init_ttree();
|
||||
bool is_pointer_type(tree type);
|
||||
bool is_string_type(tree type);
|
||||
bool is_array_type(tree type);
|
||||
bool is_record_type(tree type);
|
||||
|
@ -30,8 +30,7 @@ namespace source
|
||||
|
||||
enum class unary_operator
|
||||
{
|
||||
reference,
|
||||
dereference
|
||||
reference
|
||||
};
|
||||
|
||||
class declaration;
|
||||
@ -117,8 +116,8 @@ namespace source
|
||||
virtual void visit(record_type_expression *expression) override;
|
||||
virtual void visit(variable_expression *) override;
|
||||
virtual void visit(array_access_expression *expression) override;
|
||||
virtual void visit(field_access_expression *is_field_access) override;
|
||||
virtual void visit(dereference_expression *is_dereference) override;
|
||||
virtual void visit(field_access_expression *expression) override;
|
||||
virtual void visit(dereference_expression *expression) override;
|
||||
virtual void visit(number_literal<std::int32_t> *) override;
|
||||
virtual void visit(number_literal<double> *) override;
|
||||
virtual void visit(number_literal<bool> *) override;
|
||||
@ -249,7 +248,6 @@ namespace source
|
||||
class type_expression : public node
|
||||
{
|
||||
public:
|
||||
virtual const std::string& base_name() = 0;
|
||||
virtual basic_type_expression *is_basic();
|
||||
virtual array_type_expression *is_array();
|
||||
virtual pointer_type_expression *is_pointer();
|
||||
@ -262,7 +260,7 @@ namespace source
|
||||
/**
|
||||
* Expression defining a basic type.
|
||||
*/
|
||||
class basic_type_expression : public type_expression
|
||||
class basic_type_expression final : public type_expression
|
||||
{
|
||||
const std::string m_name;
|
||||
|
||||
@ -274,12 +272,12 @@ namespace source
|
||||
basic_type_expression(const struct position position, const std::string& name);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
const std::string& base_name() override;
|
||||
const std::string& base_name();
|
||||
|
||||
basic_type_expression *is_basic() override;
|
||||
};
|
||||
|
||||
class array_type_expression : public type_expression
|
||||
class array_type_expression final : public type_expression
|
||||
{
|
||||
type_expression *m_base;
|
||||
|
||||
@ -290,14 +288,13 @@ namespace source
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
type_expression& base();
|
||||
const std::string& base_name() override;
|
||||
|
||||
array_type_expression *is_array() override;
|
||||
|
||||
virtual ~array_type_expression() override;
|
||||
};
|
||||
|
||||
class pointer_type_expression : public type_expression
|
||||
class pointer_type_expression final : public type_expression
|
||||
{
|
||||
type_expression *m_base;
|
||||
|
||||
@ -306,14 +303,13 @@ namespace source
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
type_expression& base();
|
||||
const std::string& base_name() override;
|
||||
|
||||
pointer_type_expression *is_pointer() override;
|
||||
|
||||
virtual ~pointer_type_expression() override;
|
||||
};
|
||||
|
||||
class record_type_expression : public type_expression
|
||||
class record_type_expression final : public type_expression
|
||||
{
|
||||
public:
|
||||
using field_t = std::pair<std::string, type_expression *>;
|
||||
@ -326,6 +322,8 @@ namespace source
|
||||
|
||||
record_type_expression *is_record() override;
|
||||
|
||||
virtual ~record_type_expression() override;
|
||||
|
||||
private:
|
||||
fields_t m_fields;
|
||||
};
|
||||
|
@ -1,100 +0,0 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include "elna/source/ast.h"
|
||||
#include "elna/source/symbol_table.h"
|
||||
|
||||
namespace elna
|
||||
{
|
||||
namespace source
|
||||
{
|
||||
class name_analysis_visitor final : public empty_visitor
|
||||
{
|
||||
std::shared_ptr<symbol_table> table;
|
||||
const char *filename;
|
||||
std::list<std::unique_ptr<error>> m_errors;
|
||||
const std::size_t pointer_size;
|
||||
|
||||
std::shared_ptr<const type> convert_declaration_type(const type_expression& ast_type) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \param table Symbol table.
|
||||
* \param path Source filename.
|
||||
* \param target_pointer_size Pointer size on the target platform.
|
||||
*/
|
||||
name_analysis_visitor(std::shared_ptr<symbol_table> table, const char *filename,
|
||||
const std::size_t target_pointer_size);
|
||||
|
||||
/**
|
||||
* \return Collected errors.
|
||||
*/
|
||||
const std::list<std::unique_ptr<error>>& errors() const noexcept;
|
||||
|
||||
void visit(constant_definition *definition) override;
|
||||
void visit(declaration *declaration) override;
|
||||
void visit(program *program) override;
|
||||
void visit(procedure_definition *procedure) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Visitor which allocates registers and stack space for variables and
|
||||
* parameters.
|
||||
*/
|
||||
class allocator_visitor final : public empty_visitor
|
||||
{
|
||||
std::ptrdiff_t local_offset;
|
||||
std::ptrdiff_t argument_offset;
|
||||
std::shared_ptr<symbol_table> table;
|
||||
|
||||
public:
|
||||
allocator_visitor(std::shared_ptr<symbol_table> table);
|
||||
|
||||
void visit(declaration *declaration) override;
|
||||
void visit(program *program) override;
|
||||
void visit(procedure_definition *procedure) override;
|
||||
void visit(call_statement *statement) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* This visitor performs the type checking.
|
||||
*/
|
||||
class type_analysis_visitor final : public empty_visitor
|
||||
{
|
||||
std::shared_ptr<symbol_table> table;
|
||||
const char *filename;
|
||||
const std::size_t pointer_size;
|
||||
std::list<std::unique_ptr<error>> m_errors;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \param table Symbol table.
|
||||
* \param path Source filename.
|
||||
* \param target_pointer_size Pointer size on the target platform.
|
||||
*/
|
||||
type_analysis_visitor(std::shared_ptr<symbol_table> table, const char *filename,
|
||||
const std::size_t target_pointer_size);
|
||||
|
||||
/**
|
||||
* \return Collected errors.
|
||||
*/
|
||||
const std::list<std::unique_ptr<error>>& errors() const noexcept;
|
||||
|
||||
void visit(program *program) override;
|
||||
void visit(procedure_definition *procedure) override;
|
||||
void visit(integer_literal *literal) override;
|
||||
void visit(boolean_literal *literal) override;
|
||||
void visit(variable_expression *expression) override;
|
||||
void visit(unary_expression *expression) override;
|
||||
void visit(binary_expression *expression) override;
|
||||
void visit(call_statement *statement) override;
|
||||
void visit(constant_definition *definition) override;
|
||||
void visit(while_statement *statement) override;
|
||||
void visit(if_statement *statement) override;
|
||||
void visit(assign_statement *statement) override;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,198 +0,0 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace elna
|
||||
{
|
||||
namespace source
|
||||
{
|
||||
class symbol_table;
|
||||
class type_info;
|
||||
class typed_info;
|
||||
class constant_info;
|
||||
class variable_info;
|
||||
class parameter_info;
|
||||
class intrinsic_info;
|
||||
class procedure_info;
|
||||
|
||||
/**
|
||||
* Generic language entity information.
|
||||
*/
|
||||
class info
|
||||
{
|
||||
public:
|
||||
virtual ~info() = 0;
|
||||
|
||||
virtual type_info *is_type_info() noexcept;
|
||||
virtual typed_info *is_typed_info() noexcept;
|
||||
virtual constant_info *is_constant_info() noexcept;
|
||||
virtual variable_info *is_variable_info() noexcept;
|
||||
virtual parameter_info *is_parameter_info() noexcept;
|
||||
virtual intrinsic_info *is_intrinsic_info() noexcept;
|
||||
virtual procedure_info *is_procedure_info() noexcept;
|
||||
|
||||
protected:
|
||||
info();
|
||||
};
|
||||
|
||||
/**
|
||||
* Type information.
|
||||
*/
|
||||
class type_info final : public info
|
||||
{
|
||||
std::shared_ptr<const class type> m_type;
|
||||
|
||||
public:
|
||||
explicit type_info(std::shared_ptr<class type> type);
|
||||
~type_info() override;
|
||||
|
||||
virtual type_info *is_type_info() noexcept override;
|
||||
std::shared_ptr<const class type> type() const noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
* Information for a typed symbol.
|
||||
*/
|
||||
class typed_info : public info
|
||||
{
|
||||
std::shared_ptr<const class type> m_type;
|
||||
|
||||
protected:
|
||||
typed_info(std::shared_ptr<const class type> type);
|
||||
|
||||
public:
|
||||
~typed_info() override;
|
||||
|
||||
virtual typed_info *is_typed_info() noexcept override;
|
||||
std::shared_ptr<const class type> type() const noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constant information.
|
||||
*/
|
||||
class constant_info final : public typed_info
|
||||
{
|
||||
std::int32_t m_value;
|
||||
|
||||
public:
|
||||
constant_info(std::shared_ptr<const class type> type, const std::int32_t value);
|
||||
|
||||
virtual constant_info *is_constant_info() noexcept override;
|
||||
std::int32_t value() const noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable information.
|
||||
*/
|
||||
class variable_info final : public typed_info
|
||||
{
|
||||
public:
|
||||
std::ptrdiff_t offset{ 0 };
|
||||
|
||||
explicit variable_info(std::shared_ptr<const class type> type);
|
||||
|
||||
virtual variable_info *is_variable_info() noexcept override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Procedure parameter information.
|
||||
*/
|
||||
class parameter_info final : public typed_info
|
||||
{
|
||||
public:
|
||||
std::ptrdiff_t offset{ 0 };
|
||||
|
||||
explicit parameter_info(std::shared_ptr<const class type> type);
|
||||
|
||||
virtual parameter_info *is_parameter_info() noexcept override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Intrinsic and external procedure information.
|
||||
*/
|
||||
class intrinsic_info : public info
|
||||
{
|
||||
std::shared_ptr<const class procedure_type> m_type;
|
||||
|
||||
public:
|
||||
explicit intrinsic_info(const class procedure_type& type);
|
||||
~intrinsic_info() override;
|
||||
|
||||
std::shared_ptr<const class procedure_type> type() const noexcept;
|
||||
std::size_t parameter_stack_size() const noexcept;
|
||||
virtual intrinsic_info *is_intrinsic_info() noexcept override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Procedure information.
|
||||
*/
|
||||
class procedure_info final : public intrinsic_info
|
||||
{
|
||||
std::shared_ptr<symbol_table> local_table;
|
||||
|
||||
public:
|
||||
std::size_t local_stack_size{ 0 };
|
||||
std::size_t argument_stack_size{ 0 };
|
||||
|
||||
procedure_info(const class procedure_type& type, std::shared_ptr<symbol_table> outer_scope);
|
||||
~procedure_info() override;
|
||||
|
||||
std::shared_ptr<symbol_table> scope();
|
||||
std::size_t stack_size() const noexcept;
|
||||
virtual procedure_info *is_procedure_info() noexcept override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Symbol table.
|
||||
*/
|
||||
class symbol_table
|
||||
{
|
||||
std::unordered_map<std::string, std::shared_ptr<info>> entries;
|
||||
std::shared_ptr<symbol_table> outer_scope;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a new symbol with an optional outer scope.
|
||||
*
|
||||
* \param scope Outer scope.
|
||||
*/
|
||||
explicit symbol_table(std::shared_ptr<symbol_table> scope = nullptr);
|
||||
|
||||
/**
|
||||
* Looks for symbol in the table by name. Returns nullptr if the symbol
|
||||
* can not be found.
|
||||
*
|
||||
* \param name Symbol name.
|
||||
* \return Symbol from the table if found.
|
||||
*/
|
||||
std::shared_ptr<info> lookup(const std::string& name);
|
||||
|
||||
/**
|
||||
* Registers new symbol.
|
||||
*
|
||||
* \param name Symbol name.
|
||||
* \param entry Symbol information.
|
||||
*/
|
||||
void enter(const std::string& name, std::shared_ptr<info> entry);
|
||||
|
||||
/**
|
||||
* Returns the outer scope or nullptr if the this is the global scope.
|
||||
*
|
||||
* \return Outer scope.
|
||||
*/
|
||||
std::shared_ptr<symbol_table> scope();
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a symbol table with predefined symbols.
|
||||
*
|
||||
* \return A symbol table with predefined symbols.
|
||||
*/
|
||||
std::shared_ptr<source::symbol_table> add_builtin_symbols();}
|
||||
}
|
Reference in New Issue
Block a user