Read the input filename from the command line
This commit is contained in:
parent
b41d6fb907
commit
607bf09434
27
boot/ast.cc
27
boot/ast.cc
@ -92,9 +92,13 @@ namespace boot
|
|||||||
|
|
||||||
void empty_visitor::visit(block *block)
|
void empty_visitor::visit(block *block)
|
||||||
{
|
{
|
||||||
for (const auto definition : block->value_definitions)
|
for (const auto constant : block->constants)
|
||||||
{
|
{
|
||||||
definition->accept(this);
|
constant->accept(this);
|
||||||
|
}
|
||||||
|
for (const auto variable : block->variables)
|
||||||
|
{
|
||||||
|
variable->accept(this);
|
||||||
}
|
}
|
||||||
for (const auto body_statement : block->body)
|
for (const auto body_statement : block->body)
|
||||||
{
|
{
|
||||||
@ -474,9 +478,8 @@ namespace boot
|
|||||||
delete m_body;
|
delete m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
block::block(const struct position position, std::vector<definition *>&& value_definitions,
|
block::block(const struct position position)
|
||||||
std::vector<statement *>&& body)
|
: node(position)
|
||||||
: node(position), value_definitions(std::move(value_definitions)), body(std::move(body))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,9 +490,13 @@ namespace boot
|
|||||||
|
|
||||||
block::~block()
|
block::~block()
|
||||||
{
|
{
|
||||||
for (auto definition : this->value_definitions)
|
for (auto variable : this->variables)
|
||||||
{
|
{
|
||||||
delete definition;
|
delete variable;
|
||||||
|
}
|
||||||
|
for (auto constant : this->constants)
|
||||||
|
{
|
||||||
|
delete constant;
|
||||||
}
|
}
|
||||||
for (auto body_statement : this->body)
|
for (auto body_statement : this->body)
|
||||||
{
|
{
|
||||||
@ -497,10 +504,8 @@ namespace boot
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
program::program(const struct position position,
|
program::program(const struct position position, std::vector<definition *>&& type_definitions)
|
||||||
std::vector<definition *>&& type_definitions,
|
: block(position),
|
||||||
std::vector<definition *>&& value_definitions, std::vector<statement *>&& body)
|
|
||||||
: block(position, std::move(value_definitions), std::move(body)),
|
|
||||||
type_definitions(std::move(type_definitions))
|
type_definitions(std::move(type_definitions))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -111,49 +111,34 @@
|
|||||||
%type <elna::boot::cast_expression *> cast_expression;
|
%type <elna::boot::cast_expression *> cast_expression;
|
||||||
%%
|
%%
|
||||||
program:
|
program:
|
||||||
type_part constant_part procedure_part variable_part BEGIN_BLOCK optional_statements END_BLOCK DOT
|
type_part constant_part variable_part procedure_part BEGIN_BLOCK optional_statements END_BLOCK DOT
|
||||||
{
|
{
|
||||||
std::vector<elna::boot::definition *> definitions($1.size() + $3.size());
|
std::vector<elna::boot::definition *> definitions($1.size() + $4.size());
|
||||||
std::vector<elna::boot::definition *>::iterator definition = definitions.begin();
|
std::vector<elna::boot::definition *>::iterator definition = definitions.begin();
|
||||||
std::vector<elna::boot::definition *> value_definitions($2.size() + $4.size());
|
|
||||||
std::vector<elna::boot::definition *>::iterator value_definition = value_definitions.begin();
|
|
||||||
|
|
||||||
for (auto type : $1)
|
for (auto type : $1)
|
||||||
{
|
{
|
||||||
*definition++ = type;
|
*definition++ = type;
|
||||||
}
|
}
|
||||||
for (auto constant : $2)
|
for (auto procedure : $4)
|
||||||
{
|
|
||||||
*value_definition++ = constant;
|
|
||||||
}
|
|
||||||
for (auto procedure : $3)
|
|
||||||
{
|
{
|
||||||
*definition++ = procedure;
|
*definition++ = procedure;
|
||||||
}
|
}
|
||||||
for (auto variable : $4)
|
auto tree = new elna::boot::program(elna::boot::make_position(@5), std::move(definitions));
|
||||||
{
|
|
||||||
*value_definition++ = variable;
|
std::swap(tree->constants, $2);
|
||||||
}
|
std::swap(tree->variables, $3);
|
||||||
auto tree = new elna::boot::program(elna::boot::make_position(@5),
|
std::swap(tree->body, $6);
|
||||||
std::move(definitions), std::move(value_definitions), std::move($6));
|
|
||||||
|
|
||||||
driver.tree.reset(tree);
|
driver.tree.reset(tree);
|
||||||
}
|
}
|
||||||
block: constant_part variable_part BEGIN_BLOCK optional_statements END_BLOCK
|
block: constant_part variable_part BEGIN_BLOCK optional_statements END_BLOCK
|
||||||
{
|
{
|
||||||
std::vector<elna::boot::definition *> definitions($1.size() + $2.size());
|
$$ = new elna::boot::block(elna::boot::make_position(@3));
|
||||||
std::vector<elna::boot::definition *>::iterator definition = definitions.begin();
|
|
||||||
|
|
||||||
for (auto constant : $1)
|
std::swap($$->constants, $1);
|
||||||
{
|
std::swap($$->variables, $2);
|
||||||
*definition++ = constant;
|
std::swap($$->body, $4);
|
||||||
}
|
|
||||||
for (auto variable : $2)
|
|
||||||
{
|
|
||||||
*definition++ = variable;
|
|
||||||
}
|
|
||||||
$$ = new elna::boot::block(elna::boot::make_position(@3),
|
|
||||||
std::move(definitions), std::move($4));
|
|
||||||
}
|
}
|
||||||
procedure_definition:
|
procedure_definition:
|
||||||
PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON
|
PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON
|
||||||
|
@ -36,10 +36,6 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
return "Char";
|
return "Char";
|
||||||
}
|
}
|
||||||
else if (is_string_type(type))
|
|
||||||
{
|
|
||||||
return "String";
|
|
||||||
}
|
|
||||||
else if (is_pointer_type(type))
|
else if (is_pointer_type(type))
|
||||||
{
|
{
|
||||||
return "pointer";
|
return "pointer";
|
||||||
|
@ -86,16 +86,44 @@ namespace gcc
|
|||||||
|| type == this->symbol_map->lookup("Word")->payload;
|
|| type == this->symbol_map->lookup("Word")->payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool generic_visitor::is_numeric_type(tree type)
|
||||||
|
{
|
||||||
|
return is_integral_type(type)
|
||||||
|
|| type == this->symbol_map->lookup("Float")->payload;
|
||||||
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::program *program)
|
void generic_visitor::visit(boot::program *program)
|
||||||
{
|
{
|
||||||
for (const auto definition : program->value_definitions)
|
for (const auto& type_definition : program->type_definitions)
|
||||||
{
|
{
|
||||||
definition->accept(this);
|
type_definition->accept(this);
|
||||||
}
|
}
|
||||||
for (const auto& constant : program->type_definitions)
|
for (const auto constant : program->constants)
|
||||||
{
|
{
|
||||||
constant->accept(this);
|
constant->accept(this);
|
||||||
}
|
}
|
||||||
|
for (const auto declaration : program->variables)
|
||||||
|
{
|
||||||
|
tree declaration_type = build_type(declaration->type());
|
||||||
|
gcc_assert(declaration_type != NULL_TREE);
|
||||||
|
|
||||||
|
auto declaration_location = get_location(&declaration->position());
|
||||||
|
tree declaration_tree = build_decl(declaration_location, VAR_DECL,
|
||||||
|
get_identifier(declaration->identifier().c_str()), declaration_type);
|
||||||
|
auto result = this->symbol_map->enter(declaration->identifier(), boot::make_info(declaration_tree));
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
TREE_STATIC(declaration_tree) = 1;
|
||||||
|
varpool_node::get_create(declaration_tree);
|
||||||
|
varpool_node::finalize_decl(declaration_tree);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_at(declaration_location, "variable '%s' already declared in this scope",
|
||||||
|
declaration->identifier().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
std::array<tree, 2> parameter_types{
|
std::array<tree, 2> parameter_types{
|
||||||
integer_type_node,
|
integer_type_node,
|
||||||
build_pointer_type(build_pointer_type(char_type_node))
|
build_pointer_type(build_pointer_type(char_type_node))
|
||||||
@ -278,49 +306,57 @@ namespace gcc
|
|||||||
this->current_expression = build_string_literal(string->string().size() + 1, string->string().c_str());
|
this->current_expression = build_string_literal(string->string().size() + 1, string->string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::build_binary_operation(bool condition, boot::binary_expression *expression,
|
tree generic_visitor::build_arithmetic_operation(boot::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right, tree target_type)
|
tree_code operator_code, tree left, tree right)
|
||||||
{
|
{
|
||||||
auto expression_location = get_location(&expression->position());
|
return build_binary_operation(is_numeric_type(TREE_TYPE(left)),
|
||||||
auto left_type = TREE_TYPE(left);
|
expression, operator_code, left, right, TREE_TYPE(left));
|
||||||
auto right_type = TREE_TYPE(right);
|
}
|
||||||
|
|
||||||
if (condition)
|
tree generic_visitor::build_comparison_operation(boot::binary_expression *expression,
|
||||||
{
|
tree_code operator_code, tree left, tree right)
|
||||||
this->current_expression = build2_loc(expression_location,
|
{
|
||||||
operator_code, target_type, left, right);
|
return build_binary_operation(is_numeric_type(TREE_TYPE(left)) || is_pointer_type(TREE_TYPE(left)),
|
||||||
}
|
expression, operator_code, left, right, this->symbol_map->lookup("Bool")->payload);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
error_at(expression_location,
|
tree generic_visitor::build_logic_operation(boot::binary_expression *expression,
|
||||||
"invalid operands of type %s and %s for operator %s",
|
tree_code operator_code, tree left, tree right)
|
||||||
print_type(left_type), print_type(right_type),
|
{
|
||||||
elna::boot::print_binary_operator(expression->operation()));
|
auto symbol = this->symbol_map->lookup("Bool");
|
||||||
this->current_expression = error_mark_node;
|
|
||||||
}
|
return build_binary_operation(TREE_TYPE(left) == symbol->payload,
|
||||||
|
expression, operator_code, left, right, symbol->payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
tree generic_visitor::build_equality_operation(boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right)
|
||||||
|
{
|
||||||
|
return build_binary_operation(true, expression,
|
||||||
|
operator_code, left, right, this->symbol_map->lookup("Bool")->payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::binary_expression *expression)
|
void generic_visitor::visit(boot::binary_expression *expression)
|
||||||
{
|
{
|
||||||
expression->lhs().accept(this);
|
expression->lhs().accept(this);
|
||||||
auto left = this->current_expression;
|
tree left = this->current_expression;
|
||||||
auto left_type = TREE_TYPE(left);
|
tree left_type = TREE_TYPE(left);
|
||||||
|
|
||||||
expression->rhs().accept(this);
|
expression->rhs().accept(this);
|
||||||
auto right = this->current_expression;
|
tree right = this->current_expression;
|
||||||
auto right_type = TREE_TYPE(right);
|
tree right_type = TREE_TYPE(right);
|
||||||
|
|
||||||
auto expression_location = get_location(&expression->position());
|
location_t expression_location = get_location(&expression->position());
|
||||||
tree_code operator_code = ERROR_MARK;
|
|
||||||
tree target_type = error_mark_node;
|
|
||||||
|
|
||||||
if (is_pointer_type(left_type) && is_integral_type(right_type)
|
if (is_pointer_type(left_type) && is_integral_type(right_type))
|
||||||
&& expression->operation() == boot::binary_operator::sum)
|
|
||||||
{
|
{
|
||||||
tree convert_expression = build1_loc(expression_location, CONVERT_EXPR,
|
this->current_expression = do_pointer_arithmetic(expression->operation(), left, right);
|
||||||
sizetype, right);
|
if (this->current_expression == error_mark_node)
|
||||||
this->current_expression = build2_loc(expression_location,
|
{
|
||||||
POINTER_PLUS_EXPR, left_type, left, convert_expression);
|
error_at(expression_location,
|
||||||
|
"invalid operation %s on a pointer and an integral type",
|
||||||
|
boot::print_binary_operator(expression->operation()));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (left_type != right_type)
|
if (left_type != right_type)
|
||||||
@ -335,87 +371,45 @@ namespace gcc
|
|||||||
switch (expression->operation())
|
switch (expression->operation())
|
||||||
{
|
{
|
||||||
case boot::binary_operator::sum:
|
case boot::binary_operator::sum:
|
||||||
operator_code = PLUS_EXPR;
|
this->current_expression = build_arithmetic_operation(expression, PLUS_EXPR, left, right);
|
||||||
target_type = left_type;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::subtraction:
|
case boot::binary_operator::subtraction:
|
||||||
operator_code = MINUS_EXPR;
|
this->current_expression = build_arithmetic_operation(expression, MINUS_EXPR, left, right);
|
||||||
target_type = left_type;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::division:
|
case boot::binary_operator::division:
|
||||||
operator_code = TRUNC_DIV_EXPR;
|
this->current_expression = build_arithmetic_operation(expression, TRUNC_DIV_EXPR, left, right);
|
||||||
target_type = left_type;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::remainder:
|
case boot::binary_operator::remainder:
|
||||||
operator_code = TRUNC_MOD_EXPR;
|
this->current_expression = build_arithmetic_operation(expression, TRUNC_MOD_EXPR, left, right);
|
||||||
target_type = left_type;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::multiplication:
|
case boot::binary_operator::multiplication:
|
||||||
operator_code = MULT_EXPR;
|
this->current_expression = build_arithmetic_operation(expression, MULT_EXPR, left, right);
|
||||||
target_type = left_type;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::less:
|
case boot::binary_operator::less:
|
||||||
operator_code = LT_EXPR;
|
this->current_expression = build_comparison_operation(expression, LT_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::greater:
|
case boot::binary_operator::greater:
|
||||||
operator_code = GT_EXPR;
|
this->current_expression = build_comparison_operation(expression, GT_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::less_equal:
|
case boot::binary_operator::less_equal:
|
||||||
operator_code = LE_EXPR;
|
this->current_expression = build_comparison_operation(expression, LE_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::greater_equal:
|
case boot::binary_operator::greater_equal:
|
||||||
operator_code = GE_EXPR;
|
this->current_expression = build_comparison_operation(expression, GE_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (operator_code != ERROR_MARK) // An arithmetic operation.
|
|
||||||
{
|
|
||||||
build_binary_operation(is_integral_type(left_type) || left_type == double_type_node,
|
|
||||||
expression, operator_code, left, right, target_type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (expression->operation())
|
|
||||||
{
|
|
||||||
case boot::binary_operator::conjunction:
|
case boot::binary_operator::conjunction:
|
||||||
operator_code = TRUTH_ANDIF_EXPR;
|
this->current_expression = build_logic_operation(expression, TRUTH_ANDIF_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::disjunction:
|
case boot::binary_operator::disjunction:
|
||||||
operator_code = TRUTH_ORIF_EXPR;
|
this->current_expression = build_logic_operation(expression, TRUTH_ORIF_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (operator_code != ERROR_MARK) // A logical operation.
|
|
||||||
{
|
|
||||||
build_binary_operation(left_type == boolean_type_node,
|
|
||||||
expression, operator_code, left, right, target_type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (expression->operation())
|
|
||||||
{
|
|
||||||
case boot::binary_operator::equals:
|
case boot::binary_operator::equals:
|
||||||
operator_code = EQ_EXPR;
|
this->current_expression = build_equality_operation(expression, EQ_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::not_equals:
|
case boot::binary_operator::not_equals:
|
||||||
operator_code = NE_EXPR;
|
this->current_expression = build_equality_operation(expression, NE_EXPR, left, right);
|
||||||
target_type = boolean_type_node;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gcc_assert(operator_code != ERROR_MARK);
|
|
||||||
gcc_assert(target_type != error_mark_node);
|
|
||||||
|
|
||||||
this->current_expression = build2_loc(expression_location,
|
|
||||||
operator_code, target_type, left, right);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::unary_expression *expression)
|
void generic_visitor::visit(boot::unary_expression *expression)
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#include "elna/gcc/elna-tree.h"
|
#include "elna/gcc/elna-tree.h"
|
||||||
|
#include "elna/gcc/elna-diagnostic.h"
|
||||||
|
|
||||||
#include "stor-layout.h"
|
#include "stor-layout.h"
|
||||||
|
#include "fold-const.h"
|
||||||
|
#include "diagnostic-core.h"
|
||||||
|
|
||||||
tree elna_global_trees[ELNA_TI_MAX];
|
tree elna_global_trees[ELNA_TI_MAX];
|
||||||
|
|
||||||
@ -20,12 +23,6 @@ namespace gcc
|
|||||||
return TREE_CODE(type) == POINTER_TYPE;
|
return TREE_CODE(type) == POINTER_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_string_type(tree type)
|
|
||||||
{
|
|
||||||
return is_pointer_type(type)
|
|
||||||
&& TYPE_MAIN_VARIANT(TREE_TYPE(type)) == char_type_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
tree tree_chain_base::head()
|
tree tree_chain_base::head()
|
||||||
{
|
{
|
||||||
return first;
|
return first;
|
||||||
@ -81,5 +78,43 @@ namespace gcc
|
|||||||
|
|
||||||
return initial_table;
|
return initial_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right)
|
||||||
|
{
|
||||||
|
tree result = error_mark_node;
|
||||||
|
tree convert_expression = fold_convert(sizetype, right);
|
||||||
|
|
||||||
|
if (binary_operator == boot::binary_operator::sum)
|
||||||
|
{
|
||||||
|
result = fold_build2(POINTER_PLUS_EXPR, TREE_TYPE(left), left, convert_expression);
|
||||||
|
}
|
||||||
|
else if (binary_operator == boot::binary_operator::subtraction)
|
||||||
|
{
|
||||||
|
convert_expression = fold_build1(NEGATE_EXPR, sizetype, convert_expression);
|
||||||
|
result = fold_build2(POINTER_PLUS_EXPR, TREE_TYPE(left), left, convert_expression);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree build_binary_operation(bool condition, boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right, tree target_type)
|
||||||
|
{
|
||||||
|
location_t expression_location = get_location(&expression->position());
|
||||||
|
tree left_type = TREE_TYPE(left);
|
||||||
|
tree right_type = TREE_TYPE(right);
|
||||||
|
|
||||||
|
if (condition)
|
||||||
|
{
|
||||||
|
return build2_loc(expression_location, operator_code, target_type, left, right);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_at(expression_location,
|
||||||
|
"invalid operands of type %s and %s for operator %s",
|
||||||
|
print_type(left_type), print_type(right_type),
|
||||||
|
elna::boot::print_binary_operator(expression->operation()));
|
||||||
|
return error_mark_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -637,11 +637,11 @@ namespace boot
|
|||||||
class block : public node
|
class block : public node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<definition *> value_definitions;
|
std::vector<variable_declaration *> variables;
|
||||||
|
std::vector<constant_definition *> constants;
|
||||||
std::vector<statement *> body;
|
std::vector<statement *> body;
|
||||||
|
|
||||||
block(const struct position position, std::vector<definition *>&& value_definitions,
|
block(const struct position position);
|
||||||
std::vector<statement *>&& body);
|
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
virtual ~block() override;
|
virtual ~block() override;
|
||||||
@ -652,8 +652,7 @@ namespace boot
|
|||||||
public:
|
public:
|
||||||
std::vector<definition *> type_definitions;
|
std::vector<definition *> type_definitions;
|
||||||
|
|
||||||
program(const struct position position, std::vector<definition *>&& type_definitions,
|
program(const struct position position, std::vector<definition *>&& type_definitions);
|
||||||
std::vector<definition *>&& value_definitions, std::vector<statement *>&& body);
|
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
virtual ~program() override;
|
virtual ~program() override;
|
||||||
|
@ -31,12 +31,19 @@ namespace gcc
|
|||||||
void enter_scope();
|
void enter_scope();
|
||||||
tree_symbol_mapping leave_scope();
|
tree_symbol_mapping leave_scope();
|
||||||
|
|
||||||
void build_binary_operation(bool condition, boot::binary_expression *expression,
|
|
||||||
tree_code operator_code, tree left, tree right, tree target_type);
|
|
||||||
|
|
||||||
void make_if_branch(boot::conditional_statements& branch, tree goto_endif);
|
void make_if_branch(boot::conditional_statements& branch, tree goto_endif);
|
||||||
|
|
||||||
bool is_integral_type(tree type);
|
bool is_integral_type(tree type);
|
||||||
|
bool is_numeric_type(tree type);
|
||||||
|
|
||||||
|
tree build_arithmetic_operation(boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right);
|
||||||
|
tree build_comparison_operation(boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right);
|
||||||
|
tree build_logic_operation(boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right);
|
||||||
|
tree build_equality_operation(boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
generic_visitor(std::shared_ptr<boot::symbol_table<tree>> symbol_table);
|
generic_visitor(std::shared_ptr<boot::symbol_table<tree>> symbol_table);
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "coretypes.h"
|
#include "coretypes.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "tree.h"
|
|
||||||
|
|
||||||
|
#include "elna/boot/ast.h"
|
||||||
#include "elna/boot/symbol.h"
|
#include "elna/boot/symbol.h"
|
||||||
|
|
||||||
enum elna_tree_index
|
enum elna_tree_index
|
||||||
@ -24,7 +24,6 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
void init_ttree();
|
void init_ttree();
|
||||||
bool is_pointer_type(tree type);
|
bool is_pointer_type(tree type);
|
||||||
bool is_string_type(tree type);
|
|
||||||
|
|
||||||
class tree_chain_base
|
class tree_chain_base
|
||||||
{
|
{
|
||||||
@ -58,5 +57,11 @@ namespace gcc
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<boot::symbol_table<tree>> builtin_symbol_table();
|
std::shared_ptr<boot::symbol_table<tree>> builtin_symbol_table();
|
||||||
|
|
||||||
|
tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right);
|
||||||
|
tree build_binary_operation(bool condition, boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right, tree target_type);
|
||||||
|
tree build_arithmetic_operation(boot::binary_expression *expression,
|
||||||
|
tree_code operator_code, tree left, tree right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
source.elna
75
source.elna
@ -20,6 +20,9 @@ type
|
|||||||
end,
|
end,
|
||||||
FILE = record
|
FILE = record
|
||||||
dummy: Int
|
dummy: Int
|
||||||
|
end,
|
||||||
|
CommandLine = record
|
||||||
|
input: pointer to Char
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -141,19 +144,6 @@ end;
|
|||||||
End of standard procedures.
|
End of standard procedures.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
proc test_primitive();
|
|
||||||
begin
|
|
||||||
write_s("\nTest primitives:\n");
|
|
||||||
write_u(25u);
|
|
||||||
write_c('\n');
|
|
||||||
|
|
||||||
write_i(8);
|
|
||||||
write_c('\n');
|
|
||||||
|
|
||||||
write_b(true);
|
|
||||||
write_c('\n')
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc read_source(filename: String): pointer to Char;
|
proc read_source(filename: String): pointer to Char;
|
||||||
var
|
var
|
||||||
input_file: pointer to FILE,
|
input_file: pointer to FILE,
|
||||||
@ -272,7 +262,7 @@ var
|
|||||||
is_valid: Bool;
|
is_valid: Bool;
|
||||||
begin
|
begin
|
||||||
token_end := input;
|
token_end := input;
|
||||||
previous := cast(cast(input as Word) - 1u as pointer to Char);
|
previous := input - 1;
|
||||||
|
|
||||||
while token_end^ <> '\0' and not (previous^ <> '\\' and token_end^ = '"') do
|
while token_end^ <> '\0' and not (previous^ <> '\\' and token_end^ = '"') do
|
||||||
previous := token_end;
|
previous := token_end;
|
||||||
@ -286,7 +276,7 @@ begin
|
|||||||
|
|
||||||
is_valid := true;
|
is_valid := true;
|
||||||
constructed_string := current_token^.value.string_value;
|
constructed_string := current_token^.value.string_value;
|
||||||
while cast(input as Word) < cast(token_end as Word) and is_valid do
|
while input < token_end and is_valid do
|
||||||
|
|
||||||
if input^ = '\\' then
|
if input^ = '\\' then
|
||||||
input := input + 1;
|
input := input + 1;
|
||||||
@ -677,32 +667,51 @@ begin
|
|||||||
return tokens
|
return tokens
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc command_line(argc: Int, argv: pointer to pointer to Char);
|
proc parse_command_line(argc: Int, argv: pointer to pointer to Char): pointer to CommandLine;
|
||||||
var
|
var
|
||||||
parameter: pointer to pointer to Char,
|
parameter: pointer to pointer to Char,
|
||||||
i: Int;
|
i: Int,
|
||||||
|
result: pointer to CommandLine;
|
||||||
begin
|
begin
|
||||||
write_s("Argument count: ");
|
if argc < 2 then
|
||||||
write_i(argc - 1);
|
write_s("Fatal error: no input files.\n");
|
||||||
write_s("\nArguments:");
|
return nil
|
||||||
|
end;
|
||||||
|
if argc > 2 then
|
||||||
|
write_s("Fatal error: Unknown command line options:");
|
||||||
|
|
||||||
i := 1;
|
i := 2;
|
||||||
while i < argc do
|
while i < argc do
|
||||||
parameter := argv + i * cast(sizeof(pointer to Char) as Int);
|
parameter := argv + i * cast(sizeof(pointer to Char) as Int);
|
||||||
|
|
||||||
|
write_c(' ');
|
||||||
|
write_s(parameter^);
|
||||||
|
i := i + 1
|
||||||
|
end;
|
||||||
|
write_s(".\n");
|
||||||
|
return nil
|
||||||
|
end;
|
||||||
|
|
||||||
write_c(' ');
|
parameter := argv + cast(sizeof(pointer to Char) as Int);
|
||||||
write_s(parameter^);
|
result := cast(malloc(sizeof(CommandLine)) as pointer to CommandLine);
|
||||||
i := i + 1
|
result^.input := parameter^;
|
||||||
end
|
|
||||||
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc compile();
|
proc process(argc: Int, argv: pointer to pointer to Char): Int;
|
||||||
var
|
var
|
||||||
input: pointer to Char,
|
input: pointer to Char,
|
||||||
tokens: pointer to Token,
|
tokens: pointer to Token,
|
||||||
tokens_size: Word;
|
tokens_size: Word,
|
||||||
|
command_line: pointer to CommandLine;
|
||||||
begin
|
begin
|
||||||
input := read_source("example.elna");
|
command_line := parse_command_line(argc, argv);
|
||||||
|
|
||||||
|
if cast(command_line as Word) = 0u then
|
||||||
|
return 2
|
||||||
|
end;
|
||||||
|
input := read_source(command_line^.input);
|
||||||
tokens := tokenize(input, @tokens_size);
|
tokens := tokenize(input, @tokens_size);
|
||||||
|
|
||||||
free(input);
|
free(input);
|
||||||
@ -711,9 +720,5 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
command_line(count, parameters);
|
exit(process(count, parameters))
|
||||||
compile();
|
|
||||||
test_primitive();
|
|
||||||
|
|
||||||
exit(0)
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user