Add string type
This commit is contained in:
parent
660c774327
commit
a7b0c53d23
11
Rakefile
11
Rakefile
@ -1,3 +1,14 @@
|
|||||||
|
# MacOS:
|
||||||
|
# ---
|
||||||
|
# CC=gcc-14 CXX=g++-14 \
|
||||||
|
# CFLAGS="-I/opt/homebrew/Cellar/flex/2.6.4_2/include" \
|
||||||
|
# CXXFLAGS="-I/opt/homebrew/Cellar/flex/2.6.4_2/include" \
|
||||||
|
# ../gcc-14.2.0/configure \
|
||||||
|
# --disable-bootstrap \
|
||||||
|
# --enable-languages=c,c++,elna \
|
||||||
|
# --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk \
|
||||||
|
# --prefix=$(realpath ../gcc-install)
|
||||||
|
|
||||||
task :default do
|
task :default do
|
||||||
sh 'make -C build'
|
sh 'make -C build'
|
||||||
sh './build/bin/elna'
|
sh './build/bin/elna'
|
||||||
|
@ -32,6 +32,10 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
return "Char";
|
return "Char";
|
||||||
}
|
}
|
||||||
|
else if (is_string_type(type))
|
||||||
|
{
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return "<<unknown-type>>";
|
return "<<unknown-type>>";
|
||||||
|
@ -25,7 +25,7 @@ namespace gcc
|
|||||||
if (statement->arguments().size() != 1)
|
if (statement->arguments().size() != 1)
|
||||||
{
|
{
|
||||||
error_at(get_location(&statement->position()),
|
error_at(get_location(&statement->position()),
|
||||||
"procedure '%s' expects 1 argument, %i given",
|
"procedure '%s' expects 1 argument, %lu given",
|
||||||
statement->name().c_str(), statement->arguments().size());
|
statement->name().c_str(), statement->arguments().size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -46,6 +46,10 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
format_number = "%c\n";
|
format_number = "%c\n";
|
||||||
}
|
}
|
||||||
|
else if (is_string_type(argument_type))
|
||||||
|
{
|
||||||
|
format_number = "%s\n";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_at(get_location(&argument->position()),
|
error_at(get_location(&argument->position()),
|
||||||
@ -83,6 +87,7 @@ namespace gcc
|
|||||||
tree main_fndecl_type = build_function_type_array(integer_type_node, 2, main_fndecl_type_param);
|
tree main_fndecl_type = build_function_type_array(integer_type_node, 2, main_fndecl_type_param);
|
||||||
this->main_fndecl = build_fn_decl("main", main_fndecl_type);
|
this->main_fndecl = build_fn_decl("main", main_fndecl_type);
|
||||||
tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, integer_type_node);
|
tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, integer_type_node);
|
||||||
|
DECL_CONTEXT(resdecl) = this->main_fndecl;
|
||||||
DECL_RESULT(this->main_fndecl) = resdecl;
|
DECL_RESULT(this->main_fndecl) = resdecl;
|
||||||
tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(main_fndecl),
|
tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(main_fndecl),
|
||||||
build_int_cst_type(integer_type_node, 0));
|
build_int_cst_type(integer_type_node, 0));
|
||||||
@ -139,6 +144,11 @@ namespace gcc
|
|||||||
this->current_expression = build_int_cstu(elna_char_type_node, character->character());
|
this->current_expression = build_int_cstu(elna_char_type_node, character->character());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generic_visitor::visit(source::string_literal *string)
|
||||||
|
{
|
||||||
|
this->current_expression = build_string_literal(string->string().size() + 1, string->string().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(source::binary_expression *expression)
|
void generic_visitor::visit(source::binary_expression *expression)
|
||||||
{
|
{
|
||||||
expression->lhs().accept(this);
|
expression->lhs().accept(this);
|
||||||
@ -180,6 +190,8 @@ namespace gcc
|
|||||||
operator_code = MULT_EXPR;
|
operator_code = MULT_EXPR;
|
||||||
target_type = left_type;
|
target_type = left_type;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (operator_code != ERROR_MARK) // An arithmetic operation.
|
if (operator_code != ERROR_MARK) // An arithmetic operation.
|
||||||
{
|
{
|
||||||
@ -219,6 +231,8 @@ namespace gcc
|
|||||||
operator_code = GE_EXPR;
|
operator_code = GE_EXPR;
|
||||||
target_type = boolean_type_node;
|
target_type = boolean_type_node;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
gcc_assert(operator_code != ERROR_MARK);
|
gcc_assert(operator_code != ERROR_MARK);
|
||||||
gcc_assert(target_type != error_mark_node);
|
gcc_assert(target_type != error_mark_node);
|
||||||
@ -275,6 +289,10 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
declaration_type = elna_char_type_node;
|
declaration_type = elna_char_type_node;
|
||||||
}
|
}
|
||||||
|
else if (declaration->type().base() == "String")
|
||||||
|
{
|
||||||
|
declaration_type = elna_string_type_node;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_at(get_location(&declaration->type().position()),
|
error_at(get_location(&declaration->type().position()),
|
||||||
@ -286,6 +304,7 @@ namespace gcc
|
|||||||
get_identifier(declaration->identifier().c_str()), declaration_type);
|
get_identifier(declaration->identifier().c_str()), declaration_type);
|
||||||
auto result = this->symbol_map.insert({ declaration->identifier(), declaration_tree });
|
auto result = this->symbol_map.insert({ declaration->identifier(), declaration_tree });
|
||||||
|
|
||||||
|
// DECL_CONTEXT(declaration_tree) = this->main_fndecl;
|
||||||
if (result.second)
|
if (result.second)
|
||||||
{
|
{
|
||||||
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,
|
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,
|
||||||
|
@ -4,8 +4,23 @@
|
|||||||
|
|
||||||
tree elna_global_trees[ELNA_TI_MAX];
|
tree elna_global_trees[ELNA_TI_MAX];
|
||||||
|
|
||||||
void elna_init_ttree(void)
|
namespace elna
|
||||||
|
{
|
||||||
|
namespace gcc
|
||||||
|
{
|
||||||
|
void init_ttree()
|
||||||
{
|
{
|
||||||
elna_char_type_node = make_unsigned_type(8);
|
elna_char_type_node = make_unsigned_type(8);
|
||||||
|
elna_string_type_node = build_pointer_type(
|
||||||
|
build_qualified_type(char_type_node, TYPE_QUAL_CONST)); /* const char* */
|
||||||
TYPE_STRING_FLAG(elna_char_type_node) = 1;
|
TYPE_STRING_FLAG(elna_char_type_node) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_string_type(tree type)
|
||||||
|
{
|
||||||
|
gcc_assert(TYPE_P(type));
|
||||||
|
return TREE_CODE(type) == POINTER_TYPE
|
||||||
|
&& TYPE_MAIN_VARIANT(TREE_TYPE(type)) == char_type_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
66
gcc/elna1.cc
66
gcc/elna1.cc
@ -66,9 +66,8 @@ 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);
|
||||||
elna_init_ttree();
|
elna::gcc::init_ttree();
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
build_common_builtin_nodes();
|
build_common_builtin_nodes();
|
||||||
@ -90,7 +89,7 @@ static void elna_parse_file(const char *filename)
|
|||||||
yy::parser parser(lexer, driver);
|
yy::parser parser(lexer, driver);
|
||||||
|
|
||||||
linemap_add(line_table, LC_ENTER, 0, filename, 1);
|
linemap_add(line_table, LC_ENTER, 0, filename, 1);
|
||||||
if (auto result = parser())
|
if (parser())
|
||||||
{
|
{
|
||||||
for (const auto& error : driver.errors())
|
for (const auto& error : driver.errors())
|
||||||
{
|
{
|
||||||
@ -110,56 +109,77 @@ static void elna_parse_file(const char *filename)
|
|||||||
|
|
||||||
static void elna_langhook_parse_file(void)
|
static void elna_langhook_parse_file(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num_in_fnames; i++)
|
for (unsigned int i = 0; i < num_in_fnames; i++)
|
||||||
{
|
{
|
||||||
elna_parse_file(in_fnames[i]);
|
elna_parse_file(in_fnames[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static tree
|
static tree elna_langhook_type_for_mode(enum machine_mode mode, int unsignedp)
|
||||||
elna_langhook_type_for_mode (enum machine_mode mode, int unsignedp)
|
|
||||||
{
|
{
|
||||||
if (mode == TYPE_MODE(float_type_node))
|
if (mode == TYPE_MODE(float_type_node))
|
||||||
|
{
|
||||||
return float_type_node;
|
return float_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE (double_type_node))
|
else if (mode == TYPE_MODE(double_type_node))
|
||||||
|
{
|
||||||
return double_type_node;
|
return double_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE(intQI_type_node))
|
if (mode == TYPE_MODE(intQI_type_node))
|
||||||
|
{
|
||||||
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
|
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
|
||||||
if (mode == TYPE_MODE (intHI_type_node))
|
}
|
||||||
|
else if (mode == TYPE_MODE(intHI_type_node))
|
||||||
|
{
|
||||||
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
|
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
|
||||||
if (mode == TYPE_MODE (intSI_type_node))
|
}
|
||||||
|
else if (mode == TYPE_MODE(intSI_type_node))
|
||||||
|
{
|
||||||
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
|
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
|
||||||
if (mode == TYPE_MODE (intDI_type_node))
|
}
|
||||||
|
else if (mode == TYPE_MODE(intDI_type_node))
|
||||||
|
{
|
||||||
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
|
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
|
||||||
if (mode == TYPE_MODE (intTI_type_node))
|
}
|
||||||
|
else if (mode == TYPE_MODE(intTI_type_node))
|
||||||
|
{
|
||||||
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
|
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE (integer_type_node))
|
else if (mode == TYPE_MODE(integer_type_node))
|
||||||
|
{
|
||||||
return unsignedp ? unsigned_type_node : integer_type_node;
|
return unsignedp ? unsigned_type_node : integer_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE (long_integer_type_node))
|
else if (mode == TYPE_MODE(long_integer_type_node))
|
||||||
|
{
|
||||||
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE (long_long_integer_type_node))
|
else if (mode == TYPE_MODE(long_long_integer_type_node))
|
||||||
return unsignedp ? long_long_unsigned_type_node
|
{
|
||||||
|
return unsignedp
|
||||||
|
? long_long_unsigned_type_node
|
||||||
: long_long_integer_type_node;
|
: long_long_integer_type_node;
|
||||||
|
}
|
||||||
if (COMPLEX_MODE_P(mode))
|
if (COMPLEX_MODE_P(mode))
|
||||||
{
|
{
|
||||||
if (mode == TYPE_MODE(complex_float_type_node))
|
if (mode == TYPE_MODE(complex_float_type_node))
|
||||||
|
{
|
||||||
return complex_float_type_node;
|
return complex_float_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE(complex_double_type_node))
|
if (mode == TYPE_MODE(complex_double_type_node))
|
||||||
|
{
|
||||||
return complex_double_type_node;
|
return complex_double_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE(complex_long_double_type_node))
|
if (mode == TYPE_MODE(complex_long_double_type_node))
|
||||||
|
{
|
||||||
return complex_long_double_type_node;
|
return complex_long_double_type_node;
|
||||||
|
}
|
||||||
if (mode == TYPE_MODE(complex_integer_type_node) && !unsignedp)
|
if (mode == TYPE_MODE(complex_integer_type_node) && !unsignedp)
|
||||||
|
{
|
||||||
return complex_integer_type_node;
|
return complex_integer_type_node;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* gcc_unreachable */
|
/* gcc_unreachable */
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tree elna_langhook_type_for_size(unsigned int bits ATTRIBUTE_UNUSED,
|
static tree elna_langhook_type_for_size(unsigned int bits ATTRIBUTE_UNUSED,
|
||||||
|
@ -31,6 +31,7 @@ namespace gcc
|
|||||||
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::char_literal *character) override;
|
void visit(source::char_literal *character) override;
|
||||||
|
void visit(source::string_literal *string) 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;
|
||||||
|
@ -8,11 +8,20 @@
|
|||||||
enum elna_tree_index
|
enum elna_tree_index
|
||||||
{
|
{
|
||||||
ELNA_TI_CHAR_TYPE,
|
ELNA_TI_CHAR_TYPE,
|
||||||
|
ELNA_TI_STRING_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 elna_char_type_node elna_global_trees[ELNA_TI_CHAR_TYPE]
|
#define elna_char_type_node elna_global_trees[ELNA_TI_CHAR_TYPE]
|
||||||
|
#define elna_string_type_node elna_global_trees[ELNA_TI_STRING_TYPE]
|
||||||
|
|
||||||
void elna_init_ttree(void);
|
namespace elna
|
||||||
|
{
|
||||||
|
namespace gcc
|
||||||
|
{
|
||||||
|
void init_ttree();
|
||||||
|
bool is_string_type(tree type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "elna/source/result.h"
|
#include "elna/source/result.h"
|
||||||
#include "elna/source/types.h"
|
#include "elna/source/types.h"
|
||||||
|
|
||||||
@ -49,6 +51,7 @@ namespace source
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class number_literal;
|
class number_literal;
|
||||||
class char_literal;
|
class char_literal;
|
||||||
|
class string_literal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for AST visitors.
|
* Interface for AST visitors.
|
||||||
@ -73,6 +76,7 @@ namespace source
|
|||||||
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(char_literal *) = 0;
|
virtual void visit(char_literal *) = 0;
|
||||||
|
virtual void visit(string_literal *) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +84,7 @@ namespace source
|
|||||||
*/
|
*/
|
||||||
struct empty_visitor : parser_visitor
|
struct empty_visitor : parser_visitor
|
||||||
{
|
{
|
||||||
virtual void visit(declaration *declaration) override;
|
virtual void visit(declaration *) override;
|
||||||
virtual void visit(constant_definition *definition) override;
|
virtual void visit(constant_definition *definition) override;
|
||||||
virtual void visit(procedure_definition *definition) override;
|
virtual void visit(procedure_definition *definition) override;
|
||||||
virtual void visit(call_statement *statement) override;
|
virtual void visit(call_statement *statement) override;
|
||||||
@ -92,12 +96,13 @@ 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 *variable) override;
|
virtual void visit(type_expression *) override;
|
||||||
virtual void visit(variable_expression *variable) override;
|
virtual void visit(variable_expression *) override;
|
||||||
virtual void visit(number_literal<std::int32_t> *number) override;
|
virtual void visit(number_literal<std::int32_t> *) override;
|
||||||
virtual void visit(number_literal<double> *number) override;
|
virtual void visit(number_literal<double> *) override;
|
||||||
virtual void visit(number_literal<bool> *boolean) override;
|
virtual void visit(number_literal<bool> *) override;
|
||||||
virtual void visit(char_literal *character) override;
|
virtual void visit(char_literal *) override;
|
||||||
|
virtual void visit(string_literal *) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -408,9 +413,9 @@ namespace source
|
|||||||
|
|
||||||
class block : public node
|
class block : public node
|
||||||
{
|
{
|
||||||
std::unique_ptr<statement> m_body;
|
|
||||||
std::vector<std::unique_ptr<definition>> m_definitions;
|
std::vector<std::unique_ptr<definition>> m_definitions;
|
||||||
std::vector<std::unique_ptr<declaration>> m_declarations;
|
std::vector<std::unique_ptr<declaration>> m_declarations;
|
||||||
|
std::unique_ptr<statement> m_body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
block(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions,
|
block(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions,
|
||||||
@ -465,6 +470,17 @@ namespace source
|
|||||||
unsigned char character() const noexcept;
|
unsigned char character() const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class string_literal : public expression
|
||||||
|
{
|
||||||
|
std::string m_string;
|
||||||
|
|
||||||
|
public:
|
||||||
|
string_literal(const struct position position, const std::string& value);
|
||||||
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
|
const std::string& string() const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
class variable_expression : public expression
|
class variable_expression : public expression
|
||||||
{
|
{
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
@ -7,7 +7,7 @@ namespace elna
|
|||||||
{
|
{
|
||||||
namespace source
|
namespace source
|
||||||
{
|
{
|
||||||
void empty_visitor::visit(declaration *declaration)
|
void empty_visitor::visit(declaration *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,27 +87,31 @@ namespace source
|
|||||||
expression->operand().accept(this);
|
expression->operand().accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(type_expression *variable)
|
void empty_visitor::visit(type_expression *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(variable_expression *variable)
|
void empty_visitor::visit(variable_expression *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(number_literal<std::int32_t> *number)
|
void empty_visitor::visit(number_literal<std::int32_t> *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(number_literal<double> *number)
|
void empty_visitor::visit(number_literal<double> *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(number_literal<bool> *character)
|
void empty_visitor::visit(number_literal<bool> *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(char_literal *character)
|
void empty_visitor::visit(char_literal *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void empty_visitor::visit(string_literal *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,6 +317,21 @@ namespace source
|
|||||||
return m_character;
|
return m_character;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string_literal::string_literal(const struct position position, const std::string& value)
|
||||||
|
: expression(position), m_string(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_literal::accept(parser_visitor *visitor)
|
||||||
|
{
|
||||||
|
visitor->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& string_literal::string() const noexcept
|
||||||
|
{
|
||||||
|
return m_string;
|
||||||
|
}
|
||||||
|
|
||||||
variable_expression::variable_expression(const struct position position, const std::string& name)
|
variable_expression::variable_expression(const struct position position, const std::string& name)
|
||||||
: expression(position), m_name(name)
|
: expression(position), m_name(name)
|
||||||
{
|
{
|
||||||
@ -550,6 +569,7 @@ namespace source
|
|||||||
case binary_operator::greater_equal:
|
case binary_operator::greater_equal:
|
||||||
return ">=";
|
return ">=";
|
||||||
}
|
}
|
||||||
|
__builtin_unreachable();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,10 @@ false {
|
|||||||
return yy::parser::make_CHARACTER(
|
return yy::parser::make_CHARACTER(
|
||||||
std::string(yytext, 1, strlen(yytext) - 2), this->location);
|
std::string(yytext, 1, strlen(yytext) - 2), this->location);
|
||||||
}
|
}
|
||||||
|
\"[^\"]*\" {
|
||||||
|
return yy::parser::make_STRING(
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
%token <std::int32_t> INTEGER "integer"
|
%token <std::int32_t> INTEGER "integer"
|
||||||
%token <float> FLOAT "float"
|
%token <float> FLOAT "float"
|
||||||
%token <std::string> CHARACTER "character"
|
%token <std::string> CHARACTER "character"
|
||||||
|
%token <std::string> STRING "string"
|
||||||
%token <bool> BOOLEAN
|
%token <bool> BOOLEAN
|
||||||
%token IF WHILE DO
|
%token IF WHILE DO
|
||||||
%token CONST VAR PROCEDURE
|
%token CONST VAR PROCEDURE
|
||||||
@ -76,6 +77,7 @@
|
|||||||
%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::number_literal<bool>>> 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::char_literal>> character_literal;
|
||||||
|
%type <std::unique_ptr<elna::source::string_literal>> string_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;
|
||||||
@ -153,7 +155,11 @@ float_literal: FLOAT
|
|||||||
};
|
};
|
||||||
character_literal: CHARACTER
|
character_literal: CHARACTER
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::char_literal>(elna::source::make_position(@1), $1[0]);
|
$$ = std::make_unique<elna::source::char_literal>(elna::source::make_position(@1), $1.at(0));
|
||||||
|
};
|
||||||
|
string_literal: STRING
|
||||||
|
{
|
||||||
|
$$ = std::make_unique<elna::source::string_literal>(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
boolean_literal: BOOLEAN
|
boolean_literal: BOOLEAN
|
||||||
{
|
{
|
||||||
@ -194,6 +200,7 @@ pointer:
|
|||||||
| 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); }
|
| character_literal { $$ = std::move($1); }
|
||||||
|
| string_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