Introduce float type
This commit is contained in:
@ -30,7 +30,6 @@ elna_OBJS = \
|
||||
elna/lexer.o \
|
||||
elna/parser.o \
|
||||
elna/result.o \
|
||||
elna/semantic.o \
|
||||
elna/symbol_table.o \
|
||||
elna/types.o \
|
||||
$(END)
|
||||
|
@ -22,11 +22,11 @@ namespace gcc
|
||||
}
|
||||
else if (type == boolean_type_node)
|
||||
{
|
||||
return "Boolean";
|
||||
return "Bool";
|
||||
}
|
||||
else if (type == enumeral_node)
|
||||
else if (type == double_type_node)
|
||||
{
|
||||
return "Enum";
|
||||
return "Float";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "gimplify.h"
|
||||
#include "stringpool.h"
|
||||
#include "diagnostic.h"
|
||||
#include "realmpfr.h"
|
||||
|
||||
namespace elna
|
||||
{
|
||||
@ -31,20 +32,27 @@ namespace gcc
|
||||
auto& argument = statement->arguments().at(0);
|
||||
argument->accept(this);
|
||||
auto argument_type = TREE_TYPE(this->current_expression);
|
||||
auto argument_tree = this->current_expression;
|
||||
this->current_expression = NULL_TREE;
|
||||
|
||||
if (argument_type != integer_type_node)
|
||||
const char *format_number{ nullptr };
|
||||
if (argument_type == integer_type_node)
|
||||
{
|
||||
format_number = "%d\n";
|
||||
}
|
||||
else if (argument_type == double_type_node)
|
||||
{
|
||||
format_number = "%f\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(get_location(&argument->position()),
|
||||
"invalid argument of type %s for procedure %s",
|
||||
print_type(argument_type), statement->name().c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
constexpr const char *format_integer = "%d\n";
|
||||
tree args[] = {
|
||||
build_string_literal(strlen(format_integer) + 1, format_integer),
|
||||
argument_tree
|
||||
build_string_literal(strlen(format_number) + 1, format_number),
|
||||
this->current_expression
|
||||
};
|
||||
tree fndecl_type_param[] = {
|
||||
build_pointer_type(build_qualified_type(char_type_node, TYPE_QUAL_CONST)) /* const char* */
|
||||
@ -52,13 +60,14 @@ namespace gcc
|
||||
tree fndecl_type = build_varargs_function_type_array(integer_type_node, 1, fndecl_type_param);
|
||||
|
||||
tree printf_fn_decl = build_fn_decl("printf", fndecl_type);
|
||||
DECL_EXTERNAL (printf_fn_decl) = 1;
|
||||
DECL_EXTERNAL(printf_fn_decl) = 1;
|
||||
|
||||
tree printf_fn = build1(ADDR_EXPR, build_pointer_type(fndecl_type), printf_fn_decl);
|
||||
|
||||
tree stmt = build_call_array(integer_type_node, printf_fn, 2, args);
|
||||
|
||||
append_to_statement_list(stmt, &this->current_statements);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::program *program)
|
||||
@ -96,11 +105,26 @@ namespace gcc
|
||||
cgraph_node::finalize_function(this->main_fndecl, true);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::integer_literal *literal)
|
||||
void generic_visitor::visit(source::number_literal<std::int32_t> *literal)
|
||||
{
|
||||
this->current_expression = build_int_cst_type(integer_type_node, literal->number());
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::number_literal<double> *literal)
|
||||
{
|
||||
REAL_VALUE_TYPE real_value1;
|
||||
|
||||
mpfr_t number;
|
||||
mpfr_init2(number, SIGNIFICAND_BITS);
|
||||
mpfr_set_d(number, literal->number(), MPFR_RNDN);
|
||||
|
||||
real_from_mpfr(&real_value1, number, double_type_node, MPFR_RNDN);
|
||||
|
||||
this->current_expression = build_real(double_type_node, real_value1);
|
||||
|
||||
mpfr_clear(number);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::boolean_literal *literal)
|
||||
{
|
||||
this->current_expression = build_int_cst_type(boolean_type_node, literal->boolean());
|
||||
@ -120,28 +144,37 @@ namespace gcc
|
||||
tree_code operator_code = ERROR_MARK;
|
||||
tree target_type = error_mark_node;
|
||||
|
||||
if (left_type != right_type)
|
||||
{
|
||||
error_at(expression_location,
|
||||
"invalid operands of type %s and %s for operator %s",
|
||||
print_type(left_type), print_type(right_type),
|
||||
elna::source::print_binary_operator(expression->operation()));
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
switch (expression->operation())
|
||||
{
|
||||
case source::binary_operator::sum:
|
||||
operator_code = PLUS_EXPR;
|
||||
target_type = integer_type_node;
|
||||
target_type = left_type;
|
||||
break;
|
||||
case source::binary_operator::subtraction:
|
||||
operator_code = MINUS_EXPR;
|
||||
target_type = integer_type_node;
|
||||
target_type = left_type;
|
||||
break;
|
||||
case source::binary_operator::division:
|
||||
operator_code = TRUNC_DIV_EXPR;
|
||||
target_type = integer_type_node;
|
||||
target_type = left_type;
|
||||
break;
|
||||
case source::binary_operator::multiplication:
|
||||
operator_code = MULT_EXPR;
|
||||
target_type = integer_type_node;
|
||||
target_type = left_type;
|
||||
break;
|
||||
}
|
||||
if (operator_code != ERROR_MARK) // An arithmetic operation.
|
||||
{
|
||||
if (left_type != integer_type_node || right_type != integer_type_node)
|
||||
if (target_type != integer_type_node && target_type != double_type_node)
|
||||
{
|
||||
error_at(expression_location,
|
||||
"invalid operands of type %s and %s for operator %s",
|
||||
@ -178,15 +211,6 @@ namespace gcc
|
||||
target_type = boolean_type_node;
|
||||
break;
|
||||
}
|
||||
if (left_type != right_type)
|
||||
{
|
||||
error_at(expression_location,
|
||||
"invalid operands of type %s and %s for operator %s",
|
||||
print_type(left_type), print_type(right_type),
|
||||
elna::source::print_binary_operator(expression->operation()));
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
gcc_assert(operator_code != ERROR_MARK);
|
||||
gcc_assert(target_type != error_mark_node);
|
||||
|
||||
@ -234,6 +258,10 @@ namespace gcc
|
||||
{
|
||||
declaration_type = boolean_type_node;
|
||||
}
|
||||
else if (declaration->type().base() == "Float")
|
||||
{
|
||||
declaration_type = double_type_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(get_location(&declaration->type().position()),
|
||||
@ -385,8 +413,7 @@ namespace gcc
|
||||
{
|
||||
statement->prerequisite().accept(this);
|
||||
|
||||
if (TREE_TYPE(this->current_expression) != boolean_type_node
|
||||
&& TREE_TYPE(this->current_expression) != integer_type_node)
|
||||
if (TREE_TYPE(this->current_expression) != boolean_type_node)
|
||||
{
|
||||
error_at(get_location(&statement->prerequisite().position()),
|
||||
"expected expression of boolean type but its type is %s",
|
||||
|
Reference in New Issue
Block a user