diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-11 22:33:03 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-11 22:33:03 +0200 |
| commit | 14d4977e2ab2409bb7344395ca01d19e49f130f1 (patch) | |
| tree | 5e08f1356a970b53f16ee554642eb555550d1491 /include | |
| parent | b7dd49c1d5832ac7d82edba27316884ab53e614c (diff) | |
| download | elna-14d4977e2ab2409bb7344395ca01d19e49f130f1.tar.gz | |
Implement record extension
Diffstat (limited to 'include')
| -rw-r--r-- | include/elna/boot/ast.h | 6 | ||||
| -rw-r--r-- | include/elna/boot/result.h | 5 | ||||
| -rw-r--r-- | include/elna/boot/semantic.h | 79 | ||||
| -rw-r--r-- | include/elna/boot/symbol.h | 7 |
4 files changed, 82 insertions, 15 deletions
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index 1c27166..17a0dc1 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -135,8 +135,6 @@ namespace elna::boot */ class empty_visitor : public parser_visitor { - [[noreturn]] void not_implemented(); - public: [[noreturn]] virtual void visit(array_type_expression *) override; [[noreturn]] virtual void visit(pointer_type_expression *) override; @@ -250,6 +248,8 @@ namespace elna::boot class expression : public virtual node { public: + type type_decoration; + virtual cast_expression *is_cast(); virtual traits_expression *is_traits(); virtual binary_expression *is_binary(); @@ -501,8 +501,6 @@ namespace elna::boot expression *m_value; public: - type expression_type; - cast_expression(const struct position position, type_expression *target, expression *value); void accept(parser_visitor *visitor) override; cast_expression *is_cast() override; diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h index 3a84229..1b04bfb 100644 --- a/include/elna/boot/result.h +++ b/include/elna/boot/result.h @@ -100,6 +100,11 @@ namespace elna::boot { } + bool operator==(const return_declaration& other) const + { + return this->proper_type == other.proper_type && this->no_return == other.no_return; + } + T proper_type{}; bool no_return{ false }; }; diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h index 9d79b14..e351258 100644 --- a/include/elna/boot/semantic.h +++ b/include/elna/boot/semantic.h @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include <string> #include <unordered_map> #include <memory> +#include <set> #include <deque> #include "elna/boot/ast.h" @@ -29,29 +30,47 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { /** - * Undeclared identifier. + * Error declaring a symbol. */ - class undeclared_error : public error + class declaration_error : public error { const std::string identifier; public: - undeclared_error(const std::string& identifier, const struct position position); + enum class kind + { + undeclared, + already + }; + + declaration_error(const kind error_kind, + const std::string& identifier, const struct position position); std::string what() const override; + + private: + const kind error_kind; }; /** * A symbol was already declared in this scope. */ - class already_declared_error : public error + class type_expectation_error : public error { - const std::string identifier; - public: - already_declared_error(const std::string& identifier, const struct position position); + enum class kind + { + assignment, + result, + argument + }; + + type_expectation_error(const kind error_kind, const struct position position); std::string what() const override; + + private: + const kind error_kind; }; /** @@ -107,23 +126,47 @@ namespace elna::boot }; /** + * Argument count in a procedure or record call doesn't match + * the expected number of parameters or fields. + */ + class argument_count_error : public error + { + const std::size_t expected; + const std::size_t actual; + + public: + argument_count_error(std::size_t expected, std::size_t actual, + const struct position position); + + std::string what() const override; + }; + + /** * Checks types. */ class type_analysis_visitor final : public walking_visitor, public error_container { bool returns; symbol_bag bag; + std::shared_ptr<procedure_info> current_procedure; bool check_unresolved_symbol(std::shared_ptr<alias_type> alias, std::vector<std::string>& path); + std::size_t match_record_fields(const std::shared_ptr<record_type>& record, + std::vector<expression *>::const_iterator& argument_it, + const std::vector<expression *>::const_iterator& argument_end); public: explicit type_analysis_visitor(symbol_bag bag); void visit(procedure_declaration *declaration) override; void visit(return_statement *statement) override; + void visit(assign_statement *statement) override; + void visit(variable_declaration *declaration) override; void visit(type_declaration *declaration) override; void visit(record_type_expression *expression) override; + void visit(procedure_call *call) override; + void visit(case_statement *statement) override; }; /** @@ -138,10 +181,15 @@ namespace elna::boot std::pair<procedure_type, std::vector<std::string>> build_procedure( procedure_type_expression& expression); - std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields); + std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields, + std::set<std::string>& known_names); std::shared_ptr<variable_info> register_variable(const std::string& name, const bool is_extern, const struct position position); + type lookup_primitive_type(const std::string& name); + type type_of_constant(const constant_info::variant& value); + type lookup_field(const type& composite_type, const std::string& field_name); + public: name_analysis_visitor(symbol_bag bag); @@ -161,7 +209,12 @@ namespace elna::boot void visit(unit *unit) override; void visit(cast_expression *expression) override; void visit(traits_expression *trait) override; + void visit(binary_expression *expression) override; + void visit(unary_expression *expression) override; void visit(named_expression *expression) override; + void visit(array_access_expression *expression) override; + void visit(field_access_expression *expression) override; + void visit(dereference_expression *expression) override; void visit(literal<std::int32_t> *literal) override; void visit(literal<std::uint32_t> *literal) override; void visit(literal<double> *literal) override; @@ -185,4 +238,14 @@ namespace elna::boot void visit(unit *unit) override; void visit(type_declaration *declaration) override; }; + + /** + * Whether an expression of type \a assignment can be assigned to a variable + * of type \a assignee. + * + * \param assignee Assignee. + * \param assignment Assignment. + * \return Whether the assignment can be performed. + */ + bool is_assignable_from(const type& assignee, const type& assignment); } diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index 6258760..85532db 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -84,13 +84,14 @@ namespace elna::boot type(type&& other); type& operator=(type&& other); - bool operator==(const std::nullptr_t&); - ~type(); template<typename T> std::shared_ptr<T> get() const; + bool operator==(const std::nullptr_t&) const; + bool operator==(const type& other) const; + bool empty() const; }; @@ -466,6 +467,6 @@ namespace elna::boot * \param alias The type to lookup the innermost declaration for. * \return Innermost type declaration. */ - type inner_aliased_type(type alias); + type inner_aliased_type(const type& alias); type inner_aliased_type(std::shared_ptr<alias_type> alias); } |
