Add a char type
This commit is contained in:
parent
8176da5f9b
commit
45eb6a3b84
@ -28,6 +28,10 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
return "Float";
|
return "Float";
|
||||||
}
|
}
|
||||||
|
else if (type == elna_char_type_node)
|
||||||
|
{
|
||||||
|
return "Char";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return "<<unknown-type>>";
|
return "<<unknown-type>>";
|
||||||
|
@ -42,6 +42,10 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
format_number = "%f\n";
|
format_number = "%f\n";
|
||||||
}
|
}
|
||||||
|
else if (argument_type == elna_char_type_node)
|
||||||
|
{
|
||||||
|
format_number = "%c\n";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_at(get_location(&argument->position()),
|
error_at(get_location(&argument->position()),
|
||||||
@ -125,9 +129,14 @@ namespace gcc
|
|||||||
mpfr_clear(number);
|
mpfr_clear(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(source::boolean_literal *literal)
|
void generic_visitor::visit(source::number_literal<bool> *boolean)
|
||||||
{
|
{
|
||||||
this->current_expression = build_int_cst_type(boolean_type_node, literal->boolean());
|
this->current_expression = build_int_cst_type(boolean_type_node, boolean->number());
|
||||||
|
}
|
||||||
|
|
||||||
|
void generic_visitor::visit(source::char_literal *character)
|
||||||
|
{
|
||||||
|
this->current_expression = build_int_cstu(elna_char_type_node, character->character());
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(source::binary_expression *expression)
|
void generic_visitor::visit(source::binary_expression *expression)
|
||||||
@ -262,6 +271,10 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
declaration_type = double_type_node;
|
declaration_type = double_type_node;
|
||||||
}
|
}
|
||||||
|
else if (declaration->type().base() == "Char")
|
||||||
|
{
|
||||||
|
declaration_type = elna_char_type_node;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_at(get_location(&declaration->type().position()),
|
error_at(get_location(&declaration->type().position()),
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
#include "elna/gcc/elna-tree.h"
|
#include "elna/gcc/elna-tree.h"
|
||||||
|
|
||||||
|
#include "stor-layout.h"
|
||||||
|
|
||||||
tree elna_global_trees[ELNA_TI_MAX];
|
tree elna_global_trees[ELNA_TI_MAX];
|
||||||
|
|
||||||
|
void elna_init_ttree(void)
|
||||||
|
{
|
||||||
|
elna_char_type_node = make_unsigned_type(8);
|
||||||
|
TYPE_STRING_FLAG(elna_char_type_node) = 1;
|
||||||
|
}
|
||||||
|
@ -66,7 +66,7 @@ struct GTY (()) language_function
|
|||||||
static bool elna_langhook_init(void)
|
static bool elna_langhook_init(void)
|
||||||
{
|
{
|
||||||
build_common_tree_nodes(false);
|
build_common_tree_nodes(false);
|
||||||
enumeral_node = make_node(ENUMERAL_TYPE);
|
elna_init_ttree();
|
||||||
|
|
||||||
/* I don't know why this has to be done explicitly. */
|
/* I don't know why this has to be done explicitly. */
|
||||||
void_list_node = build_tree_list(NULL_TREE, void_type_node);
|
void_list_node = build_tree_list(NULL_TREE, void_type_node);
|
||||||
|
@ -29,7 +29,8 @@ namespace gcc
|
|||||||
void visit(source::call_statement *statement) override;
|
void visit(source::call_statement *statement) override;
|
||||||
void visit(source::number_literal<std::int32_t> *literal) override;
|
void visit(source::number_literal<std::int32_t> *literal) override;
|
||||||
void visit(source::number_literal<double> *literal) override;
|
void visit(source::number_literal<double> *literal) override;
|
||||||
void visit(source::boolean_literal *literal) override;
|
void visit(source::number_literal<bool> *boolean) override;
|
||||||
|
void visit(source::char_literal *character) override;
|
||||||
void visit(source::binary_expression *expression) override;
|
void visit(source::binary_expression *expression) override;
|
||||||
void visit(source::constant_definition *definition) override;
|
void visit(source::constant_definition *definition) override;
|
||||||
void visit(source::declaration *declaration) override;
|
void visit(source::declaration *declaration) override;
|
||||||
|
@ -7,10 +7,12 @@
|
|||||||
|
|
||||||
enum elna_tree_index
|
enum elna_tree_index
|
||||||
{
|
{
|
||||||
ELNA_TI_ENUMERAL_TYPE,
|
ELNA_TI_CHAR_TYPE,
|
||||||
ELNA_TI_MAX
|
ELNA_TI_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GTY(()) tree elna_global_trees[ELNA_TI_MAX];
|
extern GTY(()) tree elna_global_trees[ELNA_TI_MAX];
|
||||||
|
|
||||||
#define enumeral_node elna_global_trees[ELNA_TI_ENUMERAL_TYPE]
|
#define elna_char_type_node elna_global_trees[ELNA_TI_CHAR_TYPE]
|
||||||
|
|
||||||
|
void elna_init_ttree(void);
|
||||||
|
@ -48,7 +48,7 @@ namespace source
|
|||||||
class variable_expression;
|
class variable_expression;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class number_literal;
|
class number_literal;
|
||||||
class boolean_literal;
|
class char_literal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for AST visitors.
|
* Interface for AST visitors.
|
||||||
@ -71,7 +71,8 @@ namespace source
|
|||||||
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;
|
||||||
virtual void visit(boolean_literal *) = 0;
|
virtual void visit(number_literal<bool> *) = 0;
|
||||||
|
virtual void visit(char_literal *) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,8 +95,9 @@ namespace source
|
|||||||
virtual void visit(type_expression *variable) override;
|
virtual void visit(type_expression *variable) override;
|
||||||
virtual void visit(variable_expression *variable) override;
|
virtual void visit(variable_expression *variable) override;
|
||||||
virtual void visit(number_literal<std::int32_t> *number) override;
|
virtual void visit(number_literal<std::int32_t> *number) override;
|
||||||
virtual void visit(number_literal<double> *) override;
|
virtual void visit(number_literal<double> *number) override;
|
||||||
virtual void visit(boolean_literal *boolean) override;
|
virtual void visit(number_literal<bool> *boolean) override;
|
||||||
|
virtual void visit(char_literal *character) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -452,15 +454,15 @@ namespace source
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class boolean_literal : public expression
|
class char_literal : public expression
|
||||||
{
|
{
|
||||||
bool m_boolean;
|
unsigned char m_character;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
boolean_literal(const struct position position, const bool value);
|
char_literal(const struct position position, const unsigned char value);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
bool boolean() const noexcept;
|
unsigned char character() const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
class variable_expression : public expression
|
class variable_expression : public expression
|
||||||
|
@ -103,7 +103,11 @@ namespace source
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(boolean_literal *boolean)
|
void empty_visitor::visit(number_literal<bool> *character)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void empty_visitor::visit(char_literal *character)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,19 +298,19 @@ namespace source
|
|||||||
visitor->visit(this);
|
visitor->visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean_literal::boolean_literal(const struct position position, const bool value)
|
char_literal::char_literal(const struct position position, const unsigned char value)
|
||||||
: expression(position), m_boolean(value)
|
: expression(position), m_character(value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void boolean_literal::accept(parser_visitor *visitor)
|
void char_literal::accept(parser_visitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visit(this);
|
visitor->visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boolean_literal::boolean() const noexcept
|
unsigned char char_literal::character() const noexcept
|
||||||
{
|
{
|
||||||
return m_boolean;
|
return m_character;
|
||||||
}
|
}
|
||||||
|
|
||||||
variable_expression::variable_expression(const struct position position, const std::string& name)
|
variable_expression::variable_expression(const struct position position, const std::string& name)
|
||||||
|
@ -71,11 +71,15 @@ false {
|
|||||||
return yy::parser::make_IDENTIFIER(yytext, this->location);
|
return yy::parser::make_IDENTIFIER(yytext, this->location);
|
||||||
}
|
}
|
||||||
[0-9]+ {
|
[0-9]+ {
|
||||||
return yy::parser::make_NUMBER(strtol(yytext, NULL, 10), this->location);
|
return yy::parser::make_INTEGER(strtol(yytext, NULL, 10), this->location);
|
||||||
}
|
}
|
||||||
[0-9]+\.[0-9] {
|
[0-9]+\.[0-9] {
|
||||||
return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location);
|
return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location);
|
||||||
}
|
}
|
||||||
|
'[^']' {
|
||||||
|
return yy::parser::make_CHARACTER(
|
||||||
|
std::string(yytext, 1, strlen(yytext) - 2), this->location);
|
||||||
|
}
|
||||||
\( {
|
\( {
|
||||||
return yy::parser::make_LEFT_PAREN(this->location);
|
return yy::parser::make_LEFT_PAREN(this->location);
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,9 @@
|
|||||||
%start program;
|
%start program;
|
||||||
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
%token <std::string> IDENTIFIER "identifier"
|
||||||
%token <std::int32_t> NUMBER "number"
|
%token <std::int32_t> INTEGER "integer"
|
||||||
%token <float> FLOAT "float"
|
%token <float> FLOAT "float"
|
||||||
|
%token <std::string> CHARACTER "character"
|
||||||
%token <bool> BOOLEAN
|
%token <bool> BOOLEAN
|
||||||
%token IF WHILE DO
|
%token IF WHILE DO
|
||||||
%token CONST VAR PROCEDURE
|
%token CONST VAR PROCEDURE
|
||||||
@ -73,7 +74,8 @@
|
|||||||
|
|
||||||
%type <std::unique_ptr<elna::source::number_literal<std::int32_t>>> integer_literal;
|
%type <std::unique_ptr<elna::source::number_literal<std::int32_t>>> integer_literal;
|
||||||
%type <std::unique_ptr<elna::source::number_literal<double>>> float_literal;
|
%type <std::unique_ptr<elna::source::number_literal<double>>> float_literal;
|
||||||
%type <std::unique_ptr<elna::source::boolean_literal>> boolean_literal;
|
%type <std::unique_ptr<elna::source::number_literal<bool>>> boolean_literal;
|
||||||
|
%type <std::unique_ptr<elna::source::char_literal>> character_literal;
|
||||||
%type <std::unique_ptr<elna::source::constant_definition>> constant_definition;
|
%type <std::unique_ptr<elna::source::constant_definition>> constant_definition;
|
||||||
%type <std::vector<std::unique_ptr<elna::source::constant_definition>>> constant_definition_part constant_definitions;
|
%type <std::vector<std::unique_ptr<elna::source::constant_definition>>> constant_definition_part constant_definitions;
|
||||||
%type <std::unique_ptr<elna::source::declaration>> variable_declaration;
|
%type <std::unique_ptr<elna::source::declaration>> variable_declaration;
|
||||||
@ -141,7 +143,7 @@ procedure_definitions:
|
|||||||
procedure_definition_part:
|
procedure_definition_part:
|
||||||
/* no procedure definitions */ {}
|
/* no procedure definitions */ {}
|
||||||
| procedure_definitions { std::swap($$, $1); }
|
| procedure_definitions { std::swap($$, $1); }
|
||||||
integer_literal: NUMBER
|
integer_literal: INTEGER
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::number_literal<std::int32_t>>(elna::source::make_position(@1), $1);
|
$$ = std::make_unique<elna::source::number_literal<std::int32_t>>(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
@ -149,9 +151,13 @@ float_literal: FLOAT
|
|||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::number_literal<double>>(elna::source::make_position(@1), $1);
|
$$ = std::make_unique<elna::source::number_literal<double>>(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
|
character_literal: CHARACTER
|
||||||
|
{
|
||||||
|
$$ = std::make_unique<elna::source::char_literal>(elna::source::make_position(@1), $1[0]);
|
||||||
|
};
|
||||||
boolean_literal: BOOLEAN
|
boolean_literal: BOOLEAN
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::boolean_literal>(elna::source::make_position(@1), $1);
|
$$ = std::make_unique<elna::source::number_literal<bool>>(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
|
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
|
||||||
{
|
{
|
||||||
@ -187,6 +193,7 @@ pointer:
|
|||||||
integer_literal { $$ = std::move($1); }
|
integer_literal { $$ = std::move($1); }
|
||||||
| float_literal { $$ = std::move($1); }
|
| float_literal { $$ = std::move($1); }
|
||||||
| boolean_literal { $$ = std::move($1); }
|
| boolean_literal { $$ = std::move($1); }
|
||||||
|
| character_literal { $$ = std::move($1); }
|
||||||
| variable_expression { $$ = std::move($1); }
|
| variable_expression { $$ = std::move($1); }
|
||||||
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
|
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
|
||||||
summand:
|
summand:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user