Rename AST types to type expressions

This commit is contained in:
2025-03-02 23:35:07 +01:00
parent 09f204bd16
commit c5930285bf
13 changed files with 462 additions and 280 deletions

View File

@ -69,12 +69,12 @@ namespace boot
class program;
class binary_expression;
class unary_expression;
class basic_type;
class array_type;
class pointer_type;
class record_type;
class union_type;
class procedure_type;
class primitive_type_expression;
class array_type_expression;
class pointer_type_expression;
class record_type_expression;
class union_type_expression;
class procedure_type_expression;
class variable_expression;
class array_access_expression;
class field_access_expression;
@ -104,16 +104,16 @@ namespace boot
virtual void visit(program *) = 0;
virtual void visit(binary_expression *) = 0;
virtual void visit(unary_expression *) = 0;
virtual void visit(basic_type *) = 0;
virtual void visit(array_type *) = 0;
virtual void visit(pointer_type *) = 0;
virtual void visit(record_type *) = 0;
virtual void visit(union_type *) = 0;
virtual void visit(procedure_type *) = 0;
virtual void visit(primitive_type_expression *) = 0;
virtual void visit(array_type_expression *) = 0;
virtual void visit(pointer_type_expression *) = 0;
virtual void visit(record_type_expression *) = 0;
virtual void visit(union_type_expression *) = 0;
virtual void visit(procedure_type_expression *) = 0;
virtual void visit(variable_expression *) = 0;
virtual void visit(array_access_expression *) = 0;
virtual void visit(field_access_expression *is_field_access) = 0;
virtual void visit(dereference_expression *is_dereference) = 0;
virtual void visit(field_access_expression *) = 0;
virtual void visit(dereference_expression *) = 0;
virtual void visit(number_literal<std::int32_t> *) = 0;
virtual void visit(number_literal<std::uint32_t> *) = 0;
virtual void visit(number_literal<double> *) = 0;
@ -129,31 +129,31 @@ namespace boot
struct empty_visitor : parser_visitor
{
virtual void visit(variable_declaration *) override;
virtual void visit(constant_definition *definition) override;
virtual void visit(procedure_definition *definition) override;
virtual void visit(type_definition *definition) override;
virtual void visit(traits_expression *trait) override;
virtual void visit(procedure_call *call) override;
virtual void visit(cast_expression *expression) override;
virtual void visit(assign_statement *statement) override;
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(assign_statement *) override;
virtual void visit(if_statement *) override;
virtual void visit(while_statement *) override;
virtual void visit(return_statement *) override;
virtual void visit(defer_statement *defer) override;
virtual void visit(block *block) override;
virtual void visit(program *program) override;
virtual void visit(binary_expression *expression) override;
virtual void visit(unary_expression *expression) override;
virtual void visit(basic_type *) override;
virtual void visit(array_type *expression) override;
virtual void visit(pointer_type *) override;
virtual void visit(record_type *expression) override;
virtual void visit(union_type *expression) override;
virtual void visit(procedure_type *expression) override;
virtual void visit(defer_statement *) override;
virtual void visit(block *) override;
virtual void visit(program *) override;
virtual void visit(binary_expression *) override;
virtual void visit(unary_expression *) override;
virtual void visit(primitive_type_expression *) override;
virtual void visit(array_type_expression *) override;
virtual void visit(pointer_type_expression *) override;
virtual void visit(record_type_expression *) override;
virtual void visit(union_type_expression *) override;
virtual void visit(procedure_type_expression *) override;
virtual void visit(variable_expression *) override;
virtual void visit(array_access_expression *expression) override;
virtual void visit(field_access_expression *expression) override;
virtual void visit(dereference_expression *expression) override;
virtual void visit(array_access_expression *) override;
virtual void visit(field_access_expression *) override;
virtual void visit(dereference_expression *) override;
virtual void visit(number_literal<std::int32_t> *) override;
virtual void visit(number_literal<std::uint32_t> *) override;
virtual void visit(number_literal<double> *) override;
@ -214,75 +214,83 @@ namespace boot
/**
* Some type expression.
*/
class top_type : public node, public std::enable_shared_from_this<top_type>
class type_expression : public node, public std::enable_shared_from_this<type_expression>
{
public:
virtual std::shared_ptr<primitive_type_expression> is_primitive();
virtual std::shared_ptr<array_type_expression> is_array();
virtual std::shared_ptr<pointer_type_expression> is_pointer();
virtual std::shared_ptr<record_type_expression> is_record();
virtual std::shared_ptr<union_type_expression> is_union();
virtual std::shared_ptr<procedure_type_expression> is_procedure();
protected:
top_type(const struct position position);
type_expression(const struct position position);
};
/**
* Expression defining a basic type.
*/
class basic_type : public top_type
class primitive_type_expression : public type_expression
{
const std::string m_name;
public:
/**
* \param position Source code position.
* \param name Type name.
*/
basic_type(const struct position position, const std::string& name);
virtual void accept(parser_visitor *visitor) override;
const std::string name;
const std::string& base_name();
primitive_type_expression(const struct position position, const std::string& name);
virtual void accept(parser_visitor *visitor) override;
std::shared_ptr<primitive_type_expression> is_primitive() override;
};
class array_type : public top_type
class array_type_expression : public type_expression
{
std::shared_ptr<top_type> m_base;
std::shared_ptr<type_expression> m_base;
public:
const std::uint32_t size;
array_type(const struct position position, std::shared_ptr<top_type> base, const std::uint32_t size);
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;
std::shared_ptr<array_type_expression> is_array() override;
top_type& base();
type_expression& base();
};
class pointer_type : public top_type
class pointer_type_expression : public type_expression
{
std::shared_ptr<top_type> m_base;
std::shared_ptr<type_expression> m_base;
public:
pointer_type(const struct position position, std::shared_ptr<top_type> base);
pointer_type_expression(const struct position position, std::shared_ptr<type_expression> base);
virtual void accept(parser_visitor *visitor) override;
std::shared_ptr<pointer_type_expression> is_pointer() override;
top_type& base();
type_expression& base();
};
using field_t = std::pair<std::string, std::shared_ptr<top_type>>;
using field_t = std::pair<std::string, std::shared_ptr<type_expression>>;
using fields_t = std::vector<field_t>;
class record_type : public top_type
class record_type_expression : public type_expression
{
public:
fields_t fields;
record_type(const struct position position, fields_t&& fields);
record_type_expression(const struct position position, fields_t&& fields);
virtual void accept(parser_visitor *visitor) override;
std::shared_ptr<record_type_expression> is_record() override;
};
class union_type : public top_type
class union_type_expression : public type_expression
{
public:
fields_t fields;
union_type(const struct position position, fields_t&& fields);
union_type_expression(const struct position position, fields_t&& fields);
virtual void accept(parser_visitor *visitor) override;
std::shared_ptr<union_type_expression> is_union() override;
};
/**
@ -290,14 +298,14 @@ namespace boot
*/
class variable_declaration : public definition
{
std::shared_ptr<top_type> m_type;
std::shared_ptr<type_expression> m_type;
public:
variable_declaration(const struct position position, const std::string& identifier,
std::shared_ptr<top_type> type, const bool exported = false);
std::shared_ptr<type_expression> type, const bool exported = false);
virtual void accept(parser_visitor *visitor) override;
top_type& variable_type();
type_expression& variable_type();
};
/**
@ -342,19 +350,21 @@ namespace boot
/**
* Procedure type.
*/
class procedure_type : public top_type
class procedure_type_expression : public type_expression
{
public:
const std::shared_ptr<top_type> return_type;
const std::shared_ptr<type_expression> return_type;
const bool no_return;
std::vector<variable_declaration *> parameters;
procedure_type(const struct position position, std::shared_ptr<top_type> return_type = nullptr);
procedure_type(const struct position position, no_return_t);
procedure_type_expression(const struct position position,
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;
std::shared_ptr<procedure_type_expression> is_procedure() override;
virtual ~procedure_type() override;
virtual ~procedure_type_expression() override;
};
/**
@ -362,16 +372,16 @@ namespace boot
*/
class procedure_definition : public definition
{
std::shared_ptr<procedure_type> m_heading;
std::shared_ptr<procedure_type_expression> m_heading;
public:
block *const body;
procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<procedure_type> heading, block *body = nullptr);
const bool exported, std::shared_ptr<procedure_type_expression> heading, block *body = nullptr);
virtual void accept(parser_visitor *visitor) override;
procedure_type& heading();
procedure_type_expression& heading();
virtual ~procedure_definition() override;
};
@ -381,14 +391,14 @@ namespace boot
*/
class type_definition : public definition
{
std::shared_ptr<top_type> m_body;
std::shared_ptr<type_expression> m_body;
public:
type_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<top_type> expression);
const bool exported, std::shared_ptr<type_expression> expression);
virtual void accept(parser_visitor *visitor) override;
top_type& body();
type_expression& body();
};
/**
@ -396,14 +406,14 @@ namespace boot
*/
class cast_expression : public expression
{
std::shared_ptr<top_type> m_target;
std::shared_ptr<type_expression> m_target;
expression *m_value;
public:
cast_expression(const struct position position, std::shared_ptr<top_type> target, expression *value);
cast_expression(const struct position position, std::shared_ptr<type_expression> target, expression *value);
virtual void accept(parser_visitor *visitor) override;
top_type& target();
type_expression& target();
expression& value();
virtual ~cast_expression() override;
@ -411,15 +421,16 @@ namespace boot
class traits_expression : public expression
{
std::shared_ptr<top_type> m_type;
std::shared_ptr<type_expression> m_type;
public:
const std::string name;
traits_expression(const struct position position, const std::string& name, std::shared_ptr<top_type> type);
traits_expression(const struct position position, const std::string& name,
std::shared_ptr<type_expression> type);
virtual void accept(parser_visitor *visitor) override;
top_type& type();
type_expression& type();
};
/**

View File

@ -0,0 +1,37 @@
/* 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,20 +26,49 @@ 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.
*/
template<typename T, T nothing>
class symbol_table
template<typename T, typename U, U nothing>
class symbol_map
{
public:
using symbol_ptr = T;
using symbol_ptr = typename std::enable_if<
std::is_convertible<U, T>::value || std::is_assignable<T, U>::value,
T
>::type;
using iterator = typename std::unordered_map<std::string, symbol_ptr>::iterator;
using const_iterator = typename std::unordered_map<std::string, symbol_ptr>::const_iterator;
private:
std::unordered_map<std::string, symbol_ptr> entries;
std::shared_ptr<symbol_table> outer_scope;
std::shared_ptr<symbol_map> outer_scope;
public:
/**
@ -47,7 +76,7 @@ namespace boot
*
* \param scope Outer scope.
*/
explicit symbol_table(std::shared_ptr<symbol_table> scope = nullptr)
explicit symbol_map(std::shared_ptr<symbol_map> scope = nullptr)
: outer_scope(scope)
{
}
@ -104,14 +133,7 @@ namespace boot
*/
bool enter(const std::string& name, symbol_ptr entry)
{
if (lookup(name) == nothing)
{
return entries.insert({ name, entry }).second;
}
else
{
return nothing;
}
return lookup(name) == nothing && entries.insert({ name, entry }).second;
}
/**
@ -119,10 +141,12 @@ namespace boot
*
* \return Outer scope.
*/
std::shared_ptr<symbol_table> scope()
std::shared_ptr<symbol_map> scope()
{
return this->outer_scope;
}
};
using symbol_table = symbol_map<std::shared_ptr<info>, std::nullptr_t, nullptr>;
}
}

