Add a char type

This commit is contained in:
Eugen Wissner 2025-01-01 23:02:19 +01:00
parent 8176da5f9b
commit 45eb6a3b84
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
10 changed files with 70 additions and 25 deletions

View File

@ -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>>";

View File

@ -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()),

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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);
} }

View File

@ -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: