Implement constants

This commit is contained in:
Eugen Wissner 2024-12-29 22:28:53 +01:00
parent 20949c7829
commit c558c3d6b4
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
7 changed files with 85 additions and 29 deletions

View File

@ -24,6 +24,7 @@ elna_OBJS = \
elna/elna-generic.o \
elna/elna-convert.o \
elna/elna-diagnostic.o \
elna/elna-tree.o \
elna/ast.o \
elna/driver.o \
elna/lexer.o \

View File

@ -1,4 +1,5 @@
#include "elna/gcc/elna-diagnostic.h"
#include "elna/gcc/elna-tree.h"
namespace elna
{
@ -23,6 +24,10 @@ namespace gcc
{
return "Boolean";
}
else if (type == enumeral_node)
{
return "Enum";
}
else
{
return "<<unknown-type>>";

View File

@ -1,4 +1,5 @@
#include "elna/gcc/elna-generic.h"
#include "elna/gcc/elna-tree.h"
#include "elna/gcc/elna-diagnostic.h"
#include "input.h"
@ -97,12 +98,12 @@ namespace gcc
void generic_visitor::visit(source::integer_literal *literal)
{
current_expression = build_int_cst_type(integer_type_node, literal->number());
this->current_expression = build_int_cst_type(integer_type_node, literal->number());
}
void generic_visitor::visit(source::boolean_literal *literal)
{
current_expression = build_int_cst_type(boolean_type_node, literal->boolean());
this->current_expression = build_int_cst_type(boolean_type_node, literal->boolean());
}
void generic_visitor::visit(source::binary_expression *expression)
@ -179,6 +180,34 @@ namespace gcc
operator_code, integer_type_node, left, right);
}
void generic_visitor::visit(source::constant_definition *definition)
{
location_t definition_location = get_location(&definition->position());
tree definition_tree = build_decl(definition_location, CONST_DECL,
get_identifier(definition->identifier().c_str()), integer_type_node);
auto result = this->symbol_map.insert({ definition->identifier(), definition_tree });
if (result.second)
{
definition->body().accept(this);
DECL_INITIAL(definition_tree) = build_int_cst_type(integer_type_node, definition->body().number());
TREE_CONSTANT(definition_tree) = 1;
TREE_READONLY(definition_tree) = 1;
auto declaration_statement = build1_loc(definition_location, DECL_EXPR,
void_type_node, definition_tree);
append_to_statement_list(declaration_statement, &this->current_statements);
}
else
{
error_at(definition_location,
"variable '%s' already declared in this scope",
definition->identifier().c_str());
}
this->current_expression = NULL_TREE;
}
void generic_visitor::visit(source::declaration *declaration)
{
if (declaration->type().base() != "Int" && declaration->type().base() != "Bool")
@ -236,9 +265,16 @@ namespace gcc
}
statement->rvalue().accept(this);
if (TREE_CODE(lvalue->second) == CONST_DECL)
{
error_at(statement_location, "cannot modify constant '%s'",
statement->lvalue().c_str());
this->current_expression = error_mark_node;
return;
}
if (TREE_TYPE(this->current_expression) != TREE_TYPE(lvalue->second))
{
error_at(get_location(&statement->position()),
error_at(statement_location,
"cannot assign value of type %s to variable '%s' of type %s",
print_type(TREE_TYPE(this->current_expression)),
statement->lvalue().c_str(),

3
gcc/elna-tree.cc Normal file
View File

@ -0,0 +1,3 @@
#include "elna/gcc/elna-tree.h"
tree elna_global_trees[ELNA_TI_MAX];

View File

@ -16,6 +16,7 @@
#include <fstream>
#include <elna/source/driver.h>
#include "elna/gcc/elna-tree.h"
#include "elna/gcc/elna-generic.h"
#include "elna/gcc/elna-diagnostic.h"
#include "parser.hh"
@ -64,17 +65,18 @@ struct GTY (()) language_function
static bool elna_langhook_init(void)
{
build_common_tree_nodes (false);
build_common_tree_nodes(false);
enumeral_node = make_node(ENUMERAL_TYPE);
/* 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();
return true;
}
static void elna_parse_file (const char *filename)
static void elna_parse_file(const char *filename)
{
std::ifstream file{ filename, std::ios::in };
@ -106,8 +108,7 @@ static void elna_parse_file (const char *filename)
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
}
static void
elna_langhook_parse_file (void)
static void elna_langhook_parse_file(void)
{
for (int i = 0; i < num_in_fnames; i++)
{
@ -161,37 +162,30 @@ elna_langhook_type_for_mode (enum machine_mode mode, int unsignedp)
return NULL;
}
static tree
elna_langhook_type_for_size (unsigned int bits ATTRIBUTE_UNUSED,
static tree elna_langhook_type_for_size(unsigned int bits ATTRIBUTE_UNUSED,
int unsignedp ATTRIBUTE_UNUSED)
{
gcc_unreachable ();
return NULL;
gcc_unreachable();
}
/* Record a builtin function. We just ignore builtin functions. */
static tree
elna_langhook_builtin_function (tree decl)
static tree elna_langhook_builtin_function(tree decl)
{
return decl;
}
static bool
elna_langhook_global_bindings_p (void)
static bool elna_langhook_global_bindings_p(void)
{
gcc_unreachable ();
return true;
gcc_unreachable();
}
static tree
elna_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
static tree elna_langhook_pushdecl(tree decl ATTRIBUTE_UNUSED)
{
gcc_unreachable ();
gcc_unreachable();
}
static tree
elna_langhook_getdecls (void)
static tree elna_langhook_getdecls(void)
{
return NULL;
}

View File

@ -30,6 +30,7 @@ namespace gcc
void visit(source::integer_literal *literal) override;
void visit(source::boolean_literal *literal) override;
void visit(source::binary_expression *expression) override;
void visit(source::constant_definition *definition) override;
void visit(source::declaration *declaration) override;
void visit(source::variable_expression *expression) override;
void visit(source::assign_statement *statement) override;

View File

@ -0,0 +1,16 @@
#pragma once
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
enum elna_tree_index
{
ELNA_TI_ENUMERAL_TYPE,
ELNA_TI_MAX
};
extern GTY(()) tree elna_global_trees[ELNA_TI_MAX];
#define enumeral_node elna_global_trees[ELNA_TI_ENUMERAL_TYPE]