diff --git a/README.md b/README.md
index a157d30..b2fdf0a 100644
--- a/README.md
+++ b/README.md
@@ -9,44 +9,3 @@ representation for a such high-level hypothetical programming language.
## File extension
.elna
-
-## Current implementation
-
-This repository contains a GCC frontend for Elna. After finishing the frontend
-I'm planning to rewrite the compiler in Elna itself with its own backend and
-a hand-written parser. So GCC gives a way to have a simple bootstrap compiler
-and a possbility to compile Elna programs for different platforms.
-
-## Grammar
-
-Flex and bison grammar specifications, `lexer.ll` and `parser.yy`, can be found
-in the `boot/` directory.
-
-## Build
-
-The frontend requires GCC 15.1.0 (not tested with other versions).
-
-Download the GCC source. Copy the contents of this repository into `gcc/elna`
-inside GCC. Finally build GCC enabling the frontend with
-`--enable-languages=c,c++,elna`. After the installation the compiler can be
-invoked with `$prefix/bin/gelna`.
-
-There is also a `Rakefile` that downloads, builds and installs GCC into the
-`./build/` subdirectory. The `Rakefile` assumes that ruby and rake, as well as
-all GCC dependencies are already available in the system. It works under Linux
-and Mac OS. In the latter case GCC is patched with the patches used by Homebrew
-(official GCC doesn't support Apple silicon targets). Invoke with
-
-```sh
-rake boot
-```
-
-`gcc` binary is used by default, but a different gcc version can be specified
-by passing `CC` and `CXX` environment variables to rake, e.g.:
-
-```sh
-rake CC=gcc-15 CXX=g++-15 boot
-```
-
-See `rake -T` for more tasks. The GCC source is under `build/tools`. The
-installation path is `build/host/install`.
diff --git a/Rakefile b/Rakefile
index 22fdddb..d8eebd7 100644
--- a/Rakefile
+++ b/Rakefile
@@ -2,42 +2,8 @@
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.
-require 'pathname'
require 'rake/clean'
-TMP = Pathname.new('./build')
-HOST_INSTALL = TMP + 'host/install'
+CLOBBER.include 'build'
-CLOBBER.include TMP
-CLEAN.include(TMP + 'boot')
-
-directory HOST_INSTALL
-
-task default: ['source/main.elna', TMP + 'boot/elna'] do |t|
- sources, compiler = t.prerequisites.partition { |f| f.end_with? '.elna' }
-
- sh *compiler, '--parse', *sources
-end
-
-rule(/boot\/.+\.o$/ => ->(file) {
- source = Pathname.new('source') +
- Pathname.new(file).relative_path_from(TMP + 'boot').sub_ext('.elna')
-
- [HOST_INSTALL + 'bin/gelna', source]
-}) do |t|
- Pathname.new(t.name).dirname.mkpath
- sources, compiler = t.prerequisites.partition { |source| source.end_with? '.elna' }
-
- sh *compiler, '-c', '-O0', '-g', '-o', t.name, *sources
-end
-
-file TMP + 'boot/elna' => FileList['source/**/*.elna'].reject { |file|
- file != file.downcase
-}.map { |file|
- TMP + 'boot' +
- Pathname.new(file).relative_path_from('source').sub_ext('.o')
-} do |t|
- compiler = HOST_INSTALL + 'bin/gcc'
-
- sh compiler.to_path, '-o', t.name, *t.prerequisites
-end
+task default: :source
diff --git a/boot/ast.cc b/frontend/ast.cc
similarity index 99%
rename from boot/ast.cc
rename to frontend/ast.cc
index becc164..e067937 100644
--- a/boot/ast.cc
+++ b/frontend/ast.cc
@@ -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
. */
-#include "elna/boot/ast.h"
+#include "elna/frontend/ast.h"
-namespace elna::boot
+namespace elna::frontend
{
void empty_visitor::not_implemented()
{
diff --git a/boot/dependency.cc b/frontend/dependency.cc
similarity index 95%
rename from boot/dependency.cc
rename to frontend/dependency.cc
index 6b10611..25658f8 100644
--- a/boot/dependency.cc
+++ b/frontend/dependency.cc
@@ -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
. */
-#include "elna/boot/dependency.h"
+#include "elna/frontend/dependency.h"
#include
#include
#include
-#include "elna/boot/driver.h"
-#include "elna/boot/semantic.h"
+#include "elna/frontend/driver.h"
+#include "elna/frontend/semantic.h"
#include "parser.hh"
-namespace elna::boot
+namespace elna::frontend
{
dependency::dependency(const char *path)
: error_container(path)
diff --git a/boot/driver.cc b/frontend/driver.cc
similarity index 98%
rename from boot/driver.cc
rename to frontend/driver.cc
index c9a8e58..1c20d09 100644
--- a/boot/driver.cc
+++ b/frontend/driver.cc
@@ -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
. */
-#include "elna/boot/driver.h"
+#include "elna/frontend/driver.h"
-namespace elna::boot
+namespace elna::frontend
{
position make_position(const yy::location& location)
{
diff --git a/boot/lexer.ll b/frontend/lexer.ll
similarity index 98%
rename from boot/lexer.ll
rename to frontend/lexer.ll
index bed3254..f14497b 100644
--- a/boot/lexer.ll
+++ b/frontend/lexer.ll
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "parser.hh"
#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)
%}
diff --git a/boot/parser.yy b/frontend/parser.yy
similarity index 55%
rename from boot/parser.yy
rename to frontend/parser.yy
index 07fb7a5..bace8d7 100644
--- a/boot/parser.yy
+++ b/frontend/parser.yy
@@ -25,25 +25,20 @@ along with GCC; see the file COPYING3. If not see
%code requires {
#include
#include
- #include "elna/boot/driver.h"
+ #include "elna/frontend/driver.h"
#if !defined(yyFlexLexerOnce)
#include
#endif
- namespace elna
- {
- namespace boot
+ namespace elna::frontend
{
class lexer;
}
- }
}
%code provides {
- namespace elna
- {
- namespace boot
+ namespace elna::frontend
{
class lexer: public yyFlexLexer
@@ -60,15 +55,14 @@ along with GCC; see the file COPYING3. If not see
};
}
- }
}
%define api.token.raw
%define api.token.constructor
%define api.value.type variant
-%parse-param {elna::boot::lexer& lexer}
-%param {elna::boot::driver& driver}
+%parse-param {elna::frontend::lexer& lexer}
+%param {elna::frontend::driver& driver}
%locations
%header
@@ -129,48 +123,48 @@ along with GCC; see the file COPYING3. If not see
%left "+" "-"
%left "*" "/" "%"
-%type literal;
-%type > case_labels;
-%type switch_case;
-%type > switch_cases;
-%type constant_declaration;
-%type > constant_part constant_declarations;
-%type variable_declaration;
-%type > variable_declarations variable_part;
-%type type_expression;
-%type > type_expressions;
-%type traits_expression;
-%type expression operand simple_expression;
-%type unary_expression;
-%type binary_expression;
-%type > expressions actual_parameter_list;
-%type designator_expression;
-%type call_expression;
-%type return_statement;
-%type statement;
-%type > required_statements optional_statements statement_part;
-%type procedure_declaration;
-%type , elna::boot::procedure_type_expression *>> procedure_heading;
-%type return_declaration;
-%type > procedure_declarations procedure_part;
-%type type_declaration;
-%type > type_declarations type_part;
-%type > block;
-%type field_declaration formal_parameter;
-%type >>
+%type literal;
+%type > case_labels;
+%type switch_case;
+%type > switch_cases;
+%type constant_declaration;
+%type > constant_part constant_declarations;
+%type variable_declaration;
+%type > variable_declarations variable_part;
+%type type_expression;
+%type > type_expressions;
+%type traits_expression;
+%type expression operand simple_expression;
+%type unary_expression;
+%type binary_expression;
+%type > expressions actual_parameter_list;
+%type designator_expression;
+%type call_expression;
+%type return_statement;
+%type statement;
+%type > required_statements optional_statements statement_part;
+%type procedure_declaration;
+%type , elna::frontend::procedure_type_expression *>> procedure_heading;
+%type return_declaration;
+%type > procedure_declarations procedure_part;
+%type type_declaration;
+%type > type_declarations type_part;
+%type > block;
+%type field_declaration formal_parameter;
+%type >>
optional_fields required_fields formal_parameters formal_parameter_list;
-%type > elsif_then_statements elsif_do_statements;
-%type *> else_statements;
-%type cast_expression;
-%type identifier_definition;
-%type > identifier_definitions;
+%type > elsif_then_statements elsif_do_statements;
+%type *> else_statements;
+%type cast_expression;
+%type identifier_definition;
+%type > identifier_definitions;
%type > identifiers import_declaration;
-%type > import_declarations import_part;
+%type > import_declarations import_part;
%%
program:
"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->constants, $4);
@@ -183,7 +177,7 @@ program:
}
| "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->constants, $4);
@@ -195,7 +189,7 @@ program:
}
block: constant_part variable_part statement_part "end"
{
- $$ = std::make_unique(std::move($1), std::move($2), std::move($3));
+ $$ = std::make_unique(std::move($1), std::move($2), std::move($3));
}
statement_part:
/* no statements */ {}
@@ -207,8 +201,8 @@ statement_part:
$$.push_back($4);
}
identifier_definition:
- IDENTIFIER "*" { $$ = boot::identifier_definition{ $1, true }; }
- | IDENTIFIER { $$ = boot::identifier_definition{ $1, false }; }
+ IDENTIFIER "*" { $$ = frontend::identifier_definition{ $1, true }; }
+ | IDENTIFIER { $$ = frontend::identifier_definition{ $1, false }; }
identifier_definitions:
identifier_definition "," identifier_definitions
{
@@ -218,11 +212,11 @@ identifier_definitions:
| identifier_definition { $$.emplace_back(std::move($1)); }
return_declaration:
/* proper procedure */ {}
- | "->" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); }
- | "->" type_expression { $$ = boot::procedure_type_expression::return_t($2); }
+ | "->" "!" { $$ = frontend::procedure_type_expression::return_t(std::monostate{}); }
+ | "->" type_expression { $$ = frontend::procedure_type_expression::return_t($2); }
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)
{
$$.first.emplace_back(std::move(name));
@@ -232,12 +226,12 @@ procedure_heading: formal_parameter_list return_declaration
procedure_declaration:
"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);
}
| "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);
}
procedure_declarations:
@@ -252,44 +246,44 @@ procedure_part:
| procedure_declarations { std::swap($$, $1); }
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);
}
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" 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, $$);
$$.emplace($$.begin(), branch);
}
| {}
else_statements:
- "else" optional_statements { $$ = new std::vector(std::move($2)); }
+ "else" optional_statements { $$ = new std::vector(std::move($2)); }
| { $$ = nullptr; }
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, $$);
$$.emplace($$.begin(), branch);
}
| {}
return_statement: "return" expression
- { $$ = new boot::return_statement(boot::make_position(@1), $2); }
+ { $$ = new frontend::return_statement(frontend::make_position(@1), $2); }
literal:
- INTEGER { $$ = new boot::literal(boot::make_position(@1), $1); }
- | WORD { $$ = new boot::literal(boot::make_position(@1), $1); }
- | FLOAT { $$ = new boot::literal(boot::make_position(@1), $1); }
- | BOOLEAN { $$ = new boot::literal(boot::make_position(@1), $1); }
- | CHARACTER { $$ = new boot::literal(boot::make_position(@1), $1.at(0)); }
- | "nil" { $$ = new boot::literal(boot::make_position(@1), nullptr); }
- | STRING { $$ = new boot::literal(boot::make_position(@1), $1); }
+ INTEGER { $$ = new frontend::literal(frontend::make_position(@1), $1); }
+ | WORD { $$ = new frontend::literal(frontend::make_position(@1), $1); }
+ | FLOAT { $$ = new frontend::literal(frontend::make_position(@1), $1); }
+ | BOOLEAN { $$ = new frontend::literal(frontend::make_position(@1), $1); }
+ | CHARACTER { $$ = new frontend::literal(frontend::make_position(@1), $1.at(0)); }
+ | "nil" { $$ = new frontend::literal(frontend::make_position(@1), nullptr); }
+ | STRING { $$ = new frontend::literal(frontend::make_position(@1), $1); }
traits_expression:
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);
}
simple_expression:
@@ -308,82 +302,82 @@ expression:
binary_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
{
- $$ = 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
{
- $$ = 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
{
- $$ = 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
{
- $$ = 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
{
- $$ = 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
{
- $$ = 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
{
- $$ = 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
{
- $$ = 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
{
- $$ = new boot::binary_expression(boot::make_position(@2), $1, $3,
- boot::binary_operator::less_equal);
+ $$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3,
+ frontend::binary_operator::less_equal);
}
| 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
{
- $$ = 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
{
- $$ = 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
{
- $$ = new boot::binary_expression(boot::make_position(@2), $1, $3,
- boot::binary_operator::exclusive_disjunction);
+ $$ = new frontend::binary_expression(frontend::make_position(@2), $1, $3,
+ frontend::binary_operator::exclusive_disjunction);
}
| 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
{
- $$ = 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:
"@" 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
{
- $$ = 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
{
- $$ = 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:
expression "," expressions
@@ -401,31 +395,31 @@ type_expressions:
| type_expression { $$.push_back($1); }
designator_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
- { $$ = new boot::field_access_expression(boot::make_position(@2), $1, $3); }
+ { $$ = new frontend::field_access_expression(frontend::make_position(@2), $1, $3); }
| simple_expression "^"
- { $$ = new boot::dereference_expression(boot::make_position(@1), $1); }
+ { $$ = new frontend::dereference_expression(frontend::make_position(@1), $1); }
| IDENTIFIER
- { $$ = new boot::variable_expression(boot::make_position(@1), $1); }
+ { $$ = new frontend::variable_expression(frontend::make_position(@1), $1); }
statement:
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"
{
- boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4));
- $$ = new boot::while_statement(boot::make_position(@1), body, std::move($5));
+ frontend::conditional_statements *body = new frontend::conditional_statements($2, std::move($4));
+ $$ = new frontend::while_statement(frontend::make_position(@1), body, std::move($5));
}
| "if" expression "then" optional_statements elsif_then_statements else_statements "end"
{
- boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4));
- $$ = new boot::if_statement(boot::make_position(@1), then, std::move($5), $6);
+ frontend::conditional_statements *then = new frontend::conditional_statements($2, std::move($4));
+ $$ = new frontend::if_statement(frontend::make_position(@1), then, std::move($5), $6);
}
| call_expression { $$ = $1; }
| "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"
- { $$ = 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
{ $$ = { .labels = std::move($1), .statements = std::move($3) }; }
switch_cases:
@@ -467,33 +461,33 @@ optional_fields:
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
{
- $$ = new boot::pointer_type_expression(boot::make_position(@1), $2);
+ $$ = new frontend::pointer_type_expression(frontend::make_position(@1), $2);
}
| "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"
{
- $$ = 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
{
- 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);
$$ = result;
}
| "(" 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
{
- $$ = new boot::named_type_expression(boot::make_position(@1), $1);
+ $$ = new frontend::named_type_expression(frontend::make_position(@1), $1);
}
identifiers:
IDENTIFIER "," identifiers
@@ -505,19 +499,19 @@ identifiers:
variable_declaration:
identifier_definitions ":" type_expression ";"
{
- std::shared_ptr shared_type{ $3 };
- $$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type);
+ std::shared_ptr shared_type{ $3 };
+ $$ = new frontend::variable_declaration( frontend::make_position(@2), std::move($1), shared_type);
}
| identifier_definitions ":" type_expression ":=" "extern" ";"
{
- std::shared_ptr shared_type{ $3 };
- $$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type,
+ std::shared_ptr shared_type{ $3 };
+ $$ = new frontend::variable_declaration( frontend::make_position(@2), std::move($1), shared_type,
std::monostate{});
}
| identifier_definitions ":" type_expression ":=" expression ";"
{
- std::shared_ptr shared_type{ $3 };
- $$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type, $5);
+ std::shared_ptr shared_type{ $3 };
+ $$ = new frontend::variable_declaration( frontend::make_position(@2), std::move($1), shared_type, $5);
}
variable_declarations:
/* no variable declarations */ {}
@@ -531,7 +525,7 @@ variable_part:
| "var" variable_declarations { std::swap($$, $2); }
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_declaration constant_declarations
@@ -554,18 +548,18 @@ import_declarations:
import_declaration "," import_declarations
{
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
{
- $$.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:
/* no import declarations */ {}
| "import" import_declarations ";" { std::swap($$, $2); }
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_declaration type_declarations
@@ -596,5 +590,5 @@ actual_parameter_list:
void yy::parser::error(const location_type& loc, const std::string& message)
{
- driver.add_error(message, driver.input_file, loc);
+ driver.add_error(message, driver.input_file, loc);
}
diff --git a/boot/result.cc b/frontend/result.cc
similarity index 89%
rename from boot/result.cc
rename to frontend/result.cc
index dab82f4..aca9c5e 100644
--- a/boot/result.cc
+++ b/frontend/result.cc
@@ -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
. */
-#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)
: position(position), path(path)
@@ -60,8 +60,8 @@ namespace elna::boot
}
}
-std::size_t std::hash::operator()(
- const elna::boot::identifier_definition& key) const
+std::size_t std::hash::operator()(
+ const elna::frontend::identifier_definition& key) const
{
return std::hash{}(key.name);
}
diff --git a/boot/semantic.cc b/frontend/semantic.cc
similarity index 99%
rename from boot/semantic.cc
rename to frontend/semantic.cc
index b343f56..36c75b8 100644
--- a/boot/semantic.cc
+++ b/frontend/semantic.cc
@@ -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
. */
-#include "elna/boot/semantic.h"
+#include "elna/frontend/semantic.h"
#include
#include
-namespace elna::boot
+namespace elna::frontend
{
undeclared_error::undeclared_error(const std::string& identifier, const char *path, const struct position position)
: error(path, position), identifier(identifier)
@@ -636,7 +636,7 @@ namespace elna::boot
{
return;
}
- for (boot::variable_declaration *const variable : definition->body.value().variables())
+ for (variable_declaration *const variable : definition->body.value().variables())
{
variable->accept(this);
}
diff --git a/boot/symbol.cc b/frontend/symbol.cc
similarity index 99%
rename from boot/symbol.cc
rename to frontend/symbol.cc
index 902d331..bfecbd4 100644
--- a/boot/symbol.cc
+++ b/frontend/symbol.cc
@@ -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
. */
-#include "elna/boot/symbol.h"
+#include "elna/frontend/symbol.h"
-namespace elna::boot
+namespace elna::frontend
{
type::type()
{
diff --git a/gcc/Make-lang.in b/gcc/Make-lang.in
index efc7687..e25fc6d 100644
--- a/gcc/Make-lang.in
+++ b/gcc/Make-lang.in
@@ -150,7 +150,7 @@ elna.stagefeedback: stagefeedback-start
ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated
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) $<
$(POSTCOMPILE)
@@ -162,13 +162,13 @@ elna/%.o: elna/gcc/%.cc elna/generated/parser.hh elna/generated/location.hh
$(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $<
$(POSTCOMPILE)
-elna/generated/parser.cc: elna/boot/parser.yy
+elna/generated/parser.cc: elna/frontend/parser.yy
mkdir -p $(dir $@)
$(BISON) -d -o $@ $<
elna/generated/parser.hh elna/generated/location.hh: elna/generated/parser.cc
@touch $@
-elna/generated/lexer.cc: elna/boot/lexer.ll
+elna/generated/lexer.cc: elna/frontend/lexer.ll
mkdir -p $(dir $@)
$(FLEX) -o $@ $<
diff --git a/gcc/README.md b/gcc/README.md
new file mode 100644
index 0000000..99d03c3
--- /dev/null
+++ b/gcc/README.md
@@ -0,0 +1,42 @@
+# Elna programming language
+
+## Current implementation
+
+This repository contains a GCC frontend for Elna. After finishing the frontend
+I'm planning to rewrite the compiler in Elna itself with its own backend and
+a hand-written parser. So GCC gives a way to have a simple bootstrap compiler
+and a possbility to compile Elna programs for different platforms.
+
+## Grammar
+
+Flex and bison grammar specifications, `lexer.ll` and `parser.yy`, can be found
+in the `boot/` directory.
+
+## Build
+
+The frontend requires GCC 15.2.0 (not tested with other versions).
+
+Download the GCC source. Copy the contents of this repository into `gcc/elna`
+inside GCC. Finally build GCC enabling the frontend with
+`--enable-languages=c,c++,elna`. After the installation the compiler can be
+invoked with `$prefix/bin/gelna`.
+
+There is also a `Rakefile` that downloads, builds and installs GCC into the
+`./build/` subdirectory. The `Rakefile` assumes that ruby and rake, as well as
+all GCC dependencies are already available in the system. It works under Linux
+and Mac OS. In the latter case GCC is patched with the patches used by Homebrew
+(official GCC doesn't support Apple silicon targets). Invoke with
+
+```sh
+rake boot
+```
+
+`gcc` binary is used by default, but a different gcc version can be specified
+by passing `CC` and `CXX` environment variables to rake, e.g.:
+
+```sh
+rake CC=gcc-15 CXX=g++-15 boot
+```
+
+See `rake -T` for more tasks. The GCC source is under `build/tools`. The
+installation path is `build/host/install`.
diff --git a/gcc/elna-builtins.cc b/gcc/elna-builtins.cc
index 61a24c4..cf06df8 100644
--- a/gcc/elna-builtins.cc
+++ b/gcc/elna-builtins.cc
@@ -80,7 +80,7 @@ namespace elna::gcc
return symbol_table;
}
- tree build_composite_type(const std::vector& fields, tree composite_type_node,
+ tree build_composite_type(const std::vector& fields, tree composite_type_node,
std::shared_ptr symbols)
{
for (auto& field : fields)
@@ -94,7 +94,7 @@ namespace elna::gcc
return composite_type_node;
}
- tree build_procedure_type(const boot::procedure_type& procedure, std::shared_ptr symbols)
+ tree build_procedure_type(const frontend::procedure_type& procedure, std::shared_ptr symbols)
{
std::vector 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());
}
- tree get_inner_alias(const boot::type& type, std::shared_ptr symbols)
+ tree get_inner_alias(const frontend::type& type, std::shared_ptr symbols)
{
- if (auto reference = type.get())
+ if (auto reference = type.get())
{
auto looked_up = symbols->lookup(reference->identifier);
gcc_assert(looked_up != NULL_TREE);
return TREE_TYPE(looked_up);
}
- else if (auto reference = type.get())
+ else if (auto reference = type.get())
{
tree composite_type_node = make_node(RECORD_TYPE);
@@ -128,7 +128,7 @@ namespace elna::gcc
return composite_type_node;
}
- else if (auto reference = type.get())
+ else if (auto reference = type.get())
{
tree composite_type_node = make_node(UNION_TYPE);
@@ -136,34 +136,34 @@ namespace elna::gcc
return composite_type_node;
}
- else if (auto reference = type.get())
+ else if (auto reference = type.get())
{
return build_enumeration_type(reference->members);
}
- else if (auto reference = type.get())
+ else if (auto reference = type.get())
{
return build_global_pointer_type(get_inner_alias(reference->base, symbols));
}
- else if (auto reference = type.get())
+ else if (auto reference = type.get())
{
tree base = get_inner_alias(reference->base, symbols);
return build_static_array_type(base, reference->size);
}
- else if (auto reference = type.get())
+ else if (auto reference = type.get())
{
auto procedure = build_procedure_type(*reference, symbols);
return build_global_pointer_type(procedure);
}
- else if (auto reference = type.get())
+ else if (auto reference = type.get())
{
return TREE_TYPE(handle_symbol(reference->name, reference, symbols));
}
return error_mark_node;
}
- tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference,
+ tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference,
std::shared_ptr symbols)
{
tree looked_up = symbols->lookup(symbol_name);
@@ -189,7 +189,7 @@ namespace elna::gcc
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 symbols)
{
tree declaration_type = gcc::build_procedure_type(info.symbol, symbols);
@@ -210,7 +210,7 @@ namespace elna::gcc
std::vector::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,
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 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 symbols)
{
auto variable_type = get_inner_alias(info.symbol, symbols);
@@ -242,10 +242,10 @@ namespace elna::gcc
return declaration_tree;
}
- void declare_type(const std::string& name, const boot::type_info& info, std::shared_ptr symbols)
+ void declare_type(const std::string& name, const frontend::type_info& info, std::shared_ptr symbols)
{
// The top level symbol table has basic (builtin) types in it which are not aliases.
- if (auto alias_type = info.symbol.get())
+ if (auto alias_type = info.symbol.get())
{
tree type_declaration = handle_symbol(name, alias_type, symbols);
@@ -253,7 +253,7 @@ namespace elna::gcc
}
}
- void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols)
+ void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols)
{
for (auto& [symbol_name, symbol_info] : *info_table)
{
diff --git a/gcc/elna-diagnostic.cc b/gcc/elna-diagnostic.cc
index 3e6e4c3..162d6cb 100644
--- a/gcc/elna-diagnostic.cc
+++ b/gcc/elna-diagnostic.cc
@@ -31,7 +31,7 @@ namespace elna::gcc
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);
@@ -151,7 +151,7 @@ namespace elna::gcc
gcc_unreachable();
}
- void report_errors(const std::deque>& errors)
+ void report_errors(const std::deque>& errors)
{
for (const auto& error : errors)
{
diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc
index 0f0e2ef..b37b111 100644
--- a/gcc/elna-generic.cc
+++ b/gcc/elna-generic.cc
@@ -35,13 +35,13 @@ along with GCC; see the file COPYING3. If not see
namespace elna::gcc
{
- generic_visitor::generic_visitor(std::shared_ptr symbol_table, elna::boot::symbol_bag bag)
+ generic_visitor::generic_visitor(std::shared_ptr symbol_table, elna::frontend::symbol_bag bag)
: bag(bag), symbols(symbol_table)
{
}
void generic_visitor::build_procedure_call(location_t call_location,
- tree procedure_address, const std::vector& arguments)
+ tree procedure_address, const std::vector& arguments)
{
vec *argument_trees = nullptr;
tree symbol_type = TREE_TYPE(TREE_TYPE(procedure_address));
@@ -49,7 +49,7 @@ namespace elna::gcc
tree current_parameter = TYPE_ARG_TYPES(symbol_type);
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());
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,
- tree symbol, const std::vector& arguments)
+ tree symbol, const std::vector& arguments)
{
vec *tree_arguments = nullptr;
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());
@@ -129,7 +129,7 @@ namespace elna::gcc
}
void generic_visitor::build_assert_builtin(location_t call_location,
- const std::vector& arguments)
+ const std::vector& arguments)
{
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());
- 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")
{
@@ -180,7 +180,7 @@ namespace elna::gcc
return false;
}
- void generic_visitor::visit(boot::procedure_call *call)
+ void generic_visitor::visit(frontend::procedure_call *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());
@@ -235,9 +235,9 @@ namespace elna::gcc
}
}
- void generic_visitor::visit(boot::program *program)
+ void generic_visitor::visit(frontend::program *program)
{
- visit(static_cast(program));
+ visit(static_cast(program));
tree declaration_type = build_function_type_list(elna_int_type_node,
elna_int_type_node,
@@ -285,27 +285,27 @@ namespace elna::gcc
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);
}
- for (boot::constant_declaration *const constant : unit->constants)
+ for (frontend::constant_declaration *const constant : unit->constants)
{
constant->accept(this);
}
- for (boot::variable_declaration *const variable : unit->variables)
+ for (frontend::variable_declaration *const variable : unit->variables)
{
variable->accept(this);
}
- for (boot::procedure_declaration *const procedure : unit->procedures)
+ for (frontend::procedure_declaration *const procedure : unit->procedures)
{
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);
@@ -324,11 +324,11 @@ namespace elna::gcc
{
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);
}
- for (boot::variable_declaration *const variable : definition->body.value().variables())
+ for (frontend::variable_declaration *const variable : definition->body.value().variables())
{
variable->accept(this);
}
@@ -381,17 +381,17 @@ namespace elna::gcc
return bind_expr;
}
- void generic_visitor::visit(boot::literal *literal)
+ void generic_visitor::visit(frontend::literal *literal)
{
this->current_expression = build_int_cst(elna_int_type_node, literal->value);
}
- void generic_visitor::visit(boot::literal *literal)
+ void generic_visitor::visit(frontend::literal *literal)
{
this->current_expression = build_int_cstu(elna_word_type_node, literal->value);
}
- void generic_visitor::visit(boot::literal *literal)
+ void generic_visitor::visit(frontend::literal *literal)
{
REAL_VALUE_TYPE real_value1;
@@ -406,22 +406,22 @@ namespace elna::gcc
mpfr_clear(number);
}
- void generic_visitor::visit(boot::literal *boolean)
+ void generic_visitor::visit(frontend::literal *boolean)
{
this->current_expression = boolean->value ? boolean_true_node : boolean_false_node;
}
- void generic_visitor::visit(boot::literal *character)
+ void generic_visitor::visit(frontend::literal *character)
{
this->current_expression = build_int_cstu(elna_char_type_node, character->value);
}
- void generic_visitor::visit(boot::literal *)
+ void generic_visitor::visit(frontend::literal *)
{
this->current_expression = elna_pointer_nil_node;
}
- void generic_visitor::visit(boot::literal *string)
+ void generic_visitor::visit(frontend::literal *string)
{
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));
@@ -444,38 +444,38 @@ namespace elna::gcc
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)
{
return build_binary_operation(is_numeric_type(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)
{
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);
}
- 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());
tree left_type = TREE_TYPE(left);
tree right_type = TREE_TYPE(right);
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;
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;
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;
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",
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;
}
}
- 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());
tree_code equality_code, combination_code;
- if (expression->operation() == boot::binary_operator::equals)
+ if (expression->operation() == frontend::binary_operator::equals)
{
equality_code = EQ_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;
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);
tree left = this->current_expression;
@@ -558,8 +558,8 @@ namespace elna::gcc
location_t expression_location = get_location(&expression->position());
if ((POINTER_TYPE_P(left_type) || POINTER_TYPE_P(right_type))
- && (expression->operation() == boot::binary_operator::sum
- || expression->operation() == boot::binary_operator::subtraction))
+ && (expression->operation() == frontend::binary_operator::sum
+ || expression->operation() == frontend::binary_operator::subtraction))
{
this->current_expression = do_pointer_arithmetic(expression->operation(),
left, right, expression_location);
@@ -567,7 +567,7 @@ namespace elna::gcc
{
error_at(expression_location,
"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)
{
@@ -583,60 +583,60 @@ namespace elna::gcc
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(),
- boot::print_binary_operator(expression->operation()));
+ frontend::print_binary_operator(expression->operation()));
this->current_expression = error_mark_node;
return;
}
switch (expression->operation())
{
- case boot::binary_operator::sum:
+ case frontend::binary_operator::sum:
this->current_expression = build_arithmetic_operation(expression, PLUS_EXPR, left, right);
break;
- case boot::binary_operator::subtraction:
+ case frontend::binary_operator::subtraction:
this->current_expression = build_arithmetic_operation(expression, MINUS_EXPR, left, right);
break;
- case boot::binary_operator::division:
+ case frontend::binary_operator::division:
this->current_expression = build_arithmetic_operation(expression, TRUNC_DIV_EXPR, left, right);
break;
- case boot::binary_operator::remainder:
+ case frontend::binary_operator::remainder:
this->current_expression = build_arithmetic_operation(expression, TRUNC_MOD_EXPR, left, right);
break;
- case boot::binary_operator::multiplication:
+ case frontend::binary_operator::multiplication:
this->current_expression = build_arithmetic_operation(expression, MULT_EXPR, left, right);
break;
- case boot::binary_operator::less:
+ case frontend::binary_operator::less:
this->current_expression = build_comparison_operation(expression, LT_EXPR, left, right);
break;
- case boot::binary_operator::greater:
+ case frontend::binary_operator::greater:
this->current_expression = build_comparison_operation(expression, GT_EXPR, left, right);
break;
- case boot::binary_operator::less_equal:
+ case frontend::binary_operator::less_equal:
this->current_expression = build_comparison_operation(expression, LE_EXPR, left, right);
break;
- case boot::binary_operator::greater_equal:
+ case frontend::binary_operator::greater_equal:
this->current_expression = build_comparison_operation(expression, GE_EXPR, left, right);
break;
- case boot::binary_operator::conjunction:
+ case frontend::binary_operator::conjunction:
this->current_expression = build_bit_logic_operation(expression, left, right);
break;
- case boot::binary_operator::disjunction:
+ case frontend::binary_operator::disjunction:
this->current_expression = build_bit_logic_operation(expression, left, right);
break;
- case boot::binary_operator::exclusive_disjunction:
+ case frontend::binary_operator::exclusive_disjunction:
this->current_expression = build_bit_logic_operation(expression, left, right);
break;
- case boot::binary_operator::equals:
+ case frontend::binary_operator::equals:
this->current_expression = build_equality_operation(expression, left, right);
break;
- case boot::binary_operator::not_equals:
+ case frontend::binary_operator::not_equals:
this->current_expression = build_equality_operation(expression, left, right);
break;
- case boot::binary_operator::shift_left:
+ case frontend::binary_operator::shift_left:
this->current_expression = build_binary_operation(
is_numeric_type(left_type) && right_type == elna_word_type_node,
expression, LSHIFT_EXPR, left, right, left_type);
break;
- case boot::binary_operator::shift_right:
+ case frontend::binary_operator::shift_right:
this->current_expression = build_binary_operation(
is_numeric_type(left_type) && right_type == elna_word_type_node,
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);
location_t location = get_location(&expression->position());
switch (expression->operation())
{
- case boot::unary_operator::reference:
+ case frontend::unary_operator::reference:
this->current_expression = prepare_rvalue(this->current_expression);
TREE_ADDRESSABLE(this->current_expression) = 1;
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)));
TREE_NO_TRAMPOLINE(this->current_expression) = 1;
break;
- case boot::unary_operator::negation:
+ case frontend::unary_operator::negation:
if (TREE_TYPE(this->current_expression) == elna_bool_type_node)
{
this->current_expression = build1_loc(location, TRUTH_NOT_EXPR,
@@ -677,7 +677,7 @@ namespace elna::gcc
this->current_expression = error_mark_node;
}
break;
- case boot::unary_operator::minus:
+ case frontend::unary_operator::minus:
if (is_integral_type(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());
definition->body().accept(this);
@@ -732,7 +732,7 @@ namespace elna::gcc
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)
{
@@ -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);
@@ -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);
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),
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,
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)
{
@@ -856,7 +856,7 @@ namespace elna::gcc
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))
{
@@ -872,7 +872,7 @@ namespace elna::gcc
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());
@@ -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);
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);
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);
@@ -1045,7 +1045,7 @@ namespace elna::gcc
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 goto_endif = build1(GOTO_EXPR, void_type_node, endif_label_decl);
@@ -1068,7 +1068,7 @@ namespace elna::gcc
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);
@@ -1102,11 +1102,11 @@ namespace elna::gcc
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());
tree prerequisite_label_decl = build_label_decl("while_do", prerequisite_location);
@@ -1127,9 +1127,9 @@ namespace elna::gcc
this->current_expression = NULL_TREE;
}
- void generic_visitor::visit_statements(const std::vector& statements)
+ void generic_visitor::visit_statements(const std::vector& statements)
{
- for (boot::statement *const statement : statements)
+ for (frontend::statement *const statement : statements)
{
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());
tree set_result{ NULL_TREE };
tree return_type = TREE_TYPE(TREE_TYPE(current_function_decl));
@@ -1183,14 +1183,14 @@ namespace elna::gcc
this->current_expression = NULL_TREE;
}
- void generic_visitor::visit(boot::defer_statement *statement)
+ void generic_visitor::visit(frontend::defer_statement *statement)
{
enter_scope();
visit_statements(statement->statements);
defer(leave_scope());
}
- void generic_visitor::visit(boot::case_statement *statement)
+ void generic_visitor::visit(frontend::case_statement *statement)
{
statement->condition().accept(this);
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 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);
location_t case_location = get_location(&case_label->position());
diff --git a/gcc/elna-tree.cc b/gcc/elna-tree.cc
index 7860d75..93f796b 100644
--- a/gcc/elna-tree.cc
+++ b/gcc/elna-tree.cc
@@ -128,12 +128,12 @@ namespace elna::gcc
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_type = get_qualified_type(TREE_TYPE(left), 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 offset{ NULL_TREE };
@@ -164,7 +164,7 @@ namespace elna::gcc
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))
{
@@ -186,7 +186,7 @@ namespace elna::gcc
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)
{
location_t expression_location = get_location(&expression->position());
@@ -202,7 +202,7 @@ namespace elna::gcc
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(),
- elna::boot::print_binary_operator(expression->operation()));
+ elna::frontend::print_binary_operator(expression->operation()));
return error_mark_node;
}
}
diff --git a/gcc/elna1.cc b/gcc/elna1.cc
index 0333f70..448a24c 100644
--- a/gcc/elna1.cc
+++ b/gcc/elna1.cc
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks-def.h"
#include
-#include "elna/boot/dependency.h"
+#include "elna/frontend/dependency.h"
#include "elna/gcc/elna-tree.h"
#include "elna/gcc/elna-generic.h"
#include "elna/gcc/elna-diagnostic.h"
@@ -62,9 +62,9 @@ static bool elna_langhook_init(void)
return true;
}
-using dependency_state = elna::boot::dependency_state>;
+using dependency_state = elna::frontend::dependency_state>;
-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 };
@@ -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);
}
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())
{
elna::gcc::report_errors(outcome.errors());
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)
{
- std::filesystem::path sub_path = "source" / elna::boot::build_path(sub_tree->segments);
- std::unordered_map::const_iterator cached_import =
+ std::filesystem::path sub_path = "source" / elna::frontend::build_path(sub_tree->segments);
+ std::unordered_map::const_iterator cached_import =
state.cache.find(sub_path);
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++)
{
- 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);
elna::gcc::generic_visitor generic_visitor{ state.custom, state.cache.find(in_fnames[i])->second };
diff --git a/include/elna/boot/ast.h b/include/elna/frontend/ast.h
similarity index 99%
rename from include/elna/boot/ast.h
rename to include/elna/frontend/ast.h
index f67575a..bbb8a36 100644
--- a/include/elna/boot/ast.h
+++ b/include/elna/frontend/ast.h
@@ -22,10 +22,10 @@ along with GCC; see the file COPYING3. If not see
#include
#include
#include
-#include "elna/boot/symbol.h"
-#include "elna/boot/result.h"
+#include "elna/frontend/symbol.h"
+#include "elna/frontend/result.h"
-namespace elna::boot
+namespace elna::frontend
{
enum class binary_operator
{
diff --git a/include/elna/boot/dependency.h b/include/elna/frontend/dependency.h
similarity index 88%
rename from include/elna/boot/dependency.h
rename to include/elna/frontend/dependency.h
index c8f2e5b..f1502d1 100644
--- a/include/elna/boot/dependency.h
+++ b/include/elna/frontend/dependency.h
@@ -19,11 +19,11 @@ along with GCC; see the file COPYING3. If not see
#include
#include
-#include "elna/boot/result.h"
-#include "elna/boot/ast.h"
-#include "elna/boot/symbol.h"
+#include "elna/frontend/result.h"
+#include "elna/frontend/ast.h"
+#include "elna/frontend/symbol.h"
-namespace elna::boot
+namespace elna::frontend
{
class dependency : public error_container
{
@@ -48,7 +48,7 @@ namespace elna::boot
std::unordered_map cache;
explicit dependency_state(T custom)
- : globals(elna::boot::builtin_symbol_table()), custom(custom)
+ : globals(builtin_symbol_table()), custom(custom)
{
}
};
diff --git a/include/elna/boot/driver.h b/include/elna/frontend/driver.h
similarity index 96%
rename from include/elna/boot/driver.h
rename to include/elna/frontend/driver.h
index 288aa0c..66ef579 100644
--- a/include/elna/boot/driver.h
+++ b/include/elna/frontend/driver.h
@@ -18,10 +18,10 @@ along with GCC; see the file COPYING3. If not see
#pragma once
#include
-#include "elna/boot/ast.h"
+#include "elna/frontend/ast.h"
#include "location.hh"
-namespace elna::boot
+namespace elna::frontend
{
position make_position(const yy::location& location);
diff --git a/include/elna/boot/result.h b/include/elna/frontend/result.h
similarity index 94%
rename from include/elna/boot/result.h
rename to include/elna/frontend/result.h
index 9fc1849..7e5ed77 100644
--- a/include/elna/boot/result.h
+++ b/include/elna/frontend/result.h
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include
#include
-namespace elna::boot
+namespace elna::frontend
{
/**
* Position in the source text.
@@ -118,7 +118,7 @@ namespace elna::boot
}
template<>
-struct std::hash
+struct std::hash
{
- std::size_t operator()(const elna::boot::identifier_definition& key) const noexcept;
+ std::size_t operator()(const elna::frontend::identifier_definition& key) const noexcept;
};
diff --git a/include/elna/boot/semantic.h b/include/elna/frontend/semantic.h
similarity index 98%
rename from include/elna/boot/semantic.h
rename to include/elna/frontend/semantic.h
index c2a485f..8a295e4 100644
--- a/include/elna/boot/semantic.h
+++ b/include/elna/frontend/semantic.h
@@ -22,11 +22,11 @@ along with GCC; see the file COPYING3. If not see
#include
#include
-#include "elna/boot/ast.h"
-#include "elna/boot/result.h"
-#include "elna/boot/symbol.h"
+#include "elna/frontend/ast.h"
+#include "elna/frontend/result.h"
+#include "elna/frontend/symbol.h"
-namespace elna::boot
+namespace elna::frontend
{
class undeclared_error : public error
{
diff --git a/include/elna/boot/symbol.h b/include/elna/frontend/symbol.h
similarity index 99%
rename from include/elna/boot/symbol.h
rename to include/elna/frontend/symbol.h
index 5ef917e..ec912ef 100644
--- a/include/elna/boot/symbol.h
+++ b/include/elna/frontend/symbol.h
@@ -24,9 +24,9 @@ along with GCC; see the file COPYING3. If not see
#include
#include
-#include "elna/boot/result.h"
+#include "elna/frontend/result.h"
-namespace elna::boot
+namespace elna::frontend
{
class alias_type;
class primitive_type;
diff --git a/include/elna/gcc/elna-builtins.h b/include/elna/gcc/elna-builtins.h
index 0cdf519..60baab7 100644
--- a/include/elna/gcc/elna-builtins.h
+++ b/include/elna/gcc/elna-builtins.h
@@ -30,12 +30,12 @@ namespace elna::gcc
void init_ttree();
std::shared_ptr builtin_symbol_table();
- void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols);
- tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference,
+ void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols);
+ tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference,
std::shared_ptr symbols);
- tree get_inner_alias(const boot::type& type, std::shared_ptr symbols);
- void declare_procedure(const std::string& name, const boot::procedure_info& info,
+ tree get_inner_alias(const frontend::type& type, std::shared_ptr symbols);
+ void declare_procedure(const std::string& name, const frontend::procedure_info& info,
std::shared_ptr 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 symbols);
}
diff --git a/include/elna/gcc/elna-diagnostic.h b/include/elna/gcc/elna-diagnostic.h
index 1eef65d..83f768e 100644
--- a/include/elna/gcc/elna-diagnostic.h
+++ b/include/elna/gcc/elna-diagnostic.h
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include
#include
-#include "elna/boot/result.h"
+#include "elna/frontend/result.h"
namespace elna::gcc
{
@@ -40,7 +40,7 @@ namespace elna::gcc
~linemap_guard();
};
- location_t get_location(const boot::position *position);
+ location_t get_location(const frontend::position *position);
std::string print_type(tree type);
- void report_errors(const std::deque>& errors);
+ void report_errors(const std::deque>& errors);
}
diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h
index e8ab874..97cd512 100644
--- a/include/elna/gcc/elna-generic.h
+++ b/include/elna/gcc/elna-generic.h
@@ -17,9 +17,9 @@ along with GCC; see the file COPYING3. If not see
#pragma once
-#include "elna/boot/ast.h"
-#include "elna/boot/symbol.h"
-#include "elna/boot/semantic.h"
+#include "elna/frontend/ast.h"
+#include "elna/frontend/symbol.h"
+#include "elna/frontend/semantic.h"
#include "elna/gcc/elna-tree.h"
#include "config.h"
@@ -33,65 +33,65 @@ along with GCC; see the file COPYING3. If not see
namespace elna::gcc
{
- class generic_visitor final : public boot::empty_visitor
+ class generic_visitor final : public frontend::empty_visitor
{
tree current_expression{ NULL_TREE };
- elna::boot::symbol_bag bag;
+ elna::frontend::symbol_bag bag;
std::shared_ptr symbols;
void enter_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 build_comparison_operation(boot::binary_expression *expression,
+ tree build_comparison_operation(frontend::binary_expression *expression,
tree_code operator_code, tree left, tree right);
- tree build_bit_logic_operation(boot::binary_expression *expression, tree left, tree right);
- tree build_equality_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(frontend::binary_expression *expression, tree left, tree right);
void build_procedure_call(location_t call_location,
- tree procedure_address, const std::vector& arguments);
+ tree procedure_address, const std::vector& arguments);
void build_record_call(location_t call_location,
- tree symbol, const std::vector& arguments);
- bool build_builtin_procedures(boot::procedure_call *call);
- void build_assert_builtin(location_t call_location, const std::vector& arguments);
+ tree symbol, const std::vector& arguments);
+ bool build_builtin_procedures(frontend::procedure_call *call);
+ void build_assert_builtin(location_t call_location, const std::vector& arguments);
- bool expect_trait_type_only(boot::traits_expression *trait);
- bool expect_trait_for_integral_type(boot::traits_expression *trait);
- void visit_statements(const std::vector& statements);
+ bool expect_trait_type_only(frontend::traits_expression *trait);
+ bool expect_trait_for_integral_type(frontend::traits_expression *trait);
+ void visit_statements(const std::vector& statements);
bool assert_constant(location_t expression_location);
public:
- generic_visitor(std::shared_ptr symbol_table, elna::boot::symbol_bag bag);
+ generic_visitor(std::shared_ptr symbol_table, elna::frontend::symbol_bag bag);
- void visit(boot::program *program) override;
- void visit(boot::procedure_declaration *definition) override;
- void visit(boot::procedure_call *call) override;
- void visit(boot::cast_expression *expression) override;
- void visit(boot::traits_expression *trait) override;
- void visit(boot::literal *literal) override;
- void visit(boot::literal *literal) override;
- void visit(boot::literal *literal) override;
- void visit(boot::literal *boolean) override;
- void visit(boot::literal *character) override;
- void visit(boot::literal *) override;
- void visit(boot::literal *string) override;
- void visit(boot::binary_expression *expression) override;
- void visit(boot::unary_expression *expression) override;
- void visit(boot::constant_declaration *definition) override;
- void visit(boot::variable_declaration *declaration) override;
- void visit(boot::variable_expression *expression) override;
- void visit(boot::array_access_expression *expression) override;
- void visit(boot::field_access_expression *expression) override;
- void visit(boot::dereference_expression *expression) override;
- void visit(boot::unit *unit) override;
- void visit(boot::assign_statement *statement) override;
- void visit(boot::if_statement *statement) override;
- void visit(boot::import_declaration *) override;
- void visit(boot::while_statement *statement) override;
- void visit(boot::return_statement *statement) override;
- void visit(boot::defer_statement *statement) override;
- void visit(boot::case_statement *statement) override;
+ void visit(frontend::program *program) override;
+ void visit(frontend::procedure_declaration *definition) override;
+ void visit(frontend::procedure_call *call) override;
+ void visit(frontend::cast_expression *expression) override;
+ void visit(frontend::traits_expression *trait) override;
+ void visit(frontend::literal *literal) override;
+ void visit(frontend::literal *literal) override;
+ void visit(frontend::literal *literal) override;
+ void visit(frontend::literal *boolean) override;
+ void visit(frontend::literal *character) override;
+ void visit(frontend::literal *) override;
+ void visit(frontend::literal *string) override;
+ void visit(frontend::binary_expression *expression) override;
+ void visit(frontend::unary_expression *expression) override;
+ void visit(frontend::constant_declaration *definition) override;
+ void visit(frontend::variable_declaration *declaration) override;
+ void visit(frontend::variable_expression *expression) override;
+ void visit(frontend::array_access_expression *expression) override;
+ void visit(frontend::field_access_expression *expression) override;
+ void visit(frontend::dereference_expression *expression) override;
+ void visit(frontend::unit *unit) override;
+ void visit(frontend::assign_statement *statement) override;
+ void visit(frontend::if_statement *statement) override;
+ void visit(frontend::import_declaration *) override;
+ void visit(frontend::while_statement *statement) override;
+ void visit(frontend::return_statement *statement) override;
+ void visit(frontend::defer_statement *statement) override;
+ void visit(frontend::case_statement *statement) override;
};
}
diff --git a/include/elna/gcc/elna-tree.h b/include/elna/gcc/elna-tree.h
index f1402a7..48dfeb5 100644
--- a/include/elna/gcc/elna-tree.h
+++ b/include/elna/gcc/elna-tree.h
@@ -27,13 +27,13 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "fold-const.h"
-#include "elna/boot/ast.h"
-#include "elna/boot/symbol.h"
+#include "elna/frontend/ast.h"
+#include "elna/frontend/symbol.h"
#include "elna/gcc/elna1.h"
namespace elna::gcc
{
- using symbol_table = boot::symbol_map;
+ using symbol_table = frontend::symbol_map;
bool is_integral_type(tree type);
bool is_numeric_type(tree type);
@@ -74,11 +74,11 @@ namespace elna::gcc
void defer(tree statement_tree);
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 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 build_arithmetic_operation(boot::binary_expression *expression,
+ tree build_arithmetic_operation(frontend::binary_expression *expression,
tree_code operator_code, tree left, tree right);
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);
diff --git a/rakelib/boot.rake b/rakelib/boot.rake
index afafa2c..ba1320e 100644
--- a/rakelib/boot.rake
+++ b/rakelib/boot.rake
@@ -6,6 +6,7 @@
require 'uri'
require 'net/http'
require 'open3'
+require 'pathname'
def gcc_verbose(gcc_binary)
read, write = IO.pipe
@@ -59,18 +60,20 @@ end
namespace :boot do
# Dependencies.
- GCC_VERSION = "15.1.0"
- HOST_GCC = TMP + 'host/gcc'
+ GCC_VERSION = "15.2.0"
+ HOST_GCC = 'build/host/gcc'
+ HOST_INSTALL = 'build/host/install'
GCC_PATCH = 'https://raw.githubusercontent.com/Homebrew/formula-patches/575ffcaed6d3112916fed77d271dd3799a7255c4/gcc/gcc-15.1.0.diff'
directory HOST_GCC
- directory(TMP + 'tools')
+ directory HOST_INSTALL
+ directory 'build/tools'
desc 'Download and configure the bootstrap compiler'
- task configure: [TMP + 'tools', HOST_GCC, HOST_INSTALL] do
+ task configure: ['build/tools', HOST_GCC, HOST_INSTALL] do
url = URI.parse "https://gcc.gnu.org/pub/gcc/releases/gcc-#{GCC_VERSION}/gcc-#{GCC_VERSION}.tar.xz"
build_target = find_build_target
- source_directory = TMP + "tools/gcc-#{GCC_VERSION}"
+ source_directory = Pathname.new "build/tools/gcc-#{GCC_VERSION}"
frontend_link = source_directory + 'gcc'
download_and_pipe url, source_directory.dirname, ['tar', '-Jxv']
@@ -80,7 +83,7 @@ namespace :boot do
File.symlink Pathname.new('.').relative_path_from(frontend_link), (frontend_link + 'elna')
configure_options = [
- "--prefix=#{HOST_INSTALL.realpath}",
+ "--prefix=#{File.realpath HOST_INSTALL}",
'--enable-languages=c,c++,elna',
'--disable-bootstrap',
'--disable-multilib',
diff --git a/rakelib/gcc.rake b/rakelib/gcc.rake
new file mode 100644
index 0000000..746ebb8
--- /dev/null
+++ b/rakelib/gcc.rake
@@ -0,0 +1,36 @@
+# This Source Code Form is subject to the terms of the Mozilla Public License,
+# v. 2.0. If a copy of the MPL was not distributed with this file, You can
+# obtain one at https://mozilla.org/MPL/2.0/. -}
+# frozen_string_literal: true
+
+require 'pathname'
+require 'rake/clean'
+
+CLEAN.include 'build/gcc'
+
+task source: ['source/main.elna', 'build/gcc/elna'] do |t|
+ sources, compiler = t.prerequisites.partition { |f| f.end_with? '.elna' }
+
+ sh *compiler, '--parse', *sources
+end
+
+rule(/gcc\/.+\.o$/ => ->(file) {
+ source = Pathname.new('source') +
+ Pathname.new(file).relative_path_from('build/gcc').sub_ext('.elna')
+
+ ['build/host/install/bin/gelna', source]
+}) do |t|
+ Pathname.new(t.name).dirname.mkpath
+ sources, compiler = t.prerequisites.partition { |source| source.end_with? '.elna' }
+
+ sh *compiler, '-c', '-O0', '-g', '-o', t.name, *sources
+end
+
+file 'build/gcc/elna' => FileList['source/**/*.elna'].reject { |file|
+ file != file.downcase
+}.map { |file|
+ Pathname.new('build/gcc') +
+ Pathname.new(file).relative_path_from('source').sub_ext('.o')
+} do |t|
+ sh 'build/host/install/bin/gcc', '-o', t.name, *t.prerequisites
+end