aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/elna/boot/ast.h20
-rw-r--r--include/elna/boot/name_analysis.h53
-rw-r--r--include/elna/boot/type_check.h65
-rw-r--r--include/elna/gcc/elna-generic.h8
-rw-r--r--include/elna/gcc/elna-tree.h18
-rw-r--r--include/elna/gcc/elna1.h7
6 files changed, 90 insertions, 81 deletions
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h
index 9cc1419..6080155 100644
--- a/include/elna/boot/ast.h
+++ b/include/elna/boot/ast.h
@@ -43,6 +43,12 @@ namespace elna::boot
disjunction,
conjunction,
exclusive_disjunction,
+ logical_conjunction,
+ logical_disjunction,
+ logical_exclusive_disjunction,
+ bitwise_conjunction,
+ bitwise_disjunction,
+ bitwise_exclusive_disjunction,
shift_left,
shift_right
};
@@ -51,6 +57,8 @@ namespace elna::boot
{
reference,
negation,
+ bitwise_negation,
+ logical_negation,
minus,
plus
};
@@ -638,18 +646,18 @@ namespace elna::boot
class slicing_expression : public designator_expression
{
expression *m_base;
- expression *m_offset;
- expression *m_length;
+ expression *m_start;
+ expression *m_end;
public:
slicing_expression(const source_position position,
- expression *base, expression *offset, expression *length);
+ expression *base, expression *start, expression *end);
void accept(parser_visitor *visitor) override;
slicing_expression *is_slicing() override;
expression& base();
- expression& offset();
- expression& length();
+ expression& start();
+ expression& end();
~slicing_expression() override;
};
@@ -882,6 +890,7 @@ namespace elna::boot
expression& lhs();
expression& rhs();
binary_operator operation() const;
+ void operation(binary_operator operation);
~binary_expression() override;
};
@@ -900,6 +909,7 @@ namespace elna::boot
expression& operand();
unary_operator operation() const;
+ void operation(unary_operator operation);
~unary_expression() override;
};
diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h
index bb66c7a..5afe102 100644
--- a/include/elna/boot/name_analysis.h
+++ b/include/elna/boot/name_analysis.h
@@ -20,11 +20,11 @@ along with GCC; see the file COPYING3. If not see
#include <string>
#include <memory>
#include <map>
+#include <optional>
#include "elna/boot/ast.h"
#include "elna/boot/result.h"
#include "elna/boot/symbol.h"
-#include "elna/boot/type_check.h"
namespace elna::boot
{
@@ -93,6 +93,55 @@ namespace elna::boot
};
/**
+ * Access to a field that does not exist in the given type.
+ */
+ class field_not_found_error : public error
+ {
+ std::string field_name;
+ type composite_type;
+
+ public:
+ field_not_found_error(const identifier& field_name,
+ type composite_type);
+
+ std::string what() const override;
+ };
+
+ /**
+ * Field with the same name is already declared in this type.
+ */
+ class duplicate_member_error : public error
+ {
+ std::string member_name;
+ type aggregate;
+ std::optional<source_position> original;
+ std::optional<std::string> base_name;
+
+ public:
+ duplicate_member_error(const boot::identifier& member_name,
+ type aggregate, std::optional<source_position> original = std::nullopt,
+ std::optional<std::string> base_name = std::nullopt);
+
+ std::string what() const override;
+
+ std::optional<std::pair<std::string, source_position>> note() const override;
+ };
+
+ /**
+ * Trait is not applicable to the given type.
+ */
+ class unsupported_trait_type_error : public error
+ {
+ type actual;
+ std::string trait_name;
+
+ public:
+ unsupported_trait_type_error(const identifier& trait, type actual);
+
+ std::string what() const override;
+ };
+
+ /**
* Origin of a field in a composite type.
*/
struct field_origin
@@ -120,6 +169,8 @@ namespace elna::boot
type lookup_primitive_type(const std::string& name);
type lookup_field(const type& composite_type, const std::string& field_name);
+ std::optional<type> lookup_pointer_like_field(const std::string& field_name,
+ const type& element_type);
public:
name_analysis_visitor(symbol_bag bag);
diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h
index 32da10c..1680077 100644
--- a/include/elna/boot/type_check.h
+++ b/include/elna/boot/type_check.h
@@ -59,38 +59,6 @@ namespace elna::boot
/**
* Attempted to access a field that does not exist on the given type.
*/
- class field_not_found_error : public error
- {
- std::string field_name;
- type composite_type;
-
- public:
- field_not_found_error(const identifier& field_name,
- type composite_type);
-
- std::string what() const override;
- };
-
- /**
- * Field with the same name is already declared in this type.
- */
- class duplicate_member_error : public error
- {
- std::string member_name;
- type aggregate;
- std::optional<source_position> original;
- std::optional<std::string> base_name;
-
- public:
- duplicate_member_error(const boot::identifier& member_name,
- type aggregate, std::optional<source_position> original = std::nullopt,
- std::optional<std::string> base_name = std::nullopt);
-
- std::string what() const override;
-
- std::optional<std::pair<std::string, source_position>> note() const override;
- };
-
/**
* Cyclic type declaration.
*/
@@ -133,8 +101,8 @@ namespace elna::boot
};
/**
- * Argument count in a procedure or record call doesn't match
- * the expected number of parameters or fields.
+ * Argument count in a procedure call or array constructor doesn't match
+ * the expected number of parameters or elements.
*/
class argument_count_error : public error
{
@@ -152,17 +120,6 @@ namespace elna::boot
* Type passed to a trait like #min or #max does not support
* the trait.
*/
- class unsupported_trait_type_error : public error
- {
- type actual;
- std::string trait_name;
-
- public:
- unsupported_trait_type_error(const identifier& trait, type actual);
-
- std::string what() const override;
- };
-
/**
* A module-level variable initializer must be a constant expression.
*/
@@ -192,6 +149,22 @@ namespace elna::boot
};
/**
+ * A binary operator is applied to unsupported types.
+ */
+ class binary_operation_error : public error
+ {
+ type left;
+ type right;
+ binary_operator op;
+
+ public:
+ binary_operation_error(const source_position position,
+ type left, type right, binary_operator operation);
+
+ std::string what() const override;
+ };
+
+ /**
* Chain of responsibility for type compatibility checks.
*
* Populate \c ctx with pre-resolved types, then call \c run().
@@ -220,6 +193,7 @@ namespace elna::boot
verdict check_exact_match() const;
verdict check_pointer_hatch() const;
verdict check_pointer_conversion() const;
+ verdict check_slice_conversion() const;
bool run();
};
@@ -261,5 +235,6 @@ namespace elna::boot
void visit(array_constructor_expression *expression) override;
void visit(slicing_expression *expression) override;
void visit(unary_expression *expression) override;
+ void visit(binary_expression *expression) override;
};
}
diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h
index 1d98675..04b91fb 100644
--- a/include/elna/gcc/elna-generic.h
+++ b/include/elna/gcc/elna-generic.h
@@ -45,14 +45,12 @@ namespace elna::gcc
void enter_scope();
tree leave_scope();
+ void begin_function(tree fndecl);
+ void finish_function(tree fndecl);
+
tree make_if_branch(boot::conditional_statements& branch, tree next,
tree goto_append = NULL_TREE);
- tree build_arithmetic_operation(boot::binary_expression *expression,
- tree_code operator_code, tree left, tree right);
- tree build_comparison_operation(boot::binary_expression *expression,
- tree_code operator_code, tree left, tree right);
- tree build_bit_logic_operation(boot::binary_expression *expression, tree left, tree right);
tree build_equality_operation(boot::binary_expression *expression, tree left, tree right);
void build_procedure_call(location_t call_location,
tree procedure_address, const std::vector<boot::expression *>& arguments);
diff --git a/include/elna/gcc/elna-tree.h b/include/elna/gcc/elna-tree.h
index 556d52b..d826f25 100644
--- a/include/elna/gcc/elna-tree.h
+++ b/include/elna/gcc/elna-tree.h
@@ -47,13 +47,6 @@ namespace elna::gcc
bool is_castable_type(tree type);
/**
- * \param lhs Left hand value.
- * \param rhs Right hand value.
- * \return Whether rhs can be assigned to lhs.
- */
- bool are_compatible_pointers(tree lhs_type, tree rhs);
-
- /**
* Prepares a value to be bound to a variable or parameter.
*
* If rvalue is a procedure declaration, builds a procedure pointer.
@@ -63,23 +56,12 @@ namespace elna::gcc
*/
tree prepare_rvalue(tree rvalue);
- /**
- * \param assignee Assignee.
- * \param assignee Assignment.
- * \return Whether an expression assignment can be assigned to a variable of type assignee.
- */
- bool is_assignable_from(tree assignee, tree assignment);
-
void append_statement(tree statement_tree);
void defer(tree statement_tree);
tree chain_defer();
tree do_pointer_arithmetic(boot::binary_operator binary_operator,
tree left, tree right, location_t expression_location);
- tree build_binary_operation(bool condition, boot::binary_expression *expression,
- tree_code operator_code, tree left, tree right, tree target_type);
- tree build_arithmetic_operation(boot::binary_expression *expression,
- tree_code operator_code, tree left, tree right);
tree build_field(location_t location, tree record_type, const std::string name, tree type);
tree find_field_by_name(location_t expression_location, tree type, const std::string& field_name);
tree build_static_array_type(tree type, const std::uint64_t size);
diff --git a/include/elna/gcc/elna1.h b/include/elna/gcc/elna1.h
index 3f48af5..b05cdf2 100644
--- a/include/elna/gcc/elna1.h
+++ b/include/elna/gcc/elna1.h
@@ -25,12 +25,9 @@ enum elna_tree_index
ELNA_TI_BOOL_TYPE,
ELNA_TI_POINTER_TYPE,
ELNA_TI_FLOAT_TYPE,
- ELNA_TI_STRING_TYPE,
ELNA_TI_BOOL_TRUE,
ELNA_TI_BOOL_FALSE,
ELNA_TI_POINTER_NIL,
- ELNA_TI_STRING_PTR_FIELD,
- ELNA_TI_STRING_LENGTH_FIELD,
ELNA_TI_MAX
};
@@ -44,13 +41,9 @@ extern std::vector<std::string> elna_include_dirs;
#define elna_bool_type_node elna_global_trees[ELNA_TI_BOOL_TYPE]
#define elna_pointer_type_node elna_global_trees[ELNA_TI_POINTER_TYPE]
#define elna_float_type_node elna_global_trees[ELNA_TI_FLOAT_TYPE]
-#define elna_string_type_node elna_global_trees[ELNA_TI_STRING_TYPE]
#define elna_bool_true_node elna_global_trees[ELNA_TI_BOOL_TRUE]
#define elna_bool_false_node elna_global_trees[ELNA_TI_BOOL_FALSE]
#define elna_pointer_nil_node elna_global_trees[ELNA_TI_POINTER_NIL]
-#define elna_string_ptr_field_node elna_global_trees[ELNA_TI_STRING_PTR_FIELD]
-#define elna_string_length_field_node elna_global_trees[ELNA_TI_STRING_LENGTH_FIELD]
-
/* Language-dependent contents of a type. */
struct GTY (()) lang_type
{