Implement the Word type
This commit is contained in:
parent
5548b66b15
commit
005e9dcc52
@ -250,7 +250,12 @@ namespace gcc
|
|||||||
|
|
||||||
void generic_visitor::visit(source::number_literal<std::int32_t> *literal)
|
void generic_visitor::visit(source::number_literal<std::int32_t> *literal)
|
||||||
{
|
{
|
||||||
this->current_expression = build_int_cst_type(integer_type_node, literal->number());
|
this->current_expression = build_int_cst(integer_type_node, literal->number());
|
||||||
|
}
|
||||||
|
|
||||||
|
void generic_visitor::visit(source::number_literal<std::uint32_t> *literal)
|
||||||
|
{
|
||||||
|
this->current_expression = build_int_cstu(unsigned_type_node, literal->number());
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(source::number_literal<double> *literal)
|
void generic_visitor::visit(source::number_literal<double> *literal)
|
||||||
|
@ -41,6 +41,7 @@ namespace gcc
|
|||||||
void visit(source::procedure_definition *definition) override;
|
void visit(source::procedure_definition *definition) override;
|
||||||
void visit(source::call_expression *statement) override;
|
void visit(source::call_expression *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<std::uint32_t> *literal) override;
|
||||||
void visit(source::number_literal<double> *literal) override;
|
void visit(source::number_literal<double> *literal) override;
|
||||||
void visit(source::number_literal<bool> *boolean) override;
|
void visit(source::number_literal<bool> *boolean) override;
|
||||||
void visit(source::number_literal<unsigned char> *character) override;
|
void visit(source::number_literal<unsigned char> *character) override;
|
||||||
|
@ -94,6 +94,7 @@ namespace source
|
|||||||
virtual void visit(field_access_expression *is_field_access) = 0;
|
virtual void visit(field_access_expression *is_field_access) = 0;
|
||||||
virtual void visit(dereference_expression *is_dereference) = 0;
|
virtual void visit(dereference_expression *is_dereference) = 0;
|
||||||
virtual void visit(number_literal<std::int32_t> *) = 0;
|
virtual void visit(number_literal<std::int32_t> *) = 0;
|
||||||
|
virtual void visit(number_literal<std::uint32_t> *) = 0;
|
||||||
virtual void visit(number_literal<double> *) = 0;
|
virtual void visit(number_literal<double> *) = 0;
|
||||||
virtual void visit(number_literal<bool> *) = 0;
|
virtual void visit(number_literal<bool> *) = 0;
|
||||||
virtual void visit(number_literal<unsigned char> *) = 0;
|
virtual void visit(number_literal<unsigned char> *) = 0;
|
||||||
@ -130,6 +131,7 @@ namespace source
|
|||||||
virtual void visit(field_access_expression *expression) override;
|
virtual void visit(field_access_expression *expression) override;
|
||||||
virtual void visit(dereference_expression *expression) override;
|
virtual void visit(dereference_expression *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<std::uint32_t> *) override;
|
||||||
virtual void visit(number_literal<double> *) override;
|
virtual void visit(number_literal<double> *) override;
|
||||||
virtual void visit(number_literal<bool> *) override;
|
virtual void visit(number_literal<bool> *) override;
|
||||||
virtual void visit(number_literal<unsigned char> *) override;
|
virtual void visit(number_literal<unsigned char> *) override;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <optional>
|
||||||
#include "elna/source/ast.h"
|
#include "elna/source/ast.h"
|
||||||
#include "location.hh"
|
#include "location.hh"
|
||||||
|
|
||||||
@ -37,5 +38,7 @@ namespace source
|
|||||||
void error(const yy::location& loc, const std::string& message);
|
void error(const yy::location& loc, const std::string& message);
|
||||||
const std::list<std::unique_ptr<struct error>>& errors() const noexcept;
|
const std::list<std::unique_ptr<struct error>>& errors() const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::optional<char> escape_char(char escape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,10 @@ namespace source
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void empty_visitor::visit(number_literal<std::uint32_t> *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(number_literal<double> *)
|
void empty_visitor::visit(number_literal<double> *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -40,5 +40,38 @@ namespace source
|
|||||||
{
|
{
|
||||||
return m_errors;
|
return m_errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<char> escape_char(char escape)
|
||||||
|
{
|
||||||
|
switch (escape)
|
||||||
|
{
|
||||||
|
case 'n':
|
||||||
|
return std::make_optional<char>('\n');
|
||||||
|
case 'a':
|
||||||
|
return std::make_optional<char>('\a');
|
||||||
|
case 'b':
|
||||||
|
return std::make_optional<char>('\b');
|
||||||
|
case 't':
|
||||||
|
return std::make_optional<char>('\t');
|
||||||
|
case 'f':
|
||||||
|
return std::make_optional<char>('\f');
|
||||||
|
case 'r':
|
||||||
|
return std::make_optional<char>('\r');
|
||||||
|
case 'v':
|
||||||
|
return std::make_optional<char>('\v');
|
||||||
|
case '\\':
|
||||||
|
return std::make_optional<char>('\\');
|
||||||
|
case '\'':
|
||||||
|
return std::make_optional<char>('\'');
|
||||||
|
case '"':
|
||||||
|
return std::make_optional<char>('"');
|
||||||
|
case '?':
|
||||||
|
return std::make_optional<char>('\?');
|
||||||
|
case '0':
|
||||||
|
return std::make_optional<char>('\0');
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,9 @@ return {
|
|||||||
[A-Za-z_][A-Za-z0-9_]* {
|
[A-Za-z_][A-Za-z0-9_]* {
|
||||||
return yy::parser::make_IDENTIFIER(yytext, this->location);
|
return yy::parser::make_IDENTIFIER(yytext, this->location);
|
||||||
}
|
}
|
||||||
|
[0-9]+u {
|
||||||
|
return yy::parser::make_WORD(strtoul(yytext, NULL, 10), this->location);
|
||||||
|
}
|
||||||
[0-9]+ {
|
[0-9]+ {
|
||||||
return yy::parser::make_INTEGER(strtol(yytext, NULL, 10), this->location);
|
return yy::parser::make_INTEGER(strtol(yytext, NULL, 10), this->location);
|
||||||
}
|
}
|
||||||
@ -113,7 +116,7 @@ return {
|
|||||||
return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location);
|
return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location);
|
||||||
}
|
}
|
||||||
'[[:print:]]' {
|
'[[:print:]]' {
|
||||||
if (yytext[1] == '\\')
|
if (yytext[1] == '\\' || yytext[1] == '\'')
|
||||||
{
|
{
|
||||||
REJECT;
|
REJECT;
|
||||||
}
|
}
|
||||||
@ -122,45 +125,66 @@ return {
|
|||||||
return yy::parser::make_CHARACTER(std::string(yytext, 1, 1), this->location);
|
return yy::parser::make_CHARACTER(std::string(yytext, 1, 1), this->location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'\\x[0-9a-fA-F]{2}' {
|
'\\x[0-9a-fA-F]{1,2}' {
|
||||||
char character = static_cast<char>(std::stoi(yytext + 3, nullptr, 16));
|
char character = static_cast<char>(std::stoi(yytext + 3, nullptr, 16));
|
||||||
|
|
||||||
return yy::parser::make_CHARACTER(std::string(&character, 1), this->location);
|
return yy::parser::make_CHARACTER(std::string(&character, 1), this->location);
|
||||||
}
|
}
|
||||||
'\\[0nabtfrv\\'"?]' {
|
'\\[0nabtfrv\\'"?]' {
|
||||||
switch (yytext[2])
|
std::optional<char> escape = source::escape_char(yytext[2]);
|
||||||
|
if (escape.has_value())
|
||||||
|
{
|
||||||
|
return yy::parser::make_CHARACTER(std::string(&escape.value(), 1), this->location);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case 'n':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\n"), this->location);
|
|
||||||
case 'a':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\a"), this->location);
|
|
||||||
case 'b':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\b"), this->location);
|
|
||||||
case 't':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\t"), this->location);
|
|
||||||
case 'f':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\f"), this->location);
|
|
||||||
case 'r':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\r"), this->location);
|
|
||||||
case 'v':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\v"), this->location);
|
|
||||||
case '\\':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\\"), this->location);
|
|
||||||
case '\'':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("'"), this->location);
|
|
||||||
case '"':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\""), this->location);
|
|
||||||
case '?':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\?"), this->location);
|
|
||||||
case '0':
|
|
||||||
return yy::parser::make_CHARACTER(std::string("\0", 1), this->location);
|
|
||||||
default:
|
|
||||||
REJECT;
|
REJECT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\"[^\"]*\" {
|
\"[[:print:]]*\" {
|
||||||
return yy::parser::make_STRING(
|
std::string result;
|
||||||
std::string(yytext, 1, strlen(yytext) - 2), this->location);
|
const char *current_position = yytext + 1;
|
||||||
|
|
||||||
|
while (*current_position != '\0')
|
||||||
|
{
|
||||||
|
if (*current_position == '\\' && *(current_position + 1) == 'x')
|
||||||
|
{
|
||||||
|
current_position += 2;
|
||||||
|
|
||||||
|
std::size_t processed;
|
||||||
|
char character = static_cast<char>(std::stoi(current_position, &processed, 16));
|
||||||
|
if (processed == 0)
|
||||||
|
{
|
||||||
|
REJECT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_position += processed - 1;
|
||||||
|
result.push_back(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*current_position == '\\')
|
||||||
|
{
|
||||||
|
++current_position;
|
||||||
|
|
||||||
|
std::optional<char> escape = source::escape_char(*current_position);
|
||||||
|
if (escape.has_value())
|
||||||
|
{
|
||||||
|
result.push_back(escape.value());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
REJECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.push_back(*current_position);
|
||||||
|
}
|
||||||
|
++current_position;
|
||||||
|
}
|
||||||
|
result.pop_back();
|
||||||
|
return yy::parser::make_STRING(result, this->location);
|
||||||
}
|
}
|
||||||
\( {
|
\( {
|
||||||
return yy::parser::make_LEFT_PAREN(this->location);
|
return yy::parser::make_LEFT_PAREN(this->location);
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
%token <std::string> IDENTIFIER "identifier"
|
||||||
%token <std::int32_t> INTEGER "integer"
|
%token <std::int32_t> INTEGER "integer"
|
||||||
|
%token <std::uint32_t> WORD "word"
|
||||||
%token <float> FLOAT "float"
|
%token <float> FLOAT "float"
|
||||||
%token <std::string> CHARACTER "character"
|
%token <std::string> CHARACTER "character"
|
||||||
%token <std::string> STRING "string"
|
%token <std::string> STRING "string"
|
||||||
@ -208,6 +209,10 @@ literal:
|
|||||||
{
|
{
|
||||||
$$ = new elna::source::number_literal<std::int32_t>(elna::source::make_position(@1), $1);
|
$$ = new elna::source::number_literal<std::int32_t>(elna::source::make_position(@1), $1);
|
||||||
}
|
}
|
||||||
|
| WORD
|
||||||
|
{
|
||||||
|
$$ = new elna::source::number_literal<std::uint32_t>(elna::source::make_position(@1), $1);
|
||||||
|
}
|
||||||
| FLOAT
|
| FLOAT
|
||||||
{
|
{
|
||||||
$$ = new elna::source::number_literal<double>(elna::source::make_position(@1), $1);
|
$$ = new elna::source::number_literal<double>(elna::source::make_position(@1), $1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user