Add string type

This commit is contained in:
2025-01-03 22:18:35 +01:00
parent 660c774327
commit a7b0c53d23
11 changed files with 202 additions and 76 deletions

View File

@ -32,6 +32,10 @@ namespace gcc
{
return "Char";
}
else if (is_string_type(type))
{
return "String";
}
else
{
return "<<unknown-type>>";

View File

@ -25,7 +25,7 @@ namespace gcc
if (statement->arguments().size() != 1)
{
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());
return;
}
@ -46,6 +46,10 @@ namespace gcc
{
format_number = "%c\n";
}
else if (is_string_type(argument_type))
{
format_number = "%s\n";
}
else
{
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);
this->main_fndecl = build_fn_decl("main", main_fndecl_type);
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;
tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(main_fndecl),
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());
}
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)
{
expression->lhs().accept(this);
@ -180,6 +190,8 @@ namespace gcc
operator_code = MULT_EXPR;
target_type = left_type;
break;
default:
break;
}
if (operator_code != ERROR_MARK) // An arithmetic operation.
{
@ -219,6 +231,8 @@ namespace gcc
operator_code = GE_EXPR;
target_type = boolean_type_node;
break;
default:
break;
}
gcc_assert(operator_code != ERROR_MARK);
gcc_assert(target_type != error_mark_node);
@ -275,6 +289,10 @@ namespace gcc
{
declaration_type = elna_char_type_node;
}
else if (declaration->type().base() == "String")
{
declaration_type = elna_string_type_node;
}
else
{
error_at(get_location(&declaration->type().position()),
@ -286,6 +304,7 @@ namespace gcc
get_identifier(declaration->identifier().c_str()), declaration_type);
auto result = this->symbol_map.insert({ declaration->identifier(), declaration_tree });
// DECL_CONTEXT(declaration_tree) = this->main_fndecl;
if (result.second)
{
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,

View File

@ -4,8 +4,23 @@
tree elna_global_trees[ELNA_TI_MAX];
void elna_init_ttree(void)
namespace elna
{
elna_char_type_node = make_unsigned_type(8);
TYPE_STRING_FLAG(elna_char_type_node) = 1;
namespace gcc
{
void init_ttree()
{
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;
}
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;
}
}
}

View File

@ -25,14 +25,14 @@
struct GTY (()) lang_type
{
char dummy;
char dummy;
};
/* Language-dependent contents of a decl. */
struct GTY (()) lang_decl
{
char dummy;
char dummy;
};
/* Language-dependent contents of an identifier. This must include a
@ -40,7 +40,7 @@ struct GTY (()) lang_decl
struct GTY (()) lang_identifier
{
struct tree_identifier common;
struct tree_identifier common;
};
/* The resulting tree type. */
@ -50,15 +50,15 @@ union GTY ((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
"TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN "
"(&%h.generic)) : NULL"))) lang_tree_node
{
union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
struct lang_identifier GTY ((tag ("1"))) identifier;
union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
struct lang_identifier GTY ((tag ("1"))) identifier;
};
/* We don't use language_function. */
struct GTY (()) language_function
{
int dummy;
int dummy;
};
/* Language hooks. */
@ -66,9 +66,8 @@ struct GTY (()) language_function
static bool elna_langhook_init(void)
{
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);
build_common_builtin_nodes();
@ -82,7 +81,7 @@ static void elna_parse_file(const char *filename)
if (!file)
{
fatal_error(UNKNOWN_LOCATION, "cannot open filename %s: %m", filename);
fatal_error(UNKNOWN_LOCATION, "cannot open filename %s: %m", filename);
}
elna::source::driver driver{ filename };
@ -90,7 +89,7 @@ static void elna_parse_file(const char *filename)
yy::parser parser(lexer, driver);
linemap_add(line_table, LC_ENTER, 0, filename, 1);
if (auto result = parser())
if (parser())
{
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)
{
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
elna_langhook_type_for_mode (enum machine_mode mode, int unsignedp)
static tree elna_langhook_type_for_mode(enum machine_mode mode, int unsignedp)
{
if (mode == TYPE_MODE (float_type_node))
return float_type_node;
if (mode == TYPE_MODE (double_type_node))
return double_type_node;
if (mode == TYPE_MODE (intQI_type_node))
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
if (mode == TYPE_MODE (intHI_type_node))
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
if (mode == TYPE_MODE (intSI_type_node))
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
if (mode == TYPE_MODE (intDI_type_node))
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
if (mode == TYPE_MODE (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
if (mode == TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
if (mode == TYPE_MODE (long_integer_type_node))
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (mode == TYPE_MODE (long_long_integer_type_node))
return unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node;
if (COMPLEX_MODE_P (mode))
if (mode == TYPE_MODE(float_type_node))
{
if (mode == TYPE_MODE (complex_float_type_node))
return complex_float_type_node;
if (mode == TYPE_MODE (complex_double_type_node))
return complex_double_type_node;
if (mode == TYPE_MODE (complex_long_double_type_node))
return complex_long_double_type_node;
if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
return complex_integer_type_node;
return float_type_node;
}
/* gcc_unreachable */
return NULL;
else if (mode == TYPE_MODE(double_type_node))
{
return double_type_node;
}
if (mode == TYPE_MODE(intQI_type_node))
{
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
}
else if (mode == TYPE_MODE(intHI_type_node))
{
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
}
else if (mode == TYPE_MODE(intSI_type_node))
{
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
}
else if (mode == TYPE_MODE(intDI_type_node))
{
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
}
else if (mode == TYPE_MODE(intTI_type_node))
{
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
}
else if (mode == TYPE_MODE(integer_type_node))
{
return unsignedp ? unsigned_type_node : integer_type_node;
}
else if (mode == TYPE_MODE(long_integer_type_node))
{
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
}
else if (mode == TYPE_MODE(long_long_integer_type_node))
{
return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node;
}
if (COMPLEX_MODE_P(mode))
{
if (mode == TYPE_MODE(complex_float_type_node))
{
return complex_float_type_node;
}
if (mode == TYPE_MODE(complex_double_type_node))
{
return complex_double_type_node;
}
if (mode == TYPE_MODE(complex_long_double_type_node))
{
return complex_long_double_type_node;
}
if (mode == TYPE_MODE(complex_integer_type_node) && !unsignedp)
{
return complex_integer_type_node;
}
}
/* gcc_unreachable */
return nullptr;
}
static tree elna_langhook_type_for_size(unsigned int bits ATTRIBUTE_UNUSED,