Add second GENERIC visitor

This commit is contained in:
2025-03-04 22:56:32 +01:00
parent c5930285bf
commit 8dc02047df
12 changed files with 572 additions and 341 deletions

View File

@ -79,6 +79,8 @@ namespace boot
class array_access_expression;
class field_access_expression;
class dereference_expression;
class designator_expression;
class literal;
template<typename T>
class number_literal;
class defer_statement;
@ -132,9 +134,9 @@ namespace boot
virtual void visit(constant_definition *) override;
virtual void visit(procedure_definition *) override;
virtual void visit(type_definition *) override;
virtual void visit(traits_expression *) override;
virtual void visit(procedure_call *) override;
virtual void visit(cast_expression *) override;
virtual void visit(traits_expression *) override;
virtual void visit(assign_statement *) override;
virtual void visit(if_statement *) override;
virtual void visit(while_statement *) override;
@ -177,8 +179,7 @@ namespace boot
explicit node(const position position);
public:
virtual ~node() = default;
virtual void accept(parser_visitor *) = 0;
virtual ~node() = 0;
/**
* \return Node position in the source code.
@ -188,12 +189,35 @@ namespace boot
class statement : public virtual node
{
public:
virtual assign_statement *is_assign();
virtual if_statement *is_if();
virtual while_statement *is_while();
virtual return_statement *is_return();
virtual defer_statement *is_defer();
virtual procedure_call *is_call_statement();
void accept(parser_visitor *visitor);
~statement() = 0;
protected:
statement();
};
class expression : public virtual node
{
public:
virtual cast_expression *is_cast();
virtual traits_expression *is_traits();
virtual binary_expression *is_binary();
virtual unary_expression *is_unary();
virtual designator_expression *is_designator();
virtual procedure_call *is_call_expression();
virtual literal *is_literal();
void accept(parser_visitor *visitor);
~expression() = 0;
protected:
expression();
};
@ -224,6 +248,8 @@ namespace boot
virtual std::shared_ptr<union_type_expression> is_union();
virtual std::shared_ptr<procedure_type_expression> is_procedure();
void accept(parser_visitor *visitor);
protected:
type_expression(const struct position position);
};
@ -237,7 +263,7 @@ namespace boot
const std::string name;
primitive_type_expression(const struct position position, const std::string& name);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
std::shared_ptr<primitive_type_expression> is_primitive() override;
};
@ -250,7 +276,7 @@ namespace boot
array_type_expression(const struct position position,
std::shared_ptr<type_expression> base, const std::uint32_t size);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
std::shared_ptr<array_type_expression> is_array() override;
type_expression& base();
@ -262,7 +288,7 @@ namespace boot
public:
pointer_type_expression(const struct position position, std::shared_ptr<type_expression> base);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
std::shared_ptr<pointer_type_expression> is_pointer() override;
type_expression& base();
@ -278,7 +304,7 @@ namespace boot
record_type_expression(const struct position position, fields_t&& fields);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
std::shared_ptr<record_type_expression> is_record() override;
};
@ -289,7 +315,7 @@ namespace boot
union_type_expression(const struct position position, fields_t&& fields);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
std::shared_ptr<union_type_expression> is_union() override;
};
@ -303,7 +329,7 @@ namespace boot
public:
variable_declaration(const struct position position, const std::string& identifier,
std::shared_ptr<type_expression> type, const bool exported = false);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
type_expression& variable_type();
};
@ -313,6 +339,18 @@ namespace boot
*/
class literal : public expression
{
public:
virtual number_literal<std::int32_t> *is_int() = 0;
virtual number_literal<std::uint32_t> *is_word() = 0;
virtual number_literal<double> *is_float() = 0;
virtual number_literal<bool> *is_bool() = 0;
virtual number_literal<unsigned char> *is_char() = 0;
virtual number_literal<std::nullptr_t> *is_nil() = 0;
virtual number_literal<std::string> *is_string() = 0;
literal *is_literal() override;
void accept(parser_visitor *visitor);
protected:
literal();
};
@ -332,7 +370,7 @@ namespace boot
*/
constant_definition(const struct position position, const std::string& identifier,
const bool exported, literal *body);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
literal& body();
@ -361,7 +399,7 @@ namespace boot
std::shared_ptr<type_expression> return_type = nullptr);
procedure_type_expression(const struct position position, no_return_t);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
std::shared_ptr<procedure_type_expression> is_procedure() override;
virtual ~procedure_type_expression() override;
@ -379,7 +417,7 @@ namespace boot
procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<procedure_type_expression> heading, block *body = nullptr);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
procedure_type_expression& heading();
@ -396,7 +434,7 @@ namespace boot
public:
type_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<type_expression> expression);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
type_expression& body();
};
@ -411,7 +449,8 @@ namespace boot
public:
cast_expression(const struct position position, std::shared_ptr<type_expression> target, expression *value);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
cast_expression *is_cast() override;
type_expression& target();
expression& value();
@ -428,7 +467,8 @@ namespace boot
traits_expression(const struct position position, const std::string& name,
std::shared_ptr<type_expression> type);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
traits_expression *is_traits() override;
type_expression& type();
};
@ -456,7 +496,8 @@ namespace boot
public:
return_statement(const struct position position, expression *return_expression);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
virtual return_statement *is_return() override;
expression *return_expression();
@ -471,6 +512,10 @@ namespace boot
virtual field_access_expression *is_field_access();
virtual dereference_expression *is_dereference();
designator_expression *is_designator() override;
void accept(parser_visitor *visitor);
~designator_expression() = 0;
protected:
designator_expression();
};
@ -481,7 +526,7 @@ namespace boot
const std::string name;
variable_expression(const struct position position, const std::string& name);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
variable_expression *is_variable() override;
};
@ -493,7 +538,7 @@ namespace boot
public:
array_access_expression(const struct position position, expression *base, expression *index);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
expression& base();
expression& index();
@ -511,7 +556,7 @@ namespace boot
public:
field_access_expression(const struct position position, expression *base,
const std::string& field);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
expression& base();
std::string& field();
@ -527,7 +572,7 @@ namespace boot
public:
dereference_expression(const struct position position, expression *base);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
expression& base();
@ -547,7 +592,9 @@ namespace boot
std::vector<expression *> arguments;
procedure_call(const struct position position, designator_expression *callable);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
virtual procedure_call *is_call_statement() override;
virtual procedure_call *is_call_expression() override;
designator_expression& callable();
@ -567,12 +614,13 @@ namespace boot
*/
assign_statement(const struct position position, designator_expression *lvalue,
expression *rvalue);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
designator_expression& lvalue();
expression& rvalue();
virtual ~assign_statement() override;
assign_statement *is_assign() override;
};
/**
@ -588,7 +636,8 @@ namespace boot
if_statement(const struct position position, conditional_statements *body,
std::vector<statement *> *alternative = nullptr);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
virtual if_statement *is_if() override;
conditional_statements& body();
std::vector<statement *> *alternative();
@ -606,7 +655,8 @@ namespace boot
public:
std::vector<conditional_statements *> branches;
while_statement(const struct position position, conditional_statements *body);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
while_statement *is_while() override;
conditional_statements& body();
@ -621,7 +671,7 @@ namespace boot
std::vector<statement *> body;
block(const struct position position);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
virtual ~block() override;
};
@ -633,7 +683,7 @@ namespace boot
std::vector<procedure_definition *> procedures;
program(const struct position position);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
virtual ~program() override;
};
@ -649,7 +699,91 @@ namespace boot
{
}
virtual void accept(parser_visitor *visitor) override
number_literal<std::int32_t> *is_int() override
{
if (std::is_same<T, std::int32_t>::value)
{
return reinterpret_cast<number_literal<std::int32_t> *>(this);
}
else
{
return nullptr;
}
}
number_literal<std::uint32_t> *is_word() override
{
if (std::is_same<T, std::uint32_t>::value)
{
return reinterpret_cast<number_literal<std::uint32_t> *>(this);
}
else
{
return nullptr;
}
}
number_literal<double> *is_float() override
{
if (std::is_same<T, double>::value)
{
return reinterpret_cast<number_literal<double> *>(this);
}
else
{
return nullptr;
}
}
number_literal<bool> *is_bool() override
{
if (std::is_same<T, bool>::value)
{
return reinterpret_cast<number_literal<bool> *>(this);
}
else
{
return nullptr;
}
}
number_literal<unsigned char> *is_char() override
{
if (std::is_same<T, unsigned char>::value)
{
return reinterpret_cast<number_literal<unsigned char> *>(this);
}
else
{
return nullptr;
}
}
number_literal<std::nullptr_t> *is_nil() override
{
if (std::is_same<T, std::nullptr_t>::value)
{
return reinterpret_cast<number_literal<std::nullptr_t> *>(this);
}
else
{
return nullptr;
}
}
number_literal<std::string> *is_string() override
{
if (std::is_same<T, std::string>::value)
{
return reinterpret_cast<number_literal<std::string> *>(this);
}
else
{
return nullptr;
}
}
void accept(parser_visitor *visitor)
{
visitor->visit(this);
}
@ -661,7 +795,8 @@ namespace boot
std::vector<statement *> statements;
defer_statement(const struct position position);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
defer_statement *is_defer() override;
virtual ~defer_statement() override;
};
@ -676,7 +811,9 @@ namespace boot
binary_expression(const struct position position, expression *lhs,
expression *rhs, const binary_operator operation);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
binary_expression *is_binary() override;
expression& lhs();
expression& rhs();
binary_operator operation() const;
@ -693,7 +830,9 @@ namespace boot
unary_expression(const struct position position, expression *operand,
const unary_operator operation);
virtual void accept(parser_visitor *visitor) override;
void accept(parser_visitor *visitor);
unary_expression *is_unary() override;
expression& operand();
unary_operator operation() const;

View File

@ -1,37 +0,0 @@
/* Semantic analysis visitors.
Copyright (C) 2025 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#pragma once
#include "elna/boot/ast.h"
#include "elna/boot/symbol.h"
namespace elna
{
namespace boot
{
class declaration_visitor : public empty_visitor
{
std::shared_ptr<symbol_table> table;
public:
declaration_visitor(std::shared_ptr<symbol_table> table);
void visit(program *program) override;
};
}
}

View File

@ -26,32 +26,6 @@ namespace elna
{
namespace boot
{
class info
{
public:
virtual ~info() = 0;
protected:
info() = default;
};
class type
{
public:
virtual ~type() = 0;
protected:
type() = default;
};
class type_info : public info, public type
{
public:
const std::string name;
type_info(const std::string& name);
};
/**
* Symbol table.
*/
@ -146,7 +120,5 @@ namespace boot
return this->outer_scope;
}
};
using symbol_table = symbol_map<std::shared_ptr<info>, std::nullptr_t, nullptr>;
}
}

View File

@ -27,17 +27,39 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "tree-iterator.h"
#include <forward_list>
#include <unordered_map>
#include <string>
namespace elna
{
namespace gcc
{
struct type
{
type() {}
type(tree resolved): resolved(resolved) {}
type(std::shared_ptr<type> reference): reference(reference) {}
tree resolved{ NULL_TREE };
std::shared_ptr<type> reference;
};
class declaration_visitor final : public boot::empty_visitor
{
std::shared_ptr<symbol_table> symbols;
std::unordered_map<std::string, std::shared_ptr<type>> unresolved;
public:
declaration_visitor(std::shared_ptr<symbol_table> symbol_table);
void visit(boot::program *program) override;
void visit(boot::type_definition *definition) override;
};
class generic_visitor final : public boot::empty_visitor
{
tree current_expression{ NULL_TREE };
std::shared_ptr<symbol_table> symbol_map;
std::shared_ptr<symbol_table> symbols;
tree build_label_decl(const char *name, location_t loc);
tree build_procedure_type(boot::procedure_type_expression& type);