Rename boot namespace to frontend
This commit is contained in:
@@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with GCC; see the file COPYING3. If not see
|
along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "elna/boot/ast.h"
|
#include "elna/frontend/ast.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
void empty_visitor::not_implemented()
|
void empty_visitor::not_implemented()
|
||||||
{
|
{
|
||||||
@@ -15,17 +15,17 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with GCC; see the file COPYING3. If not see
|
along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "elna/boot/dependency.h"
|
#include "elna/frontend/dependency.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "elna/boot/driver.h"
|
#include "elna/frontend/driver.h"
|
||||||
#include "elna/boot/semantic.h"
|
#include "elna/frontend/semantic.h"
|
||||||
#include "parser.hh"
|
#include "parser.hh"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
dependency::dependency(const char *path)
|
dependency::dependency(const char *path)
|
||||||
: error_container(path)
|
: error_container(path)
|
||||||
@@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with GCC; see the file COPYING3. If not see
|
along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "elna/boot/driver.h"
|
#include "elna/frontend/driver.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
position make_position(const yy::location& location)
|
position make_position(const yy::location& location)
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include "parser.hh"
|
#include "parser.hh"
|
||||||
|
|
||||||
#undef YY_DECL
|
#undef YY_DECL
|
||||||
#define YY_DECL yy::parser::symbol_type elna::boot::lexer::lex(driver& driver)
|
#define YY_DECL yy::parser::symbol_type elna::frontend::lexer::lex(driver& driver)
|
||||||
#define yyterminate() return yy::parser::make_YYEOF(this->location)
|
#define yyterminate() return yy::parser::make_YYEOF(this->location)
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@@ -25,25 +25,20 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
%code requires {
|
%code requires {
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "elna/boot/driver.h"
|
#include "elna/frontend/driver.h"
|
||||||
|
|
||||||
#if !defined(yyFlexLexerOnce)
|
#if !defined(yyFlexLexerOnce)
|
||||||
#include <FlexLexer.h>
|
#include <FlexLexer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace elna
|
namespace elna::frontend
|
||||||
{
|
|
||||||
namespace boot
|
|
||||||
{
|
{
|
||||||
class lexer;
|
class lexer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
%code provides {
|
%code provides {
|
||||||
namespace elna
|
namespace elna::frontend
|
||||||
{
|
|
||||||
namespace boot
|
|
||||||
{
|
{
|
||||||
|
|
||||||
class lexer: public yyFlexLexer
|
class lexer: public yyFlexLexer
|
||||||
@@ -61,14 +56,13 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
%define api.token.raw
|
%define api.token.raw
|
||||||
%define api.token.constructor
|
%define api.token.constructor
|
||||||
%define api.value.type variant
|
%define api.value.type variant
|
||||||
|
|
||||||
%parse-param {elna::boot::lexer& lexer}
|
%parse-param {elna::frontend::lexer& lexer}
|
||||||
%param {elna::boot::driver& driver}
|
%param {elna::frontend::driver& driver}
|
||||||
%locations
|
%locations
|
||||||
|
|
||||||
%header
|
%header
|
||||||
@@ -129,48 +123,48 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
%left "+" "-"
|
%left "+" "-"
|
||||||
%left "*" "/" "%"
|
%left "*" "/" "%"
|
||||||
|
|
||||||
%type <elna::boot::literal_expression *> literal;
|
%type <elna::frontend::literal_expression *> literal;
|
||||||
%type <std::vector<elna::boot::expression *>> case_labels;
|
%type <std::vector<elna::frontend::expression *>> case_labels;
|
||||||
%type <elna::boot::switch_case> switch_case;
|
%type <elna::frontend::switch_case> switch_case;
|
||||||
%type <std::vector<elna::boot::switch_case>> switch_cases;
|
%type <std::vector<elna::frontend::switch_case>> switch_cases;
|
||||||
%type <elna::boot::constant_declaration *> constant_declaration;
|
%type <elna::frontend::constant_declaration *> constant_declaration;
|
||||||
%type <std::vector<elna::boot::constant_declaration *>> constant_part constant_declarations;
|
%type <std::vector<elna::frontend::constant_declaration *>> constant_part constant_declarations;
|
||||||
%type <elna::boot::variable_declaration *> variable_declaration;
|
%type <elna::frontend::variable_declaration *> variable_declaration;
|
||||||
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part;
|
%type <std::vector<elna::frontend::variable_declaration *>> variable_declarations variable_part;
|
||||||
%type <elna::boot::type_expression *> type_expression;
|
%type <elna::frontend::type_expression *> type_expression;
|
||||||
%type <std::vector<elna::boot::type_expression *>> type_expressions;
|
%type <std::vector<elna::frontend::type_expression *>> type_expressions;
|
||||||
%type <elna::boot::traits_expression *> traits_expression;
|
%type <elna::frontend::traits_expression *> traits_expression;
|
||||||
%type <elna::boot::expression *> expression operand simple_expression;
|
%type <elna::frontend::expression *> expression operand simple_expression;
|
||||||
%type <elna::boot::unary_expression *> unary_expression;
|
%type <elna::frontend::unary_expression *> unary_expression;
|
||||||
%type <elna::boot::binary_expression *> binary_expression;
|
%type <elna::frontend::binary_expression *> binary_expression;
|
||||||
%type <std::vector<elna::boot::expression *>> expressions actual_parameter_list;
|
%type <std::vector<elna::frontend::expression *>> expressions actual_parameter_list;
|
||||||
%type <elna::boot::designator_expression *> designator_expression;
|
%type <elna::frontend::designator_expression *> designator_expression;
|
||||||
%type <elna::boot::procedure_call*> call_expression;
|
%type <elna::frontend::procedure_call*> call_expression;
|
||||||
%type <elna::boot::return_statement *> return_statement;
|
%type <elna::frontend::return_statement *> return_statement;
|
||||||
%type <elna::boot::statement *> statement;
|
%type <elna::frontend::statement *> statement;
|
||||||
%type <std::vector<elna::boot::statement *>> required_statements optional_statements statement_part;
|
%type <std::vector<elna::frontend::statement *>> required_statements optional_statements statement_part;
|
||||||
%type <elna::boot::procedure_declaration *> procedure_declaration;
|
%type <elna::frontend::procedure_declaration *> procedure_declaration;
|
||||||
%type <std::pair<std::vector<std::string>, elna::boot::procedure_type_expression *>> procedure_heading;
|
%type <std::pair<std::vector<std::string>, elna::frontend::procedure_type_expression *>> procedure_heading;
|
||||||
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
|
%type <elna::frontend::procedure_type_expression::return_t> return_declaration;
|
||||||
%type <std::vector<elna::boot::procedure_declaration *>> procedure_declarations procedure_part;
|
%type <std::vector<elna::frontend::procedure_declaration *>> procedure_declarations procedure_part;
|
||||||
%type <elna::boot::type_declaration *> type_declaration;
|
%type <elna::frontend::type_declaration *> type_declaration;
|
||||||
%type <std::vector<elna::boot::type_declaration *>> type_declarations type_part;
|
%type <std::vector<elna::frontend::type_declaration *>> type_declarations type_part;
|
||||||
%type <std::unique_ptr<elna::boot::block>> block;
|
%type <std::unique_ptr<elna::frontend::block>> block;
|
||||||
%type <elna::boot::field_declaration> field_declaration formal_parameter;
|
%type <elna::frontend::field_declaration> field_declaration formal_parameter;
|
||||||
%type <std::vector<std::pair<std::string, elna::boot::type_expression *>>>
|
%type <std::vector<std::pair<std::string, elna::frontend::type_expression *>>>
|
||||||
optional_fields required_fields formal_parameters formal_parameter_list;
|
optional_fields required_fields formal_parameters formal_parameter_list;
|
||||||
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
|
%type <std::vector<elna::frontend::conditional_statements *>> elsif_then_statements elsif_do_statements;
|
||||||
%type <std::vector<elna::boot::statement *> *> else_statements;
|
%type <std::vector<elna::frontend::statement *> *> else_statements;
|
||||||
%type <elna::boot::cast_expression *> cast_expression;
|
%type <elna::frontend::cast_expression *> cast_expression;
|
||||||
%type <elna::boot::identifier_definition> identifier_definition;
|
%type <elna::frontend::identifier_definition> identifier_definition;
|
||||||
%type <std::vector<elna::boot::identifier_definition>> identifier_definitions;
|
%type <std::vector<elna::frontend::identifier_definition>> identifier_definitions;
|
||||||
%type <std::vector<std::string>> identifiers import_declaration;
|
%type <std::vector<std::string>> identifiers import_declaration;
|
||||||
%type <std::vector<elna::boot::import_declaration *>> import_declarations import_part;
|
%type <std::vector<elna::frontend::import_declaration *>> import_declarations import_part;
|
||||||
%%
|
%%
|
||||||
program:
|
program:
|
||||||
"program" ";" import_part constant_part type_part variable_part procedure_part statement_part "end" "."
|
"program" ";" import_part constant_part type_part variable_part procedure_part statement_part "end" "."
|
||||||
{
|
{
|
||||||
auto tree = new boot::program(boot::make_position(@1));
|
auto tree = new frontend::program(frontend::make_position(@1));
|
||||||
|
|
||||||
std::swap(tree->imports, $3);
|
std::swap(tree->imports, $3);
|
||||||
std::swap(tree->constants, $4);
|
std::swap(tree->constants, $4);
|
||||||
@@ -183,7 +177,7 @@ program:
|
|||||||
}
|
}
|
||||||
| "module" ";" import_part constant_part type_part variable_part procedure_part "end" "."
|
| "module" ";" import_part constant_part type_part variable_part procedure_part "end" "."
|
||||||
{
|
{
|
||||||
auto tree = new boot::unit(boot::make_position(@1));
|
auto tree = new frontend::unit(frontend::make_position(@1));
|
||||||
|
|
||||||
std::swap(tree->imports, $3);
|
std::swap(tree->imports, $3);
|
||||||
std::swap(tree->constants, $4);
|
std::swap(tree->constants, $4);
|
||||||
@@ -195,7 +189,7 @@ program:
|
|||||||
}
|
}
|
||||||
block: constant_part variable_part statement_part "end"
|
block: constant_part variable_part statement_part "end"
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<boot::block>(std::move($1), std::move($2), std::move($3));
|
$$ = std::make_unique<frontend::block>(std::move($1), std::move($2), std::move($3));
|
||||||
}
|
}
|
||||||
statement_part:
|
statement_part:
|
||||||
/* no statements */ {}
|
/* no statements */ {}
|
||||||
@@ -207,8 +201,8 @@ statement_part:
|
|||||||
$$.push_back($4);
|
$$.push_back($4);
|
||||||
}
|
}
|
||||||
identifier_definition:
|
identifier_definition:
|
||||||
IDENTIFIER "*" { $$ = boot::identifier_definition{ $1, true }; }
|
IDENTIFIER "*" { $$ = frontend::identifier_definition{ $1, true }; }
|
||||||
| IDENTIFIER { $$ = boot::identifier_definition{ $1, false }; }
|
| IDENTIFIER { $$ = frontend::identifier_definition{ $1, false }; }
|
||||||
identifier_definitions:
|
identifier_definitions:
|
||||||
identifier_definition "," identifier_definitions
|
identifier_definition "," identifier_definitions
|
||||||
{
|
{
|
||||||
@@ -218,11 +212,11 @@ identifier_definitions:
|
|||||||
| identifier_definition { $$.emplace_back(std::move($1)); }
|
| identifier_definition { $$.emplace_back(std::move($1)); }
|
||||||
return_declaration:
|
return_declaration:
|
||||||
/* proper procedure */ {}
|
/* proper procedure */ {}
|
||||||
| "->" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); }
|
| "->" "!" { $$ = frontend::procedure_type_expression::return_t(std::monostate{}); }
|
||||||
| "->" type_expression { $$ = boot::procedure_type_expression::return_t($2); }
|
| "->" type_expression { $$ = frontend::procedure_type_expression::return_t($2); }
|
||||||
procedure_heading: formal_parameter_list return_declaration
|
procedure_heading: formal_parameter_list return_declaration
|
||||||
{
|
{
|
||||||
$$.second = new boot::procedure_type_expression(boot::make_position(@1), std::move($2));
|
$$.second = new frontend::procedure_type_expression(frontend::make_position(@1), std::move($2));
|
||||||
for (auto& [name, type] : $1)
|
for (auto& [name, type] : $1)
|
||||||
{
|
{
|
||||||
$$.first.emplace_back(std::move(name));
|
$$.first.emplace_back(std::move(name));
|
||||||
@@ -232,12 +226,12 @@ procedure_heading: formal_parameter_list return_declaration
|
|||||||
procedure_declaration:
|
procedure_declaration:
|
||||||
"proc" identifier_definition procedure_heading ";" block ";"
|
"proc" identifier_definition procedure_heading ";" block ";"
|
||||||
{
|
{
|
||||||
$$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3.second, std::move(*$5));
|
$$ = new frontend::procedure_declaration(frontend::make_position(@1), std::move($2), $3.second, std::move(*$5));
|
||||||
std::swap($3.first, $$->parameter_names);
|
std::swap($3.first, $$->parameter_names);
|
||||||
}
|
}
|
||||||
| "proc" identifier_definition procedure_heading ";" "extern" ";"
|
| "proc" identifier_definition procedure_heading ";" "extern" ";"
|
||||||
{
|
{
|
||||||
$$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3.second);
|
$$ = new frontend::procedure_declaration(frontend::make_position(@1), std::move($2), $3.second);
|
||||||
std::swap($3.first, $$->parameter_names);
|
std::swap($3.first, $$->parameter_names);
|
||||||
}
|
}
|
||||||
procedure_declarations:
|
procedure_declarations:
|
||||||
@@ -252,44 +246,44 @@ procedure_part:
|
|||||||
| procedure_declarations { std::swap($$, $1); }
|
| procedure_declarations { std::swap($$, $1); }
|
||||||
call_expression: designator_expression actual_parameter_list
|
call_expression: designator_expression actual_parameter_list
|
||||||
{
|
{
|
||||||
$$ = new boot::procedure_call(boot::make_position(@1), $1);
|
$$ = new frontend::procedure_call(frontend::make_position(@1), $1);
|
||||||
std::swap($$->arguments, $2);
|
std::swap($$->arguments, $2);
|
||||||
}
|
}
|
||||||
cast_expression: "cast" "(" expression ":" type_expression ")"
|
cast_expression: "cast" "(" expression ":" type_expression ")"
|
||||||
{ $$ = new boot::cast_expression(boot::make_position(@1), $5, $3); }
|
{ $$ = new frontend::cast_expression(frontend::make_position(@1), $5, $3); }
|
||||||
elsif_do_statements:
|
elsif_do_statements:
|
||||||
"elsif" expression "do" optional_statements elsif_do_statements
|
"elsif" expression "do" optional_statements elsif_do_statements
|
||||||
{
|
{
|
||||||
boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4));
|
frontend::conditional_statements *branch = new frontend::conditional_statements($2, std::move($4));
|
||||||
std::swap($5, $$);
|
std::swap($5, $$);
|
||||||
$$.emplace($$.begin(), branch);
|
$$.emplace($$.begin(), branch);
|
||||||
}
|
}
|
||||||
| {}
|
| {}
|
||||||
else_statements:
|
else_statements:
|
||||||
"else" optional_statements { $$ = new std::vector<boot::statement *>(std::move($2)); }
|
"else" optional_statements { $$ = new std::vector<frontend::statement *>(std::move($2)); }
|
||||||
| { $$ = nullptr; }
|
| { $$ = nullptr; }
|
||||||
elsif_then_statements:
|
elsif_then_statements:
|
||||||
"elsif" expression "then" optional_statements elsif_then_statements
|
"elsif" expression "then" optional_statements elsif_then_statements
|
||||||
{
|
{
|
||||||
boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4));
|
frontend::conditional_statements *branch = new frontend::conditional_statements($2, std::move($4));
|
||||||
std::swap($5, $$);
|
std::swap($5, $$);
|
||||||
$$.emplace($$.begin(), branch);
|
$$.emplace($$.begin(), branch);
|
||||||
}
|
}
|
||||||
| {}
|
| {}
|
||||||
return_statement: "return" expression
|
return_statement: "return" expression
|
||||||
{ $$ = new boot::return_statement(boot::make_position(@1), $2); }
|
{ $$ = new frontend::return_statement(frontend::make_position(@1), $2); }
|
||||||
literal:
|
literal:
|
||||||
INTEGER { $$ = new boot::literal<std::int32_t>(boot::make_position(@1), $1); }
|
INTEGER { $$ = new frontend::literal<std::int32_t>(frontend::make_position(@1), $1); }
|
||||||
| WORD { $$ = new boot::literal<std::uint32_t>(boot::make_position(@1), $1); }
|
| WORD { $$ = new frontend::literal<std::uint32_t>(frontend::make_position(@1), $1); }
|
||||||
| FLOAT { $$ = new boot::literal<double>(boot::make_position(@1), $1); }
|
| FLOAT { $$ = new frontend::literal<double>(frontend::make_position(@1), $1); }
|
||||||
| BOOLEAN { $$ = new boot::literal<bool>(boot::make_position(@1), $1); }
|
| BOOLEAN { $$ = new frontend::literal<bool>(frontend::make_position(@1), $1); }
|
||||||
| CHARACTER { $$ = new boot::literal<unsigned char>(boot::make_position(@1), $1.at(0)); }
|
| CHARACTER { $$ = new frontend::literal<unsigned char>(frontend::make_position(@1), $1.at(0)); }
|
||||||
| "nil" { $$ = new boot::literal<std::nullptr_t>(boot::make_position(@1), nullptr); }
|
| "nil" { $$ = new frontend::literal<std::nullptr_t>(frontend::make_position(@1), nullptr); }
|
||||||
| STRING { $$ = new boot::literal<std::string>(boot::make_position(@1), $1); }
|
| STRING { $$ = new frontend::literal<std::string>(frontend::make_position(@1), $1); }
|
||||||
traits_expression:
|
traits_expression:
|
||||||
TRAIT "(" type_expressions ")"
|
TRAIT "(" type_expressions ")"
|
||||||
{
|
{
|
||||||
$$ = new boot::traits_expression(boot::make_position(@1), $1);
|
$$ = new frontend::traits_expression(frontend::make_position(@1), $1);
|
||||||
std::swap($3, $$->parameters);
|
std::swap($3, $$->parameters);
|
||||||
}
|
}
|
||||||
simple_expression:
|
simple_expression:
|
||||||
@@ -308,82 +302,82 @@ expression:
|
|||||||
binary_expression:
|
binary_expression:
|
||||||
expression "*" expression
|
expression "*" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::multiplication);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::multiplication);
|
||||||
}
|
}
|
||||||
| expression "/" expression
|
| expression "/" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::division);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::division);
|
||||||
}
|
}
|
||||||
| expression "%" expression
|
| expression "%" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::remainder);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::remainder);
|
||||||
}
|
}
|
||||||
| expression "+" expression
|
| expression "+" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::sum);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::sum);
|
||||||
}
|
}
|
||||||
| expression "-" expression
|
| expression "-" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::subtraction);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::subtraction);
|
||||||
}
|
}
|
||||||
| expression "=" expression
|
| expression "=" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::equals);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::equals);
|
||||||
}
|
}
|
||||||
| expression "<>" expression
|
| expression "<>" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::not_equals);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::not_equals);
|
||||||
}
|
}
|
||||||
| expression "<" expression
|
| expression "<" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::less);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::less);
|
||||||
}
|
}
|
||||||
| expression ">" expression
|
| expression ">" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::greater);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::greater);
|
||||||
}
|
}
|
||||||
| expression "<=" expression
|
| expression "<=" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3,
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3,
|
||||||
boot::binary_operator::less_equal);
|
frontend::binary_operator::less_equal);
|
||||||
}
|
}
|
||||||
| expression ">=" expression
|
| expression ">=" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::greater_equal);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::greater_equal);
|
||||||
}
|
}
|
||||||
| expression "&" expression
|
| expression "&" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::conjunction);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::conjunction);
|
||||||
}
|
}
|
||||||
| expression "or" expression
|
| expression "or" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::disjunction);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::disjunction);
|
||||||
}
|
}
|
||||||
| expression "xor" expression
|
| expression "xor" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3,
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3,
|
||||||
boot::binary_operator::exclusive_disjunction);
|
frontend::binary_operator::exclusive_disjunction);
|
||||||
}
|
}
|
||||||
| expression "<<" expression
|
| expression "<<" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::shift_left);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::shift_left);
|
||||||
}
|
}
|
||||||
| expression ">>" expression
|
| expression ">>" expression
|
||||||
{
|
{
|
||||||
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::shift_right);
|
$$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3, frontend::binary_operator::shift_right);
|
||||||
}
|
}
|
||||||
unary_expression:
|
unary_expression:
|
||||||
"@" operand
|
"@" operand
|
||||||
{
|
{
|
||||||
$$ = new boot::unary_expression(boot::make_position(@1), $2, boot::unary_operator::reference);
|
$$ = new frontend::unary_expression(frontend::make_position(@1), $2, frontend::unary_operator::reference);
|
||||||
}
|
}
|
||||||
| "~" operand
|
| "~" operand
|
||||||
{
|
{
|
||||||
$$ = new boot::unary_expression(boot::make_position(@1), $2, boot::unary_operator::negation);
|
$$ = new frontend::unary_expression(frontend::make_position(@1), $2, frontend::unary_operator::negation);
|
||||||
}
|
}
|
||||||
| "-" operand
|
| "-" operand
|
||||||
{
|
{
|
||||||
$$ = new boot::unary_expression(boot::make_position(@1), $2, boot::unary_operator::minus);
|
$$ = new frontend::unary_expression(frontend::make_position(@1), $2, frontend::unary_operator::minus);
|
||||||
}
|
}
|
||||||
expressions:
|
expressions:
|
||||||
expression "," expressions
|
expression "," expressions
|
||||||
@@ -401,31 +395,31 @@ type_expressions:
|
|||||||
| type_expression { $$.push_back($1); }
|
| type_expression { $$.push_back($1); }
|
||||||
designator_expression:
|
designator_expression:
|
||||||
simple_expression "[" expression "]"
|
simple_expression "[" expression "]"
|
||||||
{ $$ = new boot::array_access_expression(boot::make_position(@2), $1, $3); }
|
{ $$ = new frontend::array_access_expression(frontend::make_position(@2), $1, $3); }
|
||||||
| simple_expression "." IDENTIFIER
|
| simple_expression "." IDENTIFIER
|
||||||
{ $$ = new boot::field_access_expression(boot::make_position(@2), $1, $3); }
|
{ $$ = new frontend::field_access_expression(frontend::make_position(@2), $1, $3); }
|
||||||
| simple_expression "^"
|
| simple_expression "^"
|
||||||
{ $$ = new boot::dereference_expression(boot::make_position(@1), $1); }
|
{ $$ = new frontend::dereference_expression(frontend::make_position(@1), $1); }
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
{ $$ = new boot::variable_expression(boot::make_position(@1), $1); }
|
{ $$ = new frontend::variable_expression(frontend::make_position(@1), $1); }
|
||||||
statement:
|
statement:
|
||||||
designator_expression ":=" expression
|
designator_expression ":=" expression
|
||||||
{ $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); }
|
{ $$ = new frontend::assign_statement(frontend::make_position(@1), $1, $3); }
|
||||||
| "while" expression "do" optional_statements elsif_do_statements "end"
|
| "while" expression "do" optional_statements elsif_do_statements "end"
|
||||||
{
|
{
|
||||||
boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4));
|
frontend::conditional_statements *body = new frontend::conditional_statements($2, std::move($4));
|
||||||
$$ = new boot::while_statement(boot::make_position(@1), body, std::move($5));
|
$$ = new frontend::while_statement(frontend::make_position(@1), body, std::move($5));
|
||||||
}
|
}
|
||||||
| "if" expression "then" optional_statements elsif_then_statements else_statements "end"
|
| "if" expression "then" optional_statements elsif_then_statements else_statements "end"
|
||||||
{
|
{
|
||||||
boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4));
|
frontend::conditional_statements *then = new frontend::conditional_statements($2, std::move($4));
|
||||||
$$ = new boot::if_statement(boot::make_position(@1), then, std::move($5), $6);
|
$$ = new frontend::if_statement(frontend::make_position(@1), then, std::move($5), $6);
|
||||||
}
|
}
|
||||||
| call_expression { $$ = $1; }
|
| call_expression { $$ = $1; }
|
||||||
| "defer" optional_statements "end"
|
| "defer" optional_statements "end"
|
||||||
{ $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
|
{ $$ = new frontend::defer_statement(frontend::make_position(@1), std::move($2)); }
|
||||||
| "case" expression "of" switch_cases else_statements "end"
|
| "case" expression "of" switch_cases else_statements "end"
|
||||||
{ $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4), $5); }
|
{ $$ = new frontend::case_statement(frontend::make_position(@1), $2, std::move($4), $5); }
|
||||||
switch_case: case_labels ":" optional_statements
|
switch_case: case_labels ":" optional_statements
|
||||||
{ $$ = { .labels = std::move($1), .statements = std::move($3) }; }
|
{ $$ = { .labels = std::move($1), .statements = std::move($3) }; }
|
||||||
switch_cases:
|
switch_cases:
|
||||||
@@ -467,33 +461,33 @@ optional_fields:
|
|||||||
type_expression:
|
type_expression:
|
||||||
"[" INTEGER "]" type_expression
|
"[" INTEGER "]" type_expression
|
||||||
{
|
{
|
||||||
$$ = new boot::array_type_expression(boot::make_position(@1), $4, $2);
|
$$ = new frontend::array_type_expression(frontend::make_position(@1), $4, $2);
|
||||||
}
|
}
|
||||||
| "^" type_expression
|
| "^" type_expression
|
||||||
{
|
{
|
||||||
$$ = new boot::pointer_type_expression(boot::make_position(@1), $2);
|
$$ = new frontend::pointer_type_expression(frontend::make_position(@1), $2);
|
||||||
}
|
}
|
||||||
| "record" optional_fields "end"
|
| "record" optional_fields "end"
|
||||||
{
|
{
|
||||||
$$ = new boot::record_type_expression(boot::make_position(@1), std::move($2));
|
$$ = new frontend::record_type_expression(frontend::make_position(@1), std::move($2));
|
||||||
}
|
}
|
||||||
| "union" required_fields "end"
|
| "union" required_fields "end"
|
||||||
{
|
{
|
||||||
$$ = new boot::union_type_expression(boot::make_position(@1), std::move($2));
|
$$ = new frontend::union_type_expression(frontend::make_position(@1), std::move($2));
|
||||||
}
|
}
|
||||||
| "proc" "(" type_expressions ")" return_declaration
|
| "proc" "(" type_expressions ")" return_declaration
|
||||||
{
|
{
|
||||||
auto result = new boot::procedure_type_expression(boot::make_position(@1), std::move($5));
|
auto result = new frontend::procedure_type_expression(frontend::make_position(@1), std::move($5));
|
||||||
std::swap(result->parameters, $3);
|
std::swap(result->parameters, $3);
|
||||||
$$ = result;
|
$$ = result;
|
||||||
}
|
}
|
||||||
| "(" identifiers ")"
|
| "(" identifiers ")"
|
||||||
{
|
{
|
||||||
$$ = new boot::enumeration_type_expression(boot::make_position(@1), std::move($2));
|
$$ = new frontend::enumeration_type_expression(frontend::make_position(@1), std::move($2));
|
||||||
}
|
}
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
{
|
{
|
||||||
$$ = new boot::named_type_expression(boot::make_position(@1), $1);
|
$$ = new frontend::named_type_expression(frontend::make_position(@1), $1);
|
||||||
}
|
}
|
||||||
identifiers:
|
identifiers:
|
||||||
IDENTIFIER "," identifiers
|
IDENTIFIER "," identifiers
|
||||||
@@ -505,19 +499,19 @@ identifiers:
|
|||||||
variable_declaration:
|
variable_declaration:
|
||||||
identifier_definitions ":" type_expression ";"
|
identifier_definitions ":" type_expression ";"
|
||||||
{
|
{
|
||||||
std::shared_ptr<boot::type_expression> shared_type{ $3 };
|
std::shared_ptr<frontend::type_expression> shared_type{ $3 };
|
||||||
$$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type);
|
$$ = new frontend::variable_declaration( frontend::make_position(@2), std::move($1), shared_type);
|
||||||
}
|
}
|
||||||
| identifier_definitions ":" type_expression ":=" "extern" ";"
|
| identifier_definitions ":" type_expression ":=" "extern" ";"
|
||||||
{
|
{
|
||||||
std::shared_ptr<boot::type_expression> shared_type{ $3 };
|
std::shared_ptr<frontend::type_expression> shared_type{ $3 };
|
||||||
$$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type,
|
$$ = new frontend::variable_declaration( frontend::make_position(@2), std::move($1), shared_type,
|
||||||
std::monostate{});
|
std::monostate{});
|
||||||
}
|
}
|
||||||
| identifier_definitions ":" type_expression ":=" expression ";"
|
| identifier_definitions ":" type_expression ":=" expression ";"
|
||||||
{
|
{
|
||||||
std::shared_ptr<boot::type_expression> shared_type{ $3 };
|
std::shared_ptr<frontend::type_expression> shared_type{ $3 };
|
||||||
$$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type, $5);
|
$$ = new frontend::variable_declaration( frontend::make_position(@2), std::move($1), shared_type, $5);
|
||||||
}
|
}
|
||||||
variable_declarations:
|
variable_declarations:
|
||||||
/* no variable declarations */ {}
|
/* no variable declarations */ {}
|
||||||
@@ -531,7 +525,7 @@ variable_part:
|
|||||||
| "var" variable_declarations { std::swap($$, $2); }
|
| "var" variable_declarations { std::swap($$, $2); }
|
||||||
constant_declaration: identifier_definition ":=" expression ";"
|
constant_declaration: identifier_definition ":=" expression ";"
|
||||||
{
|
{
|
||||||
$$ = new boot::constant_declaration(boot::make_position(@1), std::move($1), $3);
|
$$ = new frontend::constant_declaration(frontend::make_position(@1), std::move($1), $3);
|
||||||
}
|
}
|
||||||
constant_declarations:
|
constant_declarations:
|
||||||
constant_declaration constant_declarations
|
constant_declaration constant_declarations
|
||||||
@@ -554,18 +548,18 @@ import_declarations:
|
|||||||
import_declaration "," import_declarations
|
import_declaration "," import_declarations
|
||||||
{
|
{
|
||||||
std::swap($$, $3);
|
std::swap($$, $3);
|
||||||
$$.emplace($$.cbegin(), new boot::import_declaration(boot::make_position(@1), std::move($1)));
|
$$.emplace($$.cbegin(), new frontend::import_declaration(frontend::make_position(@1), std::move($1)));
|
||||||
}
|
}
|
||||||
| import_declaration
|
| import_declaration
|
||||||
{
|
{
|
||||||
$$.emplace_back(new boot::import_declaration(boot::make_position(@1), std::move($1)));
|
$$.emplace_back(new frontend::import_declaration(frontend::make_position(@1), std::move($1)));
|
||||||
}
|
}
|
||||||
import_part:
|
import_part:
|
||||||
/* no import declarations */ {}
|
/* no import declarations */ {}
|
||||||
| "import" import_declarations ";" { std::swap($$, $2); }
|
| "import" import_declarations ";" { std::swap($$, $2); }
|
||||||
type_declaration: identifier_definition "=" type_expression ";"
|
type_declaration: identifier_definition "=" type_expression ";"
|
||||||
{
|
{
|
||||||
$$ = new boot::type_declaration(boot::make_position(@1), std::move($1), $3);
|
$$ = new frontend::type_declaration(frontend::make_position(@1), std::move($1), $3);
|
||||||
}
|
}
|
||||||
type_declarations:
|
type_declarations:
|
||||||
type_declaration type_declarations
|
type_declaration type_declarations
|
||||||
@@ -596,5 +590,5 @@ actual_parameter_list:
|
|||||||
|
|
||||||
void yy::parser::error(const location_type& loc, const std::string& message)
|
void yy::parser::error(const location_type& loc, const std::string& message)
|
||||||
{
|
{
|
||||||
driver.add_error<boot::syntax_error>(message, driver.input_file, loc);
|
driver.add_error<frontend::syntax_error>(message, driver.input_file, loc);
|
||||||
}
|
}
|
||||||
@@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with GCC; see the file COPYING3. If not see
|
along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "elna/boot/result.h"
|
#include "elna/frontend/result.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
error::error(const char *path, const struct position position)
|
error::error(const char *path, const struct position position)
|
||||||
: position(position), path(path)
|
: position(position), path(path)
|
||||||
@@ -60,8 +60,8 @@ namespace elna::boot
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t std::hash<elna::boot::identifier_definition>::operator()(
|
std::size_t std::hash<elna::frontend::identifier_definition>::operator()(
|
||||||
const elna::boot::identifier_definition& key) const
|
const elna::frontend::identifier_definition& key) const
|
||||||
{
|
{
|
||||||
return std::hash<std::string>{}(key.name);
|
return std::hash<std::string>{}(key.name);
|
||||||
}
|
}
|
||||||
@@ -15,12 +15,12 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with GCC; see the file COPYING3. If not see
|
along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "elna/boot/semantic.h"
|
#include "elna/frontend/semantic.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
undeclared_error::undeclared_error(const std::string& identifier, const char *path, const struct position position)
|
undeclared_error::undeclared_error(const std::string& identifier, const char *path, const struct position position)
|
||||||
: error(path, position), identifier(identifier)
|
: error(path, position), identifier(identifier)
|
||||||
@@ -636,7 +636,7 @@ namespace elna::boot
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (boot::variable_declaration *const variable : definition->body.value().variables())
|
for (variable_declaration *const variable : definition->body.value().variables())
|
||||||
{
|
{
|
||||||
variable->accept(this);
|
variable->accept(this);
|
||||||
}
|
}
|
||||||
@@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with GCC; see the file COPYING3. If not see
|
along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "elna/boot/symbol.h"
|
#include "elna/frontend/symbol.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
type::type()
|
type::type()
|
||||||
{
|
{
|
||||||
@@ -150,7 +150,7 @@ elna.stagefeedback: stagefeedback-start
|
|||||||
ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated
|
ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated
|
||||||
ELNA_CXXFLAGS = -std=c++17
|
ELNA_CXXFLAGS = -std=c++17
|
||||||
|
|
||||||
elna/%.o: elna/boot/%.cc elna/generated/parser.hh elna/generated/location.hh
|
elna/%.o: elna/frontend/%.cc elna/generated/parser.hh elna/generated/location.hh
|
||||||
$(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $<
|
$(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $<
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
@@ -162,13 +162,13 @@ elna/%.o: elna/gcc/%.cc elna/generated/parser.hh elna/generated/location.hh
|
|||||||
$(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $<
|
$(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $<
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
elna/generated/parser.cc: elna/boot/parser.yy
|
elna/generated/parser.cc: elna/frontend/parser.yy
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(BISON) -d -o $@ $<
|
$(BISON) -d -o $@ $<
|
||||||
|
|
||||||
elna/generated/parser.hh elna/generated/location.hh: elna/generated/parser.cc
|
elna/generated/parser.hh elna/generated/location.hh: elna/generated/parser.cc
|
||||||
@touch $@
|
@touch $@
|
||||||
|
|
||||||
elna/generated/lexer.cc: elna/boot/lexer.ll
|
elna/generated/lexer.cc: elna/frontend/lexer.ll
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(FLEX) -o $@ $<
|
$(FLEX) -o $@ $<
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace elna::gcc
|
|||||||
return symbol_table;
|
return symbol_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree build_composite_type(const std::vector<boot::type_field>& fields, tree composite_type_node,
|
tree build_composite_type(const std::vector<frontend::type_field>& fields, tree composite_type_node,
|
||||||
std::shared_ptr<symbol_table> symbols)
|
std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
for (auto& field : fields)
|
for (auto& field : fields)
|
||||||
@@ -94,7 +94,7 @@ namespace elna::gcc
|
|||||||
return composite_type_node;
|
return composite_type_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree build_procedure_type(const boot::procedure_type& procedure, std::shared_ptr<symbol_table> symbols)
|
tree build_procedure_type(const frontend::procedure_type& procedure, std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
std::vector<tree> parameter_types(procedure.parameters.size());
|
std::vector<tree> parameter_types(procedure.parameters.size());
|
||||||
|
|
||||||
@@ -111,16 +111,16 @@ namespace elna::gcc
|
|||||||
return build_function_type_array(return_type, procedure.parameters.size(), parameter_types.data());
|
return build_function_type_array(return_type, procedure.parameters.size(), parameter_types.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols)
|
tree get_inner_alias(const frontend::type& type, std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
if (auto reference = type.get<boot::primitive_type>())
|
if (auto reference = type.get<frontend::primitive_type>())
|
||||||
{
|
{
|
||||||
auto looked_up = symbols->lookup(reference->identifier);
|
auto looked_up = symbols->lookup(reference->identifier);
|
||||||
gcc_assert(looked_up != NULL_TREE);
|
gcc_assert(looked_up != NULL_TREE);
|
||||||
|
|
||||||
return TREE_TYPE(looked_up);
|
return TREE_TYPE(looked_up);
|
||||||
}
|
}
|
||||||
else if (auto reference = type.get<boot::record_type>())
|
else if (auto reference = type.get<frontend::record_type>())
|
||||||
{
|
{
|
||||||
tree composite_type_node = make_node(RECORD_TYPE);
|
tree composite_type_node = make_node(RECORD_TYPE);
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ namespace elna::gcc
|
|||||||
|
|
||||||
return composite_type_node;
|
return composite_type_node;
|
||||||
}
|
}
|
||||||
else if (auto reference = type.get<boot::union_type>())
|
else if (auto reference = type.get<frontend::union_type>())
|
||||||
{
|
{
|
||||||
tree composite_type_node = make_node(UNION_TYPE);
|
tree composite_type_node = make_node(UNION_TYPE);
|
||||||
|
|
||||||
@@ -136,34 +136,34 @@ namespace elna::gcc
|
|||||||
|
|
||||||
return composite_type_node;
|
return composite_type_node;
|
||||||
}
|
}
|
||||||
else if (auto reference = type.get<boot::enumeration_type>())
|
else if (auto reference = type.get<frontend::enumeration_type>())
|
||||||
{
|
{
|
||||||
return build_enumeration_type(reference->members);
|
return build_enumeration_type(reference->members);
|
||||||
}
|
}
|
||||||
else if (auto reference = type.get<boot::pointer_type>())
|
else if (auto reference = type.get<frontend::pointer_type>())
|
||||||
{
|
{
|
||||||
return build_global_pointer_type(get_inner_alias(reference->base, symbols));
|
return build_global_pointer_type(get_inner_alias(reference->base, symbols));
|
||||||
}
|
}
|
||||||
else if (auto reference = type.get<boot::array_type>())
|
else if (auto reference = type.get<frontend::array_type>())
|
||||||
{
|
{
|
||||||
tree base = get_inner_alias(reference->base, symbols);
|
tree base = get_inner_alias(reference->base, symbols);
|
||||||
|
|
||||||
return build_static_array_type(base, reference->size);
|
return build_static_array_type(base, reference->size);
|
||||||
}
|
}
|
||||||
else if (auto reference = type.get<boot::procedure_type>())
|
else if (auto reference = type.get<frontend::procedure_type>())
|
||||||
{
|
{
|
||||||
auto procedure = build_procedure_type(*reference, symbols);
|
auto procedure = build_procedure_type(*reference, symbols);
|
||||||
|
|
||||||
return build_global_pointer_type(procedure);
|
return build_global_pointer_type(procedure);
|
||||||
}
|
}
|
||||||
else if (auto reference = type.get<boot::alias_type>())
|
else if (auto reference = type.get<frontend::alias_type>())
|
||||||
{
|
{
|
||||||
return TREE_TYPE(handle_symbol(reference->name, reference, symbols));
|
return TREE_TYPE(handle_symbol(reference->name, reference, symbols));
|
||||||
}
|
}
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree handle_symbol(const std::string& symbol_name, std::shared_ptr<boot::alias_type> reference,
|
tree handle_symbol(const std::string& symbol_name, std::shared_ptr<frontend::alias_type> reference,
|
||||||
std::shared_ptr<symbol_table> symbols)
|
std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
tree looked_up = symbols->lookup(symbol_name);
|
tree looked_up = symbols->lookup(symbol_name);
|
||||||
@@ -189,7 +189,7 @@ namespace elna::gcc
|
|||||||
return looked_up;
|
return looked_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
void declare_procedure(const std::string& name, const boot::procedure_info& info,
|
void declare_procedure(const std::string& name, const frontend::procedure_info& info,
|
||||||
std::shared_ptr<symbol_table> symbols)
|
std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
tree declaration_type = gcc::build_procedure_type(info.symbol, symbols);
|
tree declaration_type = gcc::build_procedure_type(info.symbol, symbols);
|
||||||
@@ -210,7 +210,7 @@ namespace elna::gcc
|
|||||||
|
|
||||||
std::vector<std::string>::const_iterator parameter_name = info.names.cbegin();
|
std::vector<std::string>::const_iterator parameter_name = info.names.cbegin();
|
||||||
|
|
||||||
for (boot::type parameter : info.symbol.parameters)
|
for (frontend::type parameter : info.symbol.parameters)
|
||||||
{
|
{
|
||||||
tree declaration_tree = build_decl(UNKNOWN_LOCATION, PARM_DECL,
|
tree declaration_tree = build_decl(UNKNOWN_LOCATION, PARM_DECL,
|
||||||
get_identifier(parameter_name->c_str()), function_args_iter_cond(¶meter_type));
|
get_identifier(parameter_name->c_str()), function_args_iter_cond(¶meter_type));
|
||||||
@@ -227,7 +227,7 @@ namespace elna::gcc
|
|||||||
TREE_PUBLIC(fndecl) = info.exported;
|
TREE_PUBLIC(fndecl) = info.exported;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree declare_variable(const std::string& name, const boot::variable_info& info,
|
tree declare_variable(const std::string& name, const frontend::variable_info& info,
|
||||||
std::shared_ptr<symbol_table> symbols)
|
std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
auto variable_type = get_inner_alias(info.symbol, symbols);
|
auto variable_type = get_inner_alias(info.symbol, symbols);
|
||||||
@@ -242,10 +242,10 @@ namespace elna::gcc
|
|||||||
return declaration_tree;
|
return declaration_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
void declare_type(const std::string& name, const boot::type_info& info, std::shared_ptr<symbol_table> symbols)
|
void declare_type(const std::string& name, const frontend::type_info& info, std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
// The top level symbol table has basic (builtin) types in it which are not aliases.
|
// The top level symbol table has basic (builtin) types in it which are not aliases.
|
||||||
if (auto alias_type = info.symbol.get<boot::alias_type>())
|
if (auto alias_type = info.symbol.get<frontend::alias_type>())
|
||||||
{
|
{
|
||||||
tree type_declaration = handle_symbol(name, alias_type, symbols);
|
tree type_declaration = handle_symbol(name, alias_type, symbols);
|
||||||
|
|
||||||
@@ -253,7 +253,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols)
|
void rewrite_symbol_table(std::shared_ptr<frontend::symbol_table> info_table, std::shared_ptr<symbol_table> symbols)
|
||||||
{
|
{
|
||||||
for (auto& [symbol_name, symbol_info] : *info_table)
|
for (auto& [symbol_name, symbol_info] : *info_table)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace elna::gcc
|
|||||||
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
|
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
location_t get_location(const boot::position *position)
|
location_t get_location(const frontend::position *position)
|
||||||
{
|
{
|
||||||
linemap_line_start(line_table, position->line, 0);
|
linemap_line_start(line_table, position->line, 0);
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ namespace elna::gcc
|
|||||||
gcc_unreachable();
|
gcc_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors)
|
void report_errors(const std::deque<std::unique_ptr<frontend::error>>& errors)
|
||||||
{
|
{
|
||||||
for (const auto& error : errors)
|
for (const auto& error : errors)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
|
|
||||||
namespace elna::gcc
|
namespace elna::gcc
|
||||||
{
|
{
|
||||||
generic_visitor::generic_visitor(std::shared_ptr<symbol_table> symbol_table, elna::boot::symbol_bag bag)
|
generic_visitor::generic_visitor(std::shared_ptr<symbol_table> symbol_table, elna::frontend::symbol_bag bag)
|
||||||
: bag(bag), symbols(symbol_table)
|
: bag(bag), symbols(symbol_table)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::build_procedure_call(location_t call_location,
|
void generic_visitor::build_procedure_call(location_t call_location,
|
||||||
tree procedure_address, const std::vector<boot::expression *>& arguments)
|
tree procedure_address, const std::vector<frontend::expression *>& arguments)
|
||||||
{
|
{
|
||||||
vec<tree, va_gc> *argument_trees = nullptr;
|
vec<tree, va_gc> *argument_trees = nullptr;
|
||||||
tree symbol_type = TREE_TYPE(TREE_TYPE(procedure_address));
|
tree symbol_type = TREE_TYPE(TREE_TYPE(procedure_address));
|
||||||
@@ -49,7 +49,7 @@ namespace elna::gcc
|
|||||||
tree current_parameter = TYPE_ARG_TYPES(symbol_type);
|
tree current_parameter = TYPE_ARG_TYPES(symbol_type);
|
||||||
|
|
||||||
vec_alloc(argument_trees, arguments.size());
|
vec_alloc(argument_trees, arguments.size());
|
||||||
for (boot::expression *const argument : arguments)
|
for (frontend::expression *const argument : arguments)
|
||||||
{
|
{
|
||||||
location_t argument_location = get_location(&argument->position());
|
location_t argument_location = get_location(&argument->position());
|
||||||
if (VOID_TYPE_P(TREE_VALUE(current_parameter)))
|
if (VOID_TYPE_P(TREE_VALUE(current_parameter)))
|
||||||
@@ -88,11 +88,11 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::build_record_call(location_t call_location,
|
void generic_visitor::build_record_call(location_t call_location,
|
||||||
tree symbol, const std::vector<boot::expression *>& arguments)
|
tree symbol, const std::vector<frontend::expression *>& arguments)
|
||||||
{
|
{
|
||||||
vec<constructor_elt, va_gc> *tree_arguments = nullptr;
|
vec<constructor_elt, va_gc> *tree_arguments = nullptr;
|
||||||
tree record_fields = TYPE_FIELDS(symbol);
|
tree record_fields = TYPE_FIELDS(symbol);
|
||||||
for (boot::expression *const argument : arguments)
|
for (frontend::expression *const argument : arguments)
|
||||||
{
|
{
|
||||||
location_t argument_location = get_location(&argument->position());
|
location_t argument_location = get_location(&argument->position());
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::build_assert_builtin(location_t call_location,
|
void generic_visitor::build_assert_builtin(location_t call_location,
|
||||||
const std::vector<boot::expression *>& arguments)
|
const std::vector<frontend::expression *>& arguments)
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
{
|
{
|
||||||
@@ -165,11 +165,11 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generic_visitor::build_builtin_procedures(boot::procedure_call *call)
|
bool generic_visitor::build_builtin_procedures(frontend::procedure_call *call)
|
||||||
{
|
{
|
||||||
location_t call_location = get_location(&call->position());
|
location_t call_location = get_location(&call->position());
|
||||||
|
|
||||||
if (boot::variable_expression *named_call = call->callable().is_variable())
|
if (frontend::variable_expression *named_call = call->callable().is_variable())
|
||||||
{
|
{
|
||||||
if (named_call->name == "assert")
|
if (named_call->name == "assert")
|
||||||
{
|
{
|
||||||
@@ -180,7 +180,7 @@ namespace elna::gcc
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::procedure_call *call)
|
void generic_visitor::visit(frontend::procedure_call *call)
|
||||||
{
|
{
|
||||||
if (build_builtin_procedures(call))
|
if (build_builtin_procedures(call))
|
||||||
{
|
{
|
||||||
@@ -215,7 +215,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::cast_expression *expression)
|
void generic_visitor::visit(frontend::cast_expression *expression)
|
||||||
{
|
{
|
||||||
tree cast_target = get_inner_alias(expression->expression_type, this->symbols->scope());
|
tree cast_target = get_inner_alias(expression->expression_type, this->symbols->scope());
|
||||||
|
|
||||||
@@ -235,9 +235,9 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::program *program)
|
void generic_visitor::visit(frontend::program *program)
|
||||||
{
|
{
|
||||||
visit(static_cast<boot::unit *>(program));
|
visit(static_cast<frontend::unit *>(program));
|
||||||
|
|
||||||
tree declaration_type = build_function_type_list(elna_int_type_node,
|
tree declaration_type = build_function_type_list(elna_int_type_node,
|
||||||
elna_int_type_node,
|
elna_int_type_node,
|
||||||
@@ -285,27 +285,27 @@ namespace elna::gcc
|
|||||||
cgraph_node::finalize_function(fndecl, true);
|
cgraph_node::finalize_function(fndecl, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::unit *unit)
|
void generic_visitor::visit(frontend::unit *unit)
|
||||||
{
|
{
|
||||||
for (boot::import_declaration *const declaration : unit->imports)
|
for (frontend::import_declaration *const declaration : unit->imports)
|
||||||
{
|
{
|
||||||
declaration->accept(this);
|
declaration->accept(this);
|
||||||
}
|
}
|
||||||
for (boot::constant_declaration *const constant : unit->constants)
|
for (frontend::constant_declaration *const constant : unit->constants)
|
||||||
{
|
{
|
||||||
constant->accept(this);
|
constant->accept(this);
|
||||||
}
|
}
|
||||||
for (boot::variable_declaration *const variable : unit->variables)
|
for (frontend::variable_declaration *const variable : unit->variables)
|
||||||
{
|
{
|
||||||
variable->accept(this);
|
variable->accept(this);
|
||||||
}
|
}
|
||||||
for (boot::procedure_declaration *const procedure : unit->procedures)
|
for (frontend::procedure_declaration *const procedure : unit->procedures)
|
||||||
{
|
{
|
||||||
procedure->accept(this);
|
procedure->accept(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::procedure_declaration *definition)
|
void generic_visitor::visit(frontend::procedure_declaration *definition)
|
||||||
{
|
{
|
||||||
tree fndecl = this->symbols->lookup(definition->identifier.name);
|
tree fndecl = this->symbols->lookup(definition->identifier.name);
|
||||||
|
|
||||||
@@ -324,11 +324,11 @@ namespace elna::gcc
|
|||||||
{
|
{
|
||||||
this->symbols->enter(IDENTIFIER_POINTER(DECL_NAME(argument_chain)), argument_chain);
|
this->symbols->enter(IDENTIFIER_POINTER(DECL_NAME(argument_chain)), argument_chain);
|
||||||
}
|
}
|
||||||
for (boot::constant_declaration *const constant : definition->body.value().constants())
|
for (frontend::constant_declaration *const constant : definition->body.value().constants())
|
||||||
{
|
{
|
||||||
constant->accept(this);
|
constant->accept(this);
|
||||||
}
|
}
|
||||||
for (boot::variable_declaration *const variable : definition->body.value().variables())
|
for (frontend::variable_declaration *const variable : definition->body.value().variables())
|
||||||
{
|
{
|
||||||
variable->accept(this);
|
variable->accept(this);
|
||||||
}
|
}
|
||||||
@@ -381,17 +381,17 @@ namespace elna::gcc
|
|||||||
return bind_expr;
|
return bind_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::literal<std::int32_t> *literal)
|
void generic_visitor::visit(frontend::literal<std::int32_t> *literal)
|
||||||
{
|
{
|
||||||
this->current_expression = build_int_cst(elna_int_type_node, literal->value);
|
this->current_expression = build_int_cst(elna_int_type_node, literal->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::literal<std::uint32_t> *literal)
|
void generic_visitor::visit(frontend::literal<std::uint32_t> *literal)
|
||||||
{
|
{
|
||||||
this->current_expression = build_int_cstu(elna_word_type_node, literal->value);
|
this->current_expression = build_int_cstu(elna_word_type_node, literal->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::literal<double> *literal)
|
void generic_visitor::visit(frontend::literal<double> *literal)
|
||||||
{
|
{
|
||||||
REAL_VALUE_TYPE real_value1;
|
REAL_VALUE_TYPE real_value1;
|
||||||
|
|
||||||
@@ -406,22 +406,22 @@ namespace elna::gcc
|
|||||||
mpfr_clear(number);
|
mpfr_clear(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::literal<bool> *boolean)
|
void generic_visitor::visit(frontend::literal<bool> *boolean)
|
||||||
{
|
{
|
||||||
this->current_expression = boolean->value ? boolean_true_node : boolean_false_node;
|
this->current_expression = boolean->value ? boolean_true_node : boolean_false_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::literal<unsigned char> *character)
|
void generic_visitor::visit(frontend::literal<unsigned char> *character)
|
||||||
{
|
{
|
||||||
this->current_expression = build_int_cstu(elna_char_type_node, character->value);
|
this->current_expression = build_int_cstu(elna_char_type_node, character->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::literal<nullptr_t> *)
|
void generic_visitor::visit(frontend::literal<nullptr_t> *)
|
||||||
{
|
{
|
||||||
this->current_expression = elna_pointer_nil_node;
|
this->current_expression = elna_pointer_nil_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::literal<std::string> *string)
|
void generic_visitor::visit(frontend::literal<std::string> *string)
|
||||||
{
|
{
|
||||||
tree index_constant = build_int_cstu(elna_word_type_node, string->value.size());
|
tree index_constant = build_int_cstu(elna_word_type_node, string->value.size());
|
||||||
tree string_type = build_array_type(elna_char_type_node, build_index_type(index_constant));
|
tree string_type = build_array_type(elna_char_type_node, build_index_type(index_constant));
|
||||||
@@ -444,38 +444,38 @@ namespace elna::gcc
|
|||||||
this->current_expression = build_constructor(elna_string_type_node, elms);
|
this->current_expression = build_constructor(elna_string_type_node, elms);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree generic_visitor::build_arithmetic_operation(boot::binary_expression *expression,
|
tree generic_visitor::build_arithmetic_operation(frontend::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right)
|
tree_code operator_code, tree left, tree right)
|
||||||
{
|
{
|
||||||
return build_binary_operation(is_numeric_type(TREE_TYPE(left)),
|
return build_binary_operation(is_numeric_type(TREE_TYPE(left)),
|
||||||
expression, operator_code, left, right, TREE_TYPE(left));
|
expression, operator_code, left, right, TREE_TYPE(left));
|
||||||
}
|
}
|
||||||
|
|
||||||
tree generic_visitor::build_comparison_operation(boot::binary_expression *expression,
|
tree generic_visitor::build_comparison_operation(frontend::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right)
|
tree_code operator_code, tree left, tree right)
|
||||||
{
|
{
|
||||||
return build_binary_operation(is_numeric_type(TREE_TYPE(left)) || POINTER_TYPE_P(TREE_TYPE(left)),
|
return build_binary_operation(is_numeric_type(TREE_TYPE(left)) || POINTER_TYPE_P(TREE_TYPE(left)),
|
||||||
expression, operator_code, left, right, elna_bool_type_node);
|
expression, operator_code, left, right, elna_bool_type_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree generic_visitor::build_bit_logic_operation(boot::binary_expression *expression, tree left, tree right)
|
tree generic_visitor::build_bit_logic_operation(frontend::binary_expression *expression, tree left, tree right)
|
||||||
{
|
{
|
||||||
location_t expression_location = get_location(&expression->position());
|
location_t expression_location = get_location(&expression->position());
|
||||||
tree left_type = TREE_TYPE(left);
|
tree left_type = TREE_TYPE(left);
|
||||||
tree right_type = TREE_TYPE(right);
|
tree right_type = TREE_TYPE(right);
|
||||||
tree_code logical_code, bit_code;
|
tree_code logical_code, bit_code;
|
||||||
|
|
||||||
if (expression->operation() == boot::binary_operator::conjunction)
|
if (expression->operation() == frontend::binary_operator::conjunction)
|
||||||
{
|
{
|
||||||
bit_code = BIT_AND_EXPR;
|
bit_code = BIT_AND_EXPR;
|
||||||
logical_code = TRUTH_ANDIF_EXPR;
|
logical_code = TRUTH_ANDIF_EXPR;
|
||||||
}
|
}
|
||||||
else if (expression->operation() == boot::binary_operator::disjunction)
|
else if (expression->operation() == frontend::binary_operator::disjunction)
|
||||||
{
|
{
|
||||||
bit_code = BIT_IOR_EXPR;
|
bit_code = BIT_IOR_EXPR;
|
||||||
logical_code = TRUTH_ORIF_EXPR;
|
logical_code = TRUTH_ORIF_EXPR;
|
||||||
}
|
}
|
||||||
else if (expression->operation() == boot::binary_operator::exclusive_disjunction)
|
else if (expression->operation() == frontend::binary_operator::exclusive_disjunction)
|
||||||
{
|
{
|
||||||
bit_code = BIT_XOR_EXPR;
|
bit_code = BIT_XOR_EXPR;
|
||||||
logical_code = TRUTH_XOR_EXPR;
|
logical_code = TRUTH_XOR_EXPR;
|
||||||
@@ -496,22 +496,22 @@ namespace elna::gcc
|
|||||||
{
|
{
|
||||||
error_at(expression_location, "Invalid operands of type '%s' and '%s' for operator %s",
|
error_at(expression_location, "Invalid operands of type '%s' and '%s' for operator %s",
|
||||||
print_type(left_type).c_str(), print_type(right_type).c_str(),
|
print_type(left_type).c_str(), print_type(right_type).c_str(),
|
||||||
elna::boot::print_binary_operator(expression->operation()));
|
elna::frontend::print_binary_operator(expression->operation()));
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree generic_visitor::build_equality_operation(boot::binary_expression *expression, tree left, tree right)
|
tree generic_visitor::build_equality_operation(frontend::binary_expression *expression, tree left, tree right)
|
||||||
{
|
{
|
||||||
location_t expression_location = get_location(&expression->position());
|
location_t expression_location = get_location(&expression->position());
|
||||||
tree_code equality_code, combination_code;
|
tree_code equality_code, combination_code;
|
||||||
|
|
||||||
if (expression->operation() == boot::binary_operator::equals)
|
if (expression->operation() == frontend::binary_operator::equals)
|
||||||
{
|
{
|
||||||
equality_code = EQ_EXPR;
|
equality_code = EQ_EXPR;
|
||||||
combination_code = TRUTH_ANDIF_EXPR;
|
combination_code = TRUTH_ANDIF_EXPR;
|
||||||
}
|
}
|
||||||
else if (expression->operation() == boot::binary_operator::not_equals)
|
else if (expression->operation() == frontend::binary_operator::not_equals)
|
||||||
{
|
{
|
||||||
equality_code = NE_EXPR;
|
equality_code = NE_EXPR;
|
||||||
combination_code = TRUTH_ORIF_EXPR;
|
combination_code = TRUTH_ORIF_EXPR;
|
||||||
@@ -545,7 +545,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::binary_expression *expression)
|
void generic_visitor::visit(frontend::binary_expression *expression)
|
||||||
{
|
{
|
||||||
expression->lhs().accept(this);
|
expression->lhs().accept(this);
|
||||||
tree left = this->current_expression;
|
tree left = this->current_expression;
|
||||||
@@ -558,8 +558,8 @@ namespace elna::gcc
|
|||||||
location_t expression_location = get_location(&expression->position());
|
location_t expression_location = get_location(&expression->position());
|
||||||
|
|
||||||
if ((POINTER_TYPE_P(left_type) || POINTER_TYPE_P(right_type))
|
if ((POINTER_TYPE_P(left_type) || POINTER_TYPE_P(right_type))
|
||||||
&& (expression->operation() == boot::binary_operator::sum
|
&& (expression->operation() == frontend::binary_operator::sum
|
||||||
|| expression->operation() == boot::binary_operator::subtraction))
|
|| expression->operation() == frontend::binary_operator::subtraction))
|
||||||
{
|
{
|
||||||
this->current_expression = do_pointer_arithmetic(expression->operation(),
|
this->current_expression = do_pointer_arithmetic(expression->operation(),
|
||||||
left, right, expression_location);
|
left, right, expression_location);
|
||||||
@@ -567,7 +567,7 @@ namespace elna::gcc
|
|||||||
{
|
{
|
||||||
error_at(expression_location,
|
error_at(expression_location,
|
||||||
"invalid operation %s on a pointer and an integral type",
|
"invalid operation %s on a pointer and an integral type",
|
||||||
boot::print_binary_operator(expression->operation()));
|
frontend::print_binary_operator(expression->operation()));
|
||||||
}
|
}
|
||||||
else if (TREE_TYPE(this->current_expression) == ssizetype)
|
else if (TREE_TYPE(this->current_expression) == ssizetype)
|
||||||
{
|
{
|
||||||
@@ -583,60 +583,60 @@ namespace elna::gcc
|
|||||||
error_at(expression_location,
|
error_at(expression_location,
|
||||||
"invalid operands of type '%s' and '%s' for operator %s",
|
"invalid operands of type '%s' and '%s' for operator %s",
|
||||||
print_type(left_type).c_str(), print_type(right_type).c_str(),
|
print_type(left_type).c_str(), print_type(right_type).c_str(),
|
||||||
boot::print_binary_operator(expression->operation()));
|
frontend::print_binary_operator(expression->operation()));
|
||||||
this->current_expression = error_mark_node;
|
this->current_expression = error_mark_node;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (expression->operation())
|
switch (expression->operation())
|
||||||
{
|
{
|
||||||
case boot::binary_operator::sum:
|
case frontend::binary_operator::sum:
|
||||||
this->current_expression = build_arithmetic_operation(expression, PLUS_EXPR, left, right);
|
this->current_expression = build_arithmetic_operation(expression, PLUS_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::subtraction:
|
case frontend::binary_operator::subtraction:
|
||||||
this->current_expression = build_arithmetic_operation(expression, MINUS_EXPR, left, right);
|
this->current_expression = build_arithmetic_operation(expression, MINUS_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::division:
|
case frontend::binary_operator::division:
|
||||||
this->current_expression = build_arithmetic_operation(expression, TRUNC_DIV_EXPR, left, right);
|
this->current_expression = build_arithmetic_operation(expression, TRUNC_DIV_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::remainder:
|
case frontend::binary_operator::remainder:
|
||||||
this->current_expression = build_arithmetic_operation(expression, TRUNC_MOD_EXPR, left, right);
|
this->current_expression = build_arithmetic_operation(expression, TRUNC_MOD_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::multiplication:
|
case frontend::binary_operator::multiplication:
|
||||||
this->current_expression = build_arithmetic_operation(expression, MULT_EXPR, left, right);
|
this->current_expression = build_arithmetic_operation(expression, MULT_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::less:
|
case frontend::binary_operator::less:
|
||||||
this->current_expression = build_comparison_operation(expression, LT_EXPR, left, right);
|
this->current_expression = build_comparison_operation(expression, LT_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::greater:
|
case frontend::binary_operator::greater:
|
||||||
this->current_expression = build_comparison_operation(expression, GT_EXPR, left, right);
|
this->current_expression = build_comparison_operation(expression, GT_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::less_equal:
|
case frontend::binary_operator::less_equal:
|
||||||
this->current_expression = build_comparison_operation(expression, LE_EXPR, left, right);
|
this->current_expression = build_comparison_operation(expression, LE_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::greater_equal:
|
case frontend::binary_operator::greater_equal:
|
||||||
this->current_expression = build_comparison_operation(expression, GE_EXPR, left, right);
|
this->current_expression = build_comparison_operation(expression, GE_EXPR, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::conjunction:
|
case frontend::binary_operator::conjunction:
|
||||||
this->current_expression = build_bit_logic_operation(expression, left, right);
|
this->current_expression = build_bit_logic_operation(expression, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::disjunction:
|
case frontend::binary_operator::disjunction:
|
||||||
this->current_expression = build_bit_logic_operation(expression, left, right);
|
this->current_expression = build_bit_logic_operation(expression, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::exclusive_disjunction:
|
case frontend::binary_operator::exclusive_disjunction:
|
||||||
this->current_expression = build_bit_logic_operation(expression, left, right);
|
this->current_expression = build_bit_logic_operation(expression, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::equals:
|
case frontend::binary_operator::equals:
|
||||||
this->current_expression = build_equality_operation(expression, left, right);
|
this->current_expression = build_equality_operation(expression, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::not_equals:
|
case frontend::binary_operator::not_equals:
|
||||||
this->current_expression = build_equality_operation(expression, left, right);
|
this->current_expression = build_equality_operation(expression, left, right);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::shift_left:
|
case frontend::binary_operator::shift_left:
|
||||||
this->current_expression = build_binary_operation(
|
this->current_expression = build_binary_operation(
|
||||||
is_numeric_type(left_type) && right_type == elna_word_type_node,
|
is_numeric_type(left_type) && right_type == elna_word_type_node,
|
||||||
expression, LSHIFT_EXPR, left, right, left_type);
|
expression, LSHIFT_EXPR, left, right, left_type);
|
||||||
break;
|
break;
|
||||||
case boot::binary_operator::shift_right:
|
case frontend::binary_operator::shift_right:
|
||||||
this->current_expression = build_binary_operation(
|
this->current_expression = build_binary_operation(
|
||||||
is_numeric_type(left_type) && right_type == elna_word_type_node,
|
is_numeric_type(left_type) && right_type == elna_word_type_node,
|
||||||
expression, RSHIFT_EXPR, left, right, left_type);
|
expression, RSHIFT_EXPR, left, right, left_type);
|
||||||
@@ -644,14 +644,14 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::unary_expression *expression)
|
void generic_visitor::visit(frontend::unary_expression *expression)
|
||||||
{
|
{
|
||||||
expression->operand().accept(this);
|
expression->operand().accept(this);
|
||||||
location_t location = get_location(&expression->position());
|
location_t location = get_location(&expression->position());
|
||||||
|
|
||||||
switch (expression->operation())
|
switch (expression->operation())
|
||||||
{
|
{
|
||||||
case boot::unary_operator::reference:
|
case frontend::unary_operator::reference:
|
||||||
this->current_expression = prepare_rvalue(this->current_expression);
|
this->current_expression = prepare_rvalue(this->current_expression);
|
||||||
TREE_ADDRESSABLE(this->current_expression) = 1;
|
TREE_ADDRESSABLE(this->current_expression) = 1;
|
||||||
this->current_expression = build_fold_addr_expr_with_type_loc(location,
|
this->current_expression = build_fold_addr_expr_with_type_loc(location,
|
||||||
@@ -659,7 +659,7 @@ namespace elna::gcc
|
|||||||
build_global_pointer_type(TREE_TYPE(this->current_expression)));
|
build_global_pointer_type(TREE_TYPE(this->current_expression)));
|
||||||
TREE_NO_TRAMPOLINE(this->current_expression) = 1;
|
TREE_NO_TRAMPOLINE(this->current_expression) = 1;
|
||||||
break;
|
break;
|
||||||
case boot::unary_operator::negation:
|
case frontend::unary_operator::negation:
|
||||||
if (TREE_TYPE(this->current_expression) == elna_bool_type_node)
|
if (TREE_TYPE(this->current_expression) == elna_bool_type_node)
|
||||||
{
|
{
|
||||||
this->current_expression = build1_loc(location, TRUTH_NOT_EXPR,
|
this->current_expression = build1_loc(location, TRUTH_NOT_EXPR,
|
||||||
@@ -677,7 +677,7 @@ namespace elna::gcc
|
|||||||
this->current_expression = error_mark_node;
|
this->current_expression = error_mark_node;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case boot::unary_operator::minus:
|
case frontend::unary_operator::minus:
|
||||||
if (is_integral_type(TREE_TYPE(this->current_expression)))
|
if (is_integral_type(TREE_TYPE(this->current_expression)))
|
||||||
{
|
{
|
||||||
this->current_expression = fold_build1(NEGATE_EXPR, TREE_TYPE(this->current_expression),
|
this->current_expression = fold_build1(NEGATE_EXPR, TREE_TYPE(this->current_expression),
|
||||||
@@ -692,7 +692,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::constant_declaration *definition)
|
void generic_visitor::visit(frontend::constant_declaration *definition)
|
||||||
{
|
{
|
||||||
location_t definition_location = get_location(&definition->position());
|
location_t definition_location = get_location(&definition->position());
|
||||||
definition->body().accept(this);
|
definition->body().accept(this);
|
||||||
@@ -732,7 +732,7 @@ namespace elna::gcc
|
|||||||
this->current_expression = NULL_TREE;
|
this->current_expression = NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::variable_declaration *declaration)
|
void generic_visitor::visit(frontend::variable_declaration *declaration)
|
||||||
{
|
{
|
||||||
for (const auto& variable_identifier : declaration->identifiers)
|
for (const auto& variable_identifier : declaration->identifiers)
|
||||||
{
|
{
|
||||||
@@ -784,7 +784,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::variable_expression *expression)
|
void generic_visitor::visit(frontend::variable_expression *expression)
|
||||||
{
|
{
|
||||||
auto symbol = this->symbols->lookup(expression->name);
|
auto symbol = this->symbols->lookup(expression->name);
|
||||||
|
|
||||||
@@ -800,7 +800,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::array_access_expression *expression)
|
void generic_visitor::visit(frontend::array_access_expression *expression)
|
||||||
{
|
{
|
||||||
expression->base().accept(this);
|
expression->base().accept(this);
|
||||||
tree designator = this->current_expression;
|
tree designator = this->current_expression;
|
||||||
@@ -829,7 +829,7 @@ namespace elna::gcc
|
|||||||
tree string_ptr = build3_loc(location, COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
|
tree string_ptr = build3_loc(location, COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
|
||||||
designator, elna_string_ptr_field_node, NULL_TREE);
|
designator, elna_string_ptr_field_node, NULL_TREE);
|
||||||
|
|
||||||
tree target_pointer = do_pointer_arithmetic(boot::binary_operator::sum, string_ptr, offset, location);
|
tree target_pointer = do_pointer_arithmetic(frontend::binary_operator::sum, string_ptr, offset, location);
|
||||||
|
|
||||||
this->current_expression = build1_loc(location, INDIRECT_REF,
|
this->current_expression = build1_loc(location, INDIRECT_REF,
|
||||||
elna_char_type_node, target_pointer);
|
elna_char_type_node, target_pointer);
|
||||||
@@ -842,7 +842,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generic_visitor::expect_trait_type_only(boot::traits_expression *trait)
|
bool generic_visitor::expect_trait_type_only(frontend::traits_expression *trait)
|
||||||
{
|
{
|
||||||
if (trait->parameters.size() != 1)
|
if (trait->parameters.size() != 1)
|
||||||
{
|
{
|
||||||
@@ -856,7 +856,7 @@ namespace elna::gcc
|
|||||||
return this->current_expression != error_mark_node;
|
return this->current_expression != error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generic_visitor::expect_trait_for_integral_type(boot::traits_expression *trait)
|
bool generic_visitor::expect_trait_for_integral_type(frontend::traits_expression *trait)
|
||||||
{
|
{
|
||||||
if (!expect_trait_type_only(trait))
|
if (!expect_trait_type_only(trait))
|
||||||
{
|
{
|
||||||
@@ -872,7 +872,7 @@ namespace elna::gcc
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::traits_expression *trait)
|
void generic_visitor::visit(frontend::traits_expression *trait)
|
||||||
{
|
{
|
||||||
location_t trait_location = get_location(&trait->position());
|
location_t trait_location = get_location(&trait->position());
|
||||||
|
|
||||||
@@ -945,7 +945,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::field_access_expression *expression)
|
void generic_visitor::visit(frontend::field_access_expression *expression)
|
||||||
{
|
{
|
||||||
expression->base().accept(this);
|
expression->base().accept(this);
|
||||||
location_t expression_location = get_location(&expression->position());
|
location_t expression_location = get_location(&expression->position());
|
||||||
@@ -991,7 +991,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::dereference_expression *expression)
|
void generic_visitor::visit(frontend::dereference_expression *expression)
|
||||||
{
|
{
|
||||||
expression->base().accept(this);
|
expression->base().accept(this);
|
||||||
location_t expression_location = get_location(&expression->position());
|
location_t expression_location = get_location(&expression->position());
|
||||||
@@ -1010,7 +1010,7 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::assign_statement *statement)
|
void generic_visitor::visit(frontend::assign_statement *statement)
|
||||||
{
|
{
|
||||||
statement->lvalue().accept(this);
|
statement->lvalue().accept(this);
|
||||||
|
|
||||||
@@ -1045,7 +1045,7 @@ namespace elna::gcc
|
|||||||
this->current_expression = NULL_TREE;
|
this->current_expression = NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::if_statement *statement)
|
void generic_visitor::visit(frontend::if_statement *statement)
|
||||||
{
|
{
|
||||||
tree endif_label_decl = create_artificial_label(UNKNOWN_LOCATION);
|
tree endif_label_decl = create_artificial_label(UNKNOWN_LOCATION);
|
||||||
tree goto_endif = build1(GOTO_EXPR, void_type_node, endif_label_decl);
|
tree goto_endif = build1(GOTO_EXPR, void_type_node, endif_label_decl);
|
||||||
@@ -1068,7 +1068,7 @@ namespace elna::gcc
|
|||||||
this->current_expression = NULL_TREE;
|
this->current_expression = NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::make_if_branch(boot::conditional_statements& branch, tree goto_endif)
|
void generic_visitor::make_if_branch(frontend::conditional_statements& branch, tree goto_endif)
|
||||||
{
|
{
|
||||||
branch.prerequisite().accept(this);
|
branch.prerequisite().accept(this);
|
||||||
|
|
||||||
@@ -1102,11 +1102,11 @@ namespace elna::gcc
|
|||||||
append_statement(else_label_expr);
|
append_statement(else_label_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::import_declaration *)
|
void generic_visitor::visit(frontend::import_declaration *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::while_statement *statement)
|
void generic_visitor::visit(frontend::while_statement *statement)
|
||||||
{
|
{
|
||||||
location_t prerequisite_location = get_location(&statement->body().prerequisite().position());
|
location_t prerequisite_location = get_location(&statement->body().prerequisite().position());
|
||||||
tree prerequisite_label_decl = build_label_decl("while_do", prerequisite_location);
|
tree prerequisite_label_decl = build_label_decl("while_do", prerequisite_location);
|
||||||
@@ -1127,9 +1127,9 @@ namespace elna::gcc
|
|||||||
this->current_expression = NULL_TREE;
|
this->current_expression = NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit_statements(const std::vector<boot::statement *>& statements)
|
void generic_visitor::visit_statements(const std::vector<frontend::statement *>& statements)
|
||||||
{
|
{
|
||||||
for (boot::statement *const statement : statements)
|
for (frontend::statement *const statement : statements)
|
||||||
{
|
{
|
||||||
statement->accept(this);
|
statement->accept(this);
|
||||||
|
|
||||||
@@ -1141,9 +1141,9 @@ namespace elna::gcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::return_statement *statement)
|
void generic_visitor::visit(frontend::return_statement *statement)
|
||||||
{
|
{
|
||||||
boot::expression *return_expression = &statement->return_expression();
|
frontend::expression *return_expression = &statement->return_expression();
|
||||||
location_t statement_position = get_location(&statement->position());
|
location_t statement_position = get_location(&statement->position());
|
||||||
tree set_result{ NULL_TREE };
|
tree set_result{ NULL_TREE };
|
||||||
tree return_type = TREE_TYPE(TREE_TYPE(current_function_decl));
|
tree return_type = TREE_TYPE(TREE_TYPE(current_function_decl));
|
||||||
@@ -1183,14 +1183,14 @@ namespace elna::gcc
|
|||||||
this->current_expression = NULL_TREE;
|
this->current_expression = NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::defer_statement *statement)
|
void generic_visitor::visit(frontend::defer_statement *statement)
|
||||||
{
|
{
|
||||||
enter_scope();
|
enter_scope();
|
||||||
visit_statements(statement->statements);
|
visit_statements(statement->statements);
|
||||||
defer(leave_scope());
|
defer(leave_scope());
|
||||||
}
|
}
|
||||||
|
|
||||||
void generic_visitor::visit(boot::case_statement *statement)
|
void generic_visitor::visit(frontend::case_statement *statement)
|
||||||
{
|
{
|
||||||
statement->condition().accept(this);
|
statement->condition().accept(this);
|
||||||
tree condition_expression = this->current_expression;
|
tree condition_expression = this->current_expression;
|
||||||
@@ -1207,9 +1207,9 @@ namespace elna::gcc
|
|||||||
tree end_label_declaration = create_artificial_label(get_location(&statement->position()));
|
tree end_label_declaration = create_artificial_label(get_location(&statement->position()));
|
||||||
tree switch_statements = alloc_stmt_list();
|
tree switch_statements = alloc_stmt_list();
|
||||||
|
|
||||||
for (const boot::switch_case& case_block : statement->cases)
|
for (const frontend::switch_case& case_block : statement->cases)
|
||||||
{
|
{
|
||||||
for (boot::expression *const case_label : case_block.labels)
|
for (frontend::expression *const case_label : case_block.labels)
|
||||||
{
|
{
|
||||||
case_label->accept(this);
|
case_label->accept(this);
|
||||||
location_t case_location = get_location(&case_label->position());
|
location_t case_location = get_location(&case_label->position());
|
||||||
|
|||||||
@@ -128,12 +128,12 @@ namespace elna::gcc
|
|||||||
return field_declaration;
|
return field_declaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree do_pointer_arithmetic(boot::binary_operator binary_operator,
|
tree do_pointer_arithmetic(frontend::binary_operator binary_operator,
|
||||||
tree left, tree right, location_t operation_location)
|
tree left, tree right, location_t operation_location)
|
||||||
{
|
{
|
||||||
tree left_type = get_qualified_type(TREE_TYPE(left), TYPE_UNQUALIFIED);
|
tree left_type = get_qualified_type(TREE_TYPE(left), TYPE_UNQUALIFIED);
|
||||||
tree right_type = get_qualified_type(TREE_TYPE(right), TYPE_UNQUALIFIED);
|
tree right_type = get_qualified_type(TREE_TYPE(right), TYPE_UNQUALIFIED);
|
||||||
if (binary_operator == boot::binary_operator::sum)
|
if (binary_operator == frontend::binary_operator::sum)
|
||||||
{
|
{
|
||||||
tree pointer{ NULL_TREE };
|
tree pointer{ NULL_TREE };
|
||||||
tree offset{ NULL_TREE };
|
tree offset{ NULL_TREE };
|
||||||
@@ -164,7 +164,7 @@ namespace elna::gcc
|
|||||||
|
|
||||||
return fold_build2_loc(operation_location, POINTER_PLUS_EXPR, TREE_TYPE(pointer), pointer, offset);
|
return fold_build2_loc(operation_location, POINTER_PLUS_EXPR, TREE_TYPE(pointer), pointer, offset);
|
||||||
}
|
}
|
||||||
else if (binary_operator == boot::binary_operator::subtraction)
|
else if (binary_operator == frontend::binary_operator::subtraction)
|
||||||
{
|
{
|
||||||
if (POINTER_TYPE_P(left_type) && is_integral_type(right_type))
|
if (POINTER_TYPE_P(left_type) && is_integral_type(right_type))
|
||||||
{
|
{
|
||||||
@@ -186,7 +186,7 @@ namespace elna::gcc
|
|||||||
gcc_unreachable();
|
gcc_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
tree build_binary_operation(bool condition, boot::binary_expression *expression,
|
tree build_binary_operation(bool condition, frontend::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right, tree target_type)
|
tree_code operator_code, tree left, tree right, tree target_type)
|
||||||
{
|
{
|
||||||
location_t expression_location = get_location(&expression->position());
|
location_t expression_location = get_location(&expression->position());
|
||||||
@@ -202,7 +202,7 @@ namespace elna::gcc
|
|||||||
error_at(expression_location,
|
error_at(expression_location,
|
||||||
"invalid operands of type '%s' and '%s' for operator %s",
|
"invalid operands of type '%s' and '%s' for operator %s",
|
||||||
print_type(left_type).c_str(), print_type(right_type).c_str(),
|
print_type(left_type).c_str(), print_type(right_type).c_str(),
|
||||||
elna::boot::print_binary_operator(expression->operation()));
|
elna::frontend::print_binary_operator(expression->operation()));
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
gcc/elna1.cc
16
gcc/elna1.cc
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include "langhooks-def.h"
|
#include "langhooks-def.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "elna/boot/dependency.h"
|
#include "elna/frontend/dependency.h"
|
||||||
#include "elna/gcc/elna-tree.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"
|
||||||
@@ -62,9 +62,9 @@ static bool elna_langhook_init(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
using dependency_state = elna::boot::dependency_state<std::shared_ptr<elna::gcc::symbol_table>>;
|
using dependency_state = elna::frontend::dependency_state<std::shared_ptr<elna::gcc::symbol_table>>;
|
||||||
|
|
||||||
static elna::boot::dependency elna_parse_file(dependency_state& state, const char *filename)
|
static elna::frontend::dependency elna_parse_file(dependency_state& state, const char *filename)
|
||||||
{
|
{
|
||||||
std::ifstream entry_point{ filename, std::ios::in };
|
std::ifstream entry_point{ filename, std::ios::in };
|
||||||
|
|
||||||
@@ -73,19 +73,19 @@ static elna::boot::dependency elna_parse_file(dependency_state& state, const cha
|
|||||||
fatal_error(UNKNOWN_LOCATION, "Cannot open filename %s: %m", filename);
|
fatal_error(UNKNOWN_LOCATION, "Cannot open filename %s: %m", filename);
|
||||||
}
|
}
|
||||||
elna::gcc::linemap_guard{ filename };
|
elna::gcc::linemap_guard{ filename };
|
||||||
elna::boot::dependency outcome = elna::boot::read_source(entry_point, filename);
|
elna::frontend::dependency outcome = elna::frontend::read_source(entry_point, filename);
|
||||||
|
|
||||||
if (outcome.has_errors())
|
if (outcome.has_errors())
|
||||||
{
|
{
|
||||||
elna::gcc::report_errors(outcome.errors());
|
elna::gcc::report_errors(outcome.errors());
|
||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
elna::boot::symbol_bag outcome_bag = elna::boot::symbol_bag{ std::move(outcome.unresolved), state.globals };
|
elna::frontend::symbol_bag outcome_bag = elna::frontend::symbol_bag{ std::move(outcome.unresolved), state.globals };
|
||||||
|
|
||||||
for (const auto& sub_tree : outcome.tree->imports)
|
for (const auto& sub_tree : outcome.tree->imports)
|
||||||
{
|
{
|
||||||
std::filesystem::path sub_path = "source" / elna::boot::build_path(sub_tree->segments);
|
std::filesystem::path sub_path = "source" / elna::frontend::build_path(sub_tree->segments);
|
||||||
std::unordered_map<std::filesystem::path, elna::boot::symbol_bag>::const_iterator cached_import =
|
std::unordered_map<std::filesystem::path, elna::frontend::symbol_bag>::const_iterator cached_import =
|
||||||
state.cache.find(sub_path);
|
state.cache.find(sub_path);
|
||||||
|
|
||||||
if (cached_import == state.cache.end())
|
if (cached_import == state.cache.end())
|
||||||
@@ -114,7 +114,7 @@ static void elna_langhook_parse_file(void)
|
|||||||
|
|
||||||
for (unsigned int i = 0; i < num_in_fnames; i++)
|
for (unsigned int i = 0; i < num_in_fnames; i++)
|
||||||
{
|
{
|
||||||
elna::boot::dependency outcome = elna_parse_file(state, in_fnames[i]);
|
elna::frontend::dependency outcome = elna_parse_file(state, in_fnames[i]);
|
||||||
|
|
||||||
linemap_add(line_table, LC_ENTER, 0, in_fnames[i], 1);
|
linemap_add(line_table, LC_ENTER, 0, in_fnames[i], 1);
|
||||||
elna::gcc::generic_visitor generic_visitor{ state.custom, state.cache.find(in_fnames[i])->second };
|
elna::gcc::generic_visitor generic_visitor{ state.custom, state.cache.find(in_fnames[i])->second };
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "elna/boot/symbol.h"
|
#include "elna/frontend/symbol.h"
|
||||||
#include "elna/boot/result.h"
|
#include "elna/frontend/result.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
enum class binary_operator
|
enum class binary_operator
|
||||||
{
|
{
|
||||||
@@ -19,11 +19,11 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "elna/boot/result.h"
|
#include "elna/frontend/result.h"
|
||||||
#include "elna/boot/ast.h"
|
#include "elna/frontend/ast.h"
|
||||||
#include "elna/boot/symbol.h"
|
#include "elna/frontend/symbol.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
class dependency : public error_container
|
class dependency : public error_container
|
||||||
{
|
{
|
||||||
@@ -48,7 +48,7 @@ namespace elna::boot
|
|||||||
std::unordered_map<std::filesystem::path, symbol_bag> cache;
|
std::unordered_map<std::filesystem::path, symbol_bag> cache;
|
||||||
|
|
||||||
explicit dependency_state(T custom)
|
explicit dependency_state(T custom)
|
||||||
: globals(elna::boot::builtin_symbol_table()), custom(custom)
|
: globals(builtin_symbol_table()), custom(custom)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -18,10 +18,10 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "elna/boot/ast.h"
|
#include "elna/frontend/ast.h"
|
||||||
#include "location.hh"
|
#include "location.hh"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
position make_position(const yy::location& location);
|
position make_position(const yy::location& location);
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Position in the source text.
|
* Position in the source text.
|
||||||
@@ -118,7 +118,7 @@ namespace elna::boot
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct std::hash<elna::boot::identifier_definition>
|
struct std::hash<elna::frontend::identifier_definition>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const elna::boot::identifier_definition& key) const noexcept;
|
std::size_t operator()(const elna::frontend::identifier_definition& key) const noexcept;
|
||||||
};
|
};
|
||||||
@@ -22,11 +22,11 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
#include "elna/boot/ast.h"
|
#include "elna/frontend/ast.h"
|
||||||
#include "elna/boot/result.h"
|
#include "elna/frontend/result.h"
|
||||||
#include "elna/boot/symbol.h"
|
#include "elna/frontend/symbol.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
class undeclared_error : public error
|
class undeclared_error : public error
|
||||||
{
|
{
|
||||||
@@ -24,9 +24,9 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
|
|
||||||
#include "elna/boot/result.h"
|
#include "elna/frontend/result.h"
|
||||||
|
|
||||||
namespace elna::boot
|
namespace elna::frontend
|
||||||
{
|
{
|
||||||
class alias_type;
|
class alias_type;
|
||||||
class primitive_type;
|
class primitive_type;
|
||||||
@@ -30,12 +30,12 @@ namespace elna::gcc
|
|||||||
void init_ttree();
|
void init_ttree();
|
||||||
std::shared_ptr<symbol_table> builtin_symbol_table();
|
std::shared_ptr<symbol_table> builtin_symbol_table();
|
||||||
|
|
||||||
void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols);
|
void rewrite_symbol_table(std::shared_ptr<frontend::symbol_table> info_table, std::shared_ptr<symbol_table> symbols);
|
||||||
tree handle_symbol(const std::string& symbol_name, std::shared_ptr<boot::alias_type> reference,
|
tree handle_symbol(const std::string& symbol_name, std::shared_ptr<frontend::alias_type> reference,
|
||||||
std::shared_ptr<symbol_table> symbols);
|
std::shared_ptr<symbol_table> symbols);
|
||||||
tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols);
|
tree get_inner_alias(const frontend::type& type, std::shared_ptr<symbol_table> symbols);
|
||||||
void declare_procedure(const std::string& name, const boot::procedure_info& info,
|
void declare_procedure(const std::string& name, const frontend::procedure_info& info,
|
||||||
std::shared_ptr<symbol_table> symbols);
|
std::shared_ptr<symbol_table> symbols);
|
||||||
tree declare_variable(const std::string& name, const boot::variable_info& info,
|
tree declare_variable(const std::string& name, const frontend::variable_info& info,
|
||||||
std::shared_ptr<symbol_table> symbols);
|
std::shared_ptr<symbol_table> symbols);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "elna/boot/result.h"
|
#include "elna/frontend/result.h"
|
||||||
|
|
||||||
namespace elna::gcc
|
namespace elna::gcc
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@ namespace elna::gcc
|
|||||||
~linemap_guard();
|
~linemap_guard();
|
||||||
};
|
};
|
||||||
|
|
||||||
location_t get_location(const boot::position *position);
|
location_t get_location(const frontend::position *position);
|
||||||
std::string print_type(tree type);
|
std::string print_type(tree type);
|
||||||
void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors);
|
void report_errors(const std::deque<std::unique_ptr<frontend::error>>& errors);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "elna/boot/ast.h"
|
#include "elna/frontend/ast.h"
|
||||||
#include "elna/boot/symbol.h"
|
#include "elna/frontend/symbol.h"
|
||||||
#include "elna/boot/semantic.h"
|
#include "elna/frontend/semantic.h"
|
||||||
#include "elna/gcc/elna-tree.h"
|
#include "elna/gcc/elna-tree.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -33,65 +33,65 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
|
|
||||||
namespace elna::gcc
|
namespace elna::gcc
|
||||||
{
|
{
|
||||||
class generic_visitor final : public boot::empty_visitor
|
class generic_visitor final : public frontend::empty_visitor
|
||||||
{
|
{
|
||||||
tree current_expression{ NULL_TREE };
|
tree current_expression{ NULL_TREE };
|
||||||
elna::boot::symbol_bag bag;
|
elna::frontend::symbol_bag bag;
|
||||||
std::shared_ptr<symbol_table> symbols;
|
std::shared_ptr<symbol_table> symbols;
|
||||||
|
|
||||||
void enter_scope();
|
void enter_scope();
|
||||||
tree leave_scope();
|
tree leave_scope();
|
||||||
|
|
||||||
void make_if_branch(boot::conditional_statements& branch, tree goto_endif);
|
void make_if_branch(frontend::conditional_statements& branch, tree goto_endif);
|
||||||
|
|
||||||
tree build_arithmetic_operation(boot::binary_expression *expression,
|
tree build_arithmetic_operation(frontend::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right);
|
tree_code operator_code, tree left, tree right);
|
||||||
tree build_comparison_operation(boot::binary_expression *expression,
|
tree build_comparison_operation(frontend::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right);
|
tree_code operator_code, tree left, tree right);
|
||||||
tree build_bit_logic_operation(boot::binary_expression *expression, tree left, tree right);
|
tree build_bit_logic_operation(frontend::binary_expression *expression, tree left, tree right);
|
||||||
tree build_equality_operation(boot::binary_expression *expression, tree left, tree right);
|
tree build_equality_operation(frontend::binary_expression *expression, tree left, tree right);
|
||||||
void build_procedure_call(location_t call_location,
|
void build_procedure_call(location_t call_location,
|
||||||
tree procedure_address, const std::vector<boot::expression *>& arguments);
|
tree procedure_address, const std::vector<frontend::expression *>& arguments);
|
||||||
void build_record_call(location_t call_location,
|
void build_record_call(location_t call_location,
|
||||||
tree symbol, const std::vector<boot::expression *>& arguments);
|
tree symbol, const std::vector<frontend::expression *>& arguments);
|
||||||
bool build_builtin_procedures(boot::procedure_call *call);
|
bool build_builtin_procedures(frontend::procedure_call *call);
|
||||||
void build_assert_builtin(location_t call_location, const std::vector<boot::expression *>& arguments);
|
void build_assert_builtin(location_t call_location, const std::vector<frontend::expression *>& arguments);
|
||||||
|
|
||||||
bool expect_trait_type_only(boot::traits_expression *trait);
|
bool expect_trait_type_only(frontend::traits_expression *trait);
|
||||||
bool expect_trait_for_integral_type(boot::traits_expression *trait);
|
bool expect_trait_for_integral_type(frontend::traits_expression *trait);
|
||||||
void visit_statements(const std::vector<boot::statement *>& statements);
|
void visit_statements(const std::vector<frontend::statement *>& statements);
|
||||||
bool assert_constant(location_t expression_location);
|
bool assert_constant(location_t expression_location);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
generic_visitor(std::shared_ptr<symbol_table> symbol_table, elna::boot::symbol_bag bag);
|
generic_visitor(std::shared_ptr<symbol_table> symbol_table, elna::frontend::symbol_bag bag);
|
||||||
|
|
||||||
void visit(boot::program *program) override;
|
void visit(frontend::program *program) override;
|
||||||
void visit(boot::procedure_declaration *definition) override;
|
void visit(frontend::procedure_declaration *definition) override;
|
||||||
void visit(boot::procedure_call *call) override;
|
void visit(frontend::procedure_call *call) override;
|
||||||
void visit(boot::cast_expression *expression) override;
|
void visit(frontend::cast_expression *expression) override;
|
||||||
void visit(boot::traits_expression *trait) override;
|
void visit(frontend::traits_expression *trait) override;
|
||||||
void visit(boot::literal<std::int32_t> *literal) override;
|
void visit(frontend::literal<std::int32_t> *literal) override;
|
||||||
void visit(boot::literal<std::uint32_t> *literal) override;
|
void visit(frontend::literal<std::uint32_t> *literal) override;
|
||||||
void visit(boot::literal<double> *literal) override;
|
void visit(frontend::literal<double> *literal) override;
|
||||||
void visit(boot::literal<bool> *boolean) override;
|
void visit(frontend::literal<bool> *boolean) override;
|
||||||
void visit(boot::literal<unsigned char> *character) override;
|
void visit(frontend::literal<unsigned char> *character) override;
|
||||||
void visit(boot::literal<std::nullptr_t> *) override;
|
void visit(frontend::literal<std::nullptr_t> *) override;
|
||||||
void visit(boot::literal<std::string> *string) override;
|
void visit(frontend::literal<std::string> *string) override;
|
||||||
void visit(boot::binary_expression *expression) override;
|
void visit(frontend::binary_expression *expression) override;
|
||||||
void visit(boot::unary_expression *expression) override;
|
void visit(frontend::unary_expression *expression) override;
|
||||||
void visit(boot::constant_declaration *definition) override;
|
void visit(frontend::constant_declaration *definition) override;
|
||||||
void visit(boot::variable_declaration *declaration) override;
|
void visit(frontend::variable_declaration *declaration) override;
|
||||||
void visit(boot::variable_expression *expression) override;
|
void visit(frontend::variable_expression *expression) override;
|
||||||
void visit(boot::array_access_expression *expression) override;
|
void visit(frontend::array_access_expression *expression) override;
|
||||||
void visit(boot::field_access_expression *expression) override;
|
void visit(frontend::field_access_expression *expression) override;
|
||||||
void visit(boot::dereference_expression *expression) override;
|
void visit(frontend::dereference_expression *expression) override;
|
||||||
void visit(boot::unit *unit) override;
|
void visit(frontend::unit *unit) override;
|
||||||
void visit(boot::assign_statement *statement) override;
|
void visit(frontend::assign_statement *statement) override;
|
||||||
void visit(boot::if_statement *statement) override;
|
void visit(frontend::if_statement *statement) override;
|
||||||
void visit(boot::import_declaration *) override;
|
void visit(frontend::import_declaration *) override;
|
||||||
void visit(boot::while_statement *statement) override;
|
void visit(frontend::while_statement *statement) override;
|
||||||
void visit(boot::return_statement *statement) override;
|
void visit(frontend::return_statement *statement) override;
|
||||||
void visit(boot::defer_statement *statement) override;
|
void visit(frontend::defer_statement *statement) override;
|
||||||
void visit(boot::case_statement *statement) override;
|
void visit(frontend::case_statement *statement) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include "stringpool.h"
|
#include "stringpool.h"
|
||||||
#include "fold-const.h"
|
#include "fold-const.h"
|
||||||
|
|
||||||
#include "elna/boot/ast.h"
|
#include "elna/frontend/ast.h"
|
||||||
#include "elna/boot/symbol.h"
|
#include "elna/frontend/symbol.h"
|
||||||
#include "elna/gcc/elna1.h"
|
#include "elna/gcc/elna1.h"
|
||||||
|
|
||||||
namespace elna::gcc
|
namespace elna::gcc
|
||||||
{
|
{
|
||||||
using symbol_table = boot::symbol_map<tree, tree, NULL_TREE>;
|
using symbol_table = frontend::symbol_map<tree, tree, NULL_TREE>;
|
||||||
|
|
||||||
bool is_integral_type(tree type);
|
bool is_integral_type(tree type);
|
||||||
bool is_numeric_type(tree type);
|
bool is_numeric_type(tree type);
|
||||||
@@ -74,11 +74,11 @@ namespace elna::gcc
|
|||||||
void defer(tree statement_tree);
|
void defer(tree statement_tree);
|
||||||
tree chain_defer();
|
tree chain_defer();
|
||||||
|
|
||||||
tree do_pointer_arithmetic(boot::binary_operator binary_operator,
|
tree do_pointer_arithmetic(frontend::binary_operator binary_operator,
|
||||||
tree left, tree right, location_t expression_location);
|
tree left, tree right, location_t expression_location);
|
||||||
tree build_binary_operation(bool condition, boot::binary_expression *expression,
|
tree build_binary_operation(bool condition, frontend::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right, tree target_type);
|
tree_code operator_code, tree left, tree right, tree target_type);
|
||||||
tree build_arithmetic_operation(boot::binary_expression *expression,
|
tree build_arithmetic_operation(frontend::binary_expression *expression,
|
||||||
tree_code operator_code, tree left, tree right);
|
tree_code operator_code, tree left, tree right);
|
||||||
tree build_field(location_t location, tree record_type, const std::string name, tree type);
|
tree build_field(location_t location, tree record_type, const std::string name, tree type);
|
||||||
tree find_field_by_name(location_t expression_location, tree type, const std::string& field_name);
|
tree find_field_by_name(location_t expression_location, tree type, const std::string& field_name);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ end
|
|||||||
|
|
||||||
namespace :boot do
|
namespace :boot do
|
||||||
# Dependencies.
|
# Dependencies.
|
||||||
GCC_VERSION = "15.1.0"
|
GCC_VERSION = "15.2.0"
|
||||||
HOST_GCC = TMP + 'host/gcc'
|
HOST_GCC = TMP + 'host/gcc'
|
||||||
GCC_PATCH = 'https://raw.githubusercontent.com/Homebrew/formula-patches/575ffcaed6d3112916fed77d271dd3799a7255c4/gcc/gcc-15.1.0.diff'
|
GCC_PATCH = 'https://raw.githubusercontent.com/Homebrew/formula-patches/575ffcaed6d3112916fed77d271dd3799a7255c4/gcc/gcc-15.1.0.diff'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user