Implement constants
This commit is contained in:
parent
20949c7829
commit
c558c3d6b4
@ -24,6 +24,7 @@ elna_OBJS = \
|
|||||||
elna/elna-generic.o \
|
elna/elna-generic.o \
|
||||||
elna/elna-convert.o \
|
elna/elna-convert.o \
|
||||||
elna/elna-diagnostic.o \
|
elna/elna-diagnostic.o \
|
||||||
|
elna/elna-tree.o \
|
||||||
elna/ast.o \
|
elna/ast.o \
|
||||||
elna/driver.o \
|
elna/driver.o \
|
||||||
elna/lexer.o \
|
elna/lexer.o \
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "elna/gcc/elna-diagnostic.h"
|
#include "elna/gcc/elna-diagnostic.h"
|
||||||
|
#include "elna/gcc/elna-tree.h"
|
||||||
|
|
||||||
namespace elna
|
namespace elna
|
||||||
{
|
{
|
||||||
@ -23,6 +24,10 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
return "Boolean";
|
return "Boolean";
|
||||||
}
|
}
|
||||||
|
else if (type == enumeral_node)
|
||||||
|
{
|
||||||
|
return "Enum";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return "<<unknown-type>>";
|
return "<<unknown-type>>";
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "elna/gcc/elna-generic.h"
|
#include "elna/gcc/elna-generic.h"
|
||||||
|
#include "elna/gcc/elna-tree.h"
|
||||||
#include "elna/gcc/elna-diagnostic.h"
|
#include "elna/gcc/elna-diagnostic.h"
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
@ -97,12 +98,12 @@ namespace gcc
|
|||||||
|
|
||||||
void generic_visitor::visit(source::integer_literal *literal)
|
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)
|
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)
|
void generic_visitor::visit(source::binary_expression *expression)
|
||||||
@ -179,6 +180,34 @@ namespace gcc
|
|||||||
operator_code, integer_type_node, left, right);
|
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)
|
void generic_visitor::visit(source::declaration *declaration)
|
||||||
{
|
{
|
||||||
if (declaration->type().base() != "Int" && declaration->type().base() != "Bool")
|
if (declaration->type().base() != "Int" && declaration->type().base() != "Bool")
|
||||||
@ -236,9 +265,16 @@ namespace gcc
|
|||||||
}
|
}
|
||||||
statement->rvalue().accept(this);
|
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))
|
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",
|
"cannot assign value of type %s to variable '%s' of type %s",
|
||||||
print_type(TREE_TYPE(this->current_expression)),
|
print_type(TREE_TYPE(this->current_expression)),
|
||||||
statement->lvalue().c_str(),
|
statement->lvalue().c_str(),
|
||||||
|
3
gcc/elna-tree.cc
Normal file
3
gcc/elna-tree.cc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "elna/gcc/elna-tree.h"
|
||||||
|
|
||||||
|
tree elna_global_trees[ELNA_TI_MAX];
|
46
gcc/elna1.cc
46
gcc/elna1.cc
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <elna/source/driver.h>
|
#include <elna/source/driver.h>
|
||||||
|
#include "elna/gcc/elna-tree.h"
|
||||||
#include "elna/gcc/elna-generic.h"
|
#include "elna/gcc/elna-generic.h"
|
||||||
#include "elna/gcc/elna-diagnostic.h"
|
#include "elna/gcc/elna-diagnostic.h"
|
||||||
#include "parser.hh"
|
#include "parser.hh"
|
||||||
@ -64,17 +65,18 @@ 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);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
build_common_builtin_nodes ();
|
build_common_builtin_nodes();
|
||||||
|
|
||||||
return true;
|
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 };
|
std::ifstream file{ filename, std::ios::in };
|
||||||
|
|
||||||
@ -106,12 +108,11 @@ static void elna_parse_file (const char *filename)
|
|||||||
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
|
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void elna_langhook_parse_file(void)
|
||||||
elna_langhook_parse_file (void)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num_in_fnames; i++)
|
for (int i = 0; i < num_in_fnames; i++)
|
||||||
{
|
{
|
||||||
elna_parse_file (in_fnames[i]);
|
elna_parse_file (in_fnames[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,39 +162,32 @@ elna_langhook_type_for_mode (enum machine_mode mode, int unsignedp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tree
|
static tree elna_langhook_type_for_size(unsigned int bits ATTRIBUTE_UNUSED,
|
||||||
elna_langhook_type_for_size (unsigned int bits ATTRIBUTE_UNUSED,
|
int unsignedp ATTRIBUTE_UNUSED)
|
||||||
int unsignedp ATTRIBUTE_UNUSED)
|
|
||||||
{
|
{
|
||||||
gcc_unreachable ();
|
gcc_unreachable();
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record a builtin function. We just ignore builtin functions. */
|
/* Record a builtin function. We just ignore builtin functions. */
|
||||||
|
|
||||||
static tree
|
static tree elna_langhook_builtin_function(tree decl)
|
||||||
elna_langhook_builtin_function (tree decl)
|
|
||||||
{
|
{
|
||||||
return decl;
|
return decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool elna_langhook_global_bindings_p(void)
|
||||||
elna_langhook_global_bindings_p (void)
|
|
||||||
{
|
{
|
||||||
gcc_unreachable ();
|
gcc_unreachable();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static tree
|
static tree elna_langhook_pushdecl(tree decl ATTRIBUTE_UNUSED)
|
||||||
elna_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
|
|
||||||
{
|
{
|
||||||
gcc_unreachable ();
|
gcc_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static tree
|
static tree elna_langhook_getdecls(void)
|
||||||
elna_langhook_getdecls (void)
|
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef LANG_HOOKS_NAME
|
#undef LANG_HOOKS_NAME
|
||||||
|
@ -30,6 +30,7 @@ namespace gcc
|
|||||||
void visit(source::integer_literal *literal) override;
|
void visit(source::integer_literal *literal) override;
|
||||||
void visit(source::boolean_literal *literal) override;
|
void visit(source::boolean_literal *literal) 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::declaration *declaration) override;
|
void visit(source::declaration *declaration) override;
|
||||||
void visit(source::variable_expression *expression) override;
|
void visit(source::variable_expression *expression) override;
|
||||||
void visit(source::assign_statement *statement) override;
|
void visit(source::assign_statement *statement) override;
|
||||||
|
16
include/elna/gcc/elna-tree.h
Normal file
16
include/elna/gcc/elna-tree.h
Normal 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]
|
Loading…
x
Reference in New Issue
Block a user