View File

@ -40,7 +40,7 @@ namespace gcc
std::shared_ptr<symbol_table> symbol_map;
tree build_label_decl(const char *name, location_t loc);
tree build_procedure_type(boot::procedure_type& type);
tree build_procedure_type(boot::procedure_type_expression& type);
void enter_scope();
tree leave_scope();
@ -89,12 +89,12 @@ namespace gcc
void visit(boot::assign_statement *statement) override;
void visit(boot::if_statement *statement) override;
void visit(boot::while_statement *statement) override;
void visit(boot::basic_type *type) override;
void visit(boot::array_type *type) override;
void visit(boot::pointer_type *type) override;
void visit(boot::record_type *type) override;
void visit(boot::union_type *type) override;
void visit(boot::procedure_type *type) override;
void visit(boot::primitive_type_expression *type) override;
void visit(boot::array_type_expression *type) override;
void visit(boot::pointer_type_expression *type) override;
void visit(boot::record_type_expression *type) override;
void visit(boot::union_type_expression *type) override;
void visit(boot::procedure_type_expression *type) override;
void visit(boot::return_statement *statement) override;
void visit(boot::defer_statement *statement) override;
};

View File

@ -33,7 +33,7 @@ namespace elna
{
namespace gcc
{
using symbol_table = boot::symbol_table<tree, NULL_TREE>;
using symbol_table = boot::symbol_map<tree, tree, NULL_TREE>;
bool is_pointer_type(tree type);
bool is_integral_type(tree type);