Make type_expression abstract
This commit is contained in:
parent
98c13f0be3
commit
bbd38a5d26
@ -8,7 +8,7 @@
|
|||||||
/* Creates an expression whose value is that of EXPR, converted to type TYPE.
|
/* Creates an expression whose value is that of EXPR, converted to type TYPE.
|
||||||
This function implements all reasonable scalar conversions. */
|
This function implements all reasonable scalar conversions. */
|
||||||
|
|
||||||
tree convert(tree type, tree expr)
|
tree convert(tree /* type */, tree expr)
|
||||||
{
|
{
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
@ -285,31 +285,34 @@ namespace gcc
|
|||||||
void generic_visitor::visit(source::declaration *declaration)
|
void generic_visitor::visit(source::declaration *declaration)
|
||||||
{
|
{
|
||||||
tree declaration_type = error_mark_node;
|
tree declaration_type = error_mark_node;
|
||||||
|
source::basic_type_expression *basic_type = declaration->type().is_basic();
|
||||||
|
|
||||||
if (declaration->type().base() == "Int")
|
gcc_assert(basic_type != nullptr);
|
||||||
|
|
||||||
|
if (basic_type->base() == "Int")
|
||||||
{
|
{
|
||||||
declaration_type = integer_type_node;
|
declaration_type = integer_type_node;
|
||||||
}
|
}
|
||||||
else if (declaration->type().base() == "Bool")
|
else if (basic_type->base() == "Bool")
|
||||||
{
|
{
|
||||||
declaration_type = boolean_type_node;
|
declaration_type = boolean_type_node;
|
||||||
}
|
}
|
||||||
else if (declaration->type().base() == "Float")
|
else if (basic_type->base() == "Float")
|
||||||
{
|
{
|
||||||
declaration_type = double_type_node;
|
declaration_type = double_type_node;
|
||||||
}
|
}
|
||||||
else if (declaration->type().base() == "Char")
|
else if (basic_type->base() == "Char")
|
||||||
{
|
{
|
||||||
declaration_type = elna_char_type_node;
|
declaration_type = elna_char_type_node;
|
||||||
}
|
}
|
||||||
else if (declaration->type().base() == "String")
|
else if (basic_type->base() == "String")
|
||||||
{
|
{
|
||||||
declaration_type = elna_string_type_node;
|
declaration_type = elna_string_type_node;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_at(get_location(&declaration->type().position()),
|
error_at(get_location(&declaration->type().position()),
|
||||||
"type '%s' not declared", declaration->type().base().c_str());
|
"type '%s' not declared", basic_type->base().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto declaration_location = get_location(&declaration->position());
|
auto declaration_location = get_location(&declaration->position());
|
||||||
|
@ -46,7 +46,7 @@ namespace source
|
|||||||
class program;
|
class program;
|
||||||
class binary_expression;
|
class binary_expression;
|
||||||
class unary_expression;
|
class unary_expression;
|
||||||
class type_expression;
|
class basic_type_expression;
|
||||||
class variable_expression;
|
class variable_expression;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class number_literal;
|
class number_literal;
|
||||||
@ -70,7 +70,7 @@ namespace source
|
|||||||
virtual void visit(program *) = 0;
|
virtual void visit(program *) = 0;
|
||||||
virtual void visit(binary_expression *) = 0;
|
virtual void visit(binary_expression *) = 0;
|
||||||
virtual void visit(unary_expression *) = 0;
|
virtual void visit(unary_expression *) = 0;
|
||||||
virtual void visit(type_expression *) = 0;
|
virtual void visit(basic_type_expression *) = 0;
|
||||||
virtual void visit(variable_expression *) = 0;
|
virtual void visit(variable_expression *) = 0;
|
||||||
virtual void visit(number_literal<std::int32_t> *) = 0;
|
virtual void visit(number_literal<std::int32_t> *) = 0;
|
||||||
virtual void visit(number_literal<double> *) = 0;
|
virtual void visit(number_literal<double> *) = 0;
|
||||||
@ -96,7 +96,7 @@ namespace source
|
|||||||
virtual void visit(program *program) override;
|
virtual void visit(program *program) override;
|
||||||
virtual void visit(binary_expression *expression) override;
|
virtual void visit(binary_expression *expression) override;
|
||||||
virtual void visit(unary_expression *expression) override;
|
virtual void visit(unary_expression *expression) override;
|
||||||
virtual void visit(type_expression *) override;
|
virtual void visit(basic_type_expression *) override;
|
||||||
virtual void visit(variable_expression *) override;
|
virtual void visit(variable_expression *) override;
|
||||||
virtual void visit(number_literal<std::int32_t> *) override;
|
virtual void visit(number_literal<std::int32_t> *) override;
|
||||||
virtual void visit(number_literal<double> *) override;
|
virtual void visit(number_literal<double> *) override;
|
||||||
@ -223,20 +223,30 @@ namespace source
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expression defining a composed type like pointer or an array.
|
* Some type expression.
|
||||||
*/
|
*/
|
||||||
class type_expression : public node
|
class type_expression : public node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual basic_type_expression *is_basic();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
type_expression(const struct position position);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expression defining a basic type.
|
||||||
|
*/
|
||||||
|
class basic_type_expression : public type_expression
|
||||||
{
|
{
|
||||||
std::string m_base;
|
std::string m_base;
|
||||||
bool m_pointer{ false };
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* \param position Source code position.
|
* \param position Source code position.
|
||||||
* \param name Type name.
|
* \param name Type name.
|
||||||
* \param is_pointer Whether it is a pointer type.
|
|
||||||
*/
|
*/
|
||||||
type_expression(const struct position position, const std::string& name, const bool is_pointer = false);
|
basic_type_expression(const struct position position, const std::string& name);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,10 +254,7 @@ namespace source
|
|||||||
*/
|
*/
|
||||||
const std::string& base() const noexcept;
|
const std::string& base() const noexcept;
|
||||||
|
|
||||||
/**
|
basic_type_expression *is_basic() override;
|
||||||
* \return Whether the type is a pointer.
|
|
||||||
*/
|
|
||||||
bool is_pointer() const noexcept;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +87,7 @@ namespace source
|
|||||||
expression->operand().accept(this);
|
expression->operand().accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(type_expression *)
|
void empty_visitor::visit(basic_type_expression *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,24 +179,35 @@ namespace source
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
type_expression::type_expression(const struct position position, const std::string& name, const bool is_pointer)
|
type_expression::type_expression(const struct position position)
|
||||||
: node(position), m_base(name), m_pointer(is_pointer)
|
: node(position)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_expression::accept(parser_visitor *visitor)
|
basic_type_expression *type_expression::is_basic()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_type_expression::basic_type_expression(
|
||||||
|
const struct position position, const std::string& name)
|
||||||
|
: type_expression(position), m_base(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void basic_type_expression::accept(parser_visitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visit(this);
|
visitor->visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& type_expression::base() const noexcept
|
const std::string& basic_type_expression::base() const noexcept
|
||||||
{
|
{
|
||||||
return m_base;
|
return m_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool type_expression::is_pointer() const noexcept
|
basic_type_expression *basic_type_expression::is_basic()
|
||||||
{
|
{
|
||||||
return m_pointer;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
declaration::declaration(const struct position position, const std::string& identifier,
|
declaration::declaration(const struct position position, const std::string& identifier,
|
||||||
|
@ -90,6 +90,12 @@ false {
|
|||||||
\) {
|
\) {
|
||||||
return yy::parser::make_RIGHT_PAREN(this->location);
|
return yy::parser::make_RIGHT_PAREN(this->location);
|
||||||
}
|
}
|
||||||
|
\[ {
|
||||||
|
return yy::parser::make_LEFT_SQUARE(this->location);
|
||||||
|
}
|
||||||
|
\] {
|
||||||
|
return yy::parser::make_RIGHT_SQUARE(this->location);
|
||||||
|
}
|
||||||
\>= {
|
\>= {
|
||||||
return yy::parser::make_GREATER_EQUAL(this->location);
|
return yy::parser::make_GREATER_EQUAL(this->location);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
%token IF WHILE DO
|
%token IF WHILE DO
|
||||||
%token CONST VAR PROCEDURE
|
%token CONST VAR PROCEDURE
|
||||||
%token BEGIN_BLOCK END_BLOCK
|
%token BEGIN_BLOCK END_BLOCK
|
||||||
%token LEFT_PAREN RIGHT_PAREN SEMICOLON DOT COMMA
|
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
|
||||||
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
|
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
|
||||||
%token PLUS MINUS MULTIPLICATION DIVISION
|
%token PLUS MINUS MULTIPLICATION DIVISION
|
||||||
%token ASSIGNMENT COLON HAT AT
|
%token ASSIGNMENT COLON HAT AT
|
||||||
@ -83,7 +83,7 @@
|
|||||||
%type <std::unique_ptr<elna::source::declaration>> variable_declaration;
|
%type <std::unique_ptr<elna::source::declaration>> variable_declaration;
|
||||||
%type <std::vector<std::unique_ptr<elna::source::declaration>>> variable_declarations variable_declaration_part
|
%type <std::vector<std::unique_ptr<elna::source::declaration>>> variable_declarations variable_declaration_part
|
||||||
formal_parameter_list;
|
formal_parameter_list;
|
||||||
%type <std::unique_ptr<elna::source::type_expression>> type_expression;
|
%type <std::unique_ptr<elna::source::basic_type_expression>> type_expression;
|
||||||
%type <std::unique_ptr<elna::source::expression>> expression pointer summand factor address comparand;
|
%type <std::unique_ptr<elna::source::expression>> expression pointer summand factor address comparand;
|
||||||
%type <std::vector<std::unique_ptr<elna::source::expression>>> expressions actual_parameter_list;
|
%type <std::vector<std::unique_ptr<elna::source::expression>>> expressions actual_parameter_list;
|
||||||
%type <std::unique_ptr<elna::source::variable_expression>> variable_expression;
|
%type <std::unique_ptr<elna::source::variable_expression>> variable_expression;
|
||||||
@ -299,13 +299,9 @@ optional_statements:
|
|||||||
statements { std::swap($$, $1); }
|
statements { std::swap($$, $1); }
|
||||||
| /* no statements */ {}
|
| /* no statements */ {}
|
||||||
type_expression:
|
type_expression:
|
||||||
HAT IDENTIFIER
|
IDENTIFIER
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::type_expression>(elna::source::make_position(@1), $2, true);
|
$$ = std::make_unique<elna::source::basic_type_expression>(elna::source::make_position(@1), $1);
|
||||||
}
|
|
||||||
| IDENTIFIER
|
|
||||||
{
|
|
||||||
$$ = std::make_unique<elna::source::type_expression>(elna::source::make_position(@1), $1, false);
|
|
||||||
}
|
}
|
||||||
variable_declaration: IDENTIFIER COLON type_expression
|
variable_declaration: IDENTIFIER COLON type_expression
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user