Update to GCC 15.1

This commit is contained in:
Eugen Wissner 2025-05-14 23:05:52 +02:00
parent a02e053ed2
commit 9726fcedd9
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 74 additions and 267 deletions

View File

@ -8,8 +8,7 @@ require 'rake/clean'
require_relative 'tools/support' require_relative 'tools/support'
# Dependencies. # Dependencies.
GCC_VERSION = "14.2.0" GCC_VERSION = "15.1.0"
GCC_PATCH = 'https://raw.githubusercontent.com/Homebrew/formula-patches/f30c309442a60cfb926e780eae5d70571f8ab2cb/gcc/gcc-14.2.0-r2.diff'
# Paths. # Paths.
HOST_GCC = TMP + 'host/gcc' HOST_GCC = TMP + 'host/gcc'
@ -34,7 +33,6 @@ namespace :boot do
frontend_link = source_directory + 'gcc' frontend_link = source_directory + 'gcc'
download_and_pipe url, source_directory.dirname, ['tar', '-Jxv'] download_and_pipe url, source_directory.dirname, ['tar', '-Jxv']
download_and_pipe URI.parse(GCC_PATCH), source_directory, ['patch', '-p1']
sh 'contrib/download_prerequisites', chdir: source_directory.to_path sh 'contrib/download_prerequisites', chdir: source_directory.to_path
File.symlink Pathname.new('.').relative_path_from(frontend_link), (frontend_link + 'elna') File.symlink Pathname.new('.').relative_path_from(frontend_link), (frontend_link + 'elna')

View File

@ -211,9 +211,9 @@ procedure_heading:
} }
} }
procedure_definition: procedure_definition:
"proc" identifier_definition procedure_heading ";" block "proc" identifier_definition procedure_heading block
{ {
$$ = new boot::procedure_definition(boot::make_position(@1), std::move($2), $3.second, $5); $$ = new boot::procedure_definition(boot::make_position(@1), std::move($2), $3.second, $4);
std::swap($3.first, $$->parameter_names); std::swap($3.first, $$->parameter_names);
} }
| "proc" identifier_definition procedure_heading ";" "extern" | "proc" identifier_definition procedure_heading ";" "extern"

View File

@ -19,12 +19,12 @@ type
_extern, _extern,
_const, _const,
_var, _var,
array, _case,
_of, _of,
_type, _type,
_record, _record,
_union, _union,
pointer, pipe,
to, to,
boolean, boolean,
_nil, _nil,
@ -64,7 +64,8 @@ type
string, string,
_defer, _defer,
exclamation, exclamation,
arrow arrow,
trait
) )
Position* = record Position* = record
line: Word; line: Word;
@ -140,22 +141,22 @@ proc exit(code: Int) -> !; extern
(* (*
Standard procedures. Standard procedures.
*) *)
proc reallocarray(ptr: ^Byte, n: Word, size: Word) -> ^Byte; proc reallocarray(ptr: ^Byte, n: Word, size: Word) -> ^Byte
begin begin
return realloc(ptr, n * size) return realloc(ptr, n * size)
end end
proc write_s(value: String); proc write_s(value: String)
begin begin
write(0, cast(value.ptr: ^Byte), cast(value.length: Int)) write(0, cast(value.ptr: ^Byte), cast(value.length: Int))
end end
proc write_z(value: ^Char); proc write_z(value: ^Char)
begin begin
write(0, cast(value: ^Byte), cast(strlen(value): Int)) write(0, cast(value: ^Byte), cast(strlen(value): Int))
end end
proc write_b(value: Bool); proc write_b(value: Bool)
begin begin
if value then if value then
write_s("true") write_s("true")
@ -164,12 +165,12 @@ begin
end end
end end
proc write_c(value: Char); proc write_c(value: Char)
begin begin
write(0, cast(@value: ^Byte), 1) write(0, cast(@value: ^Byte), 1)
end end
proc write_i(value: Int); proc write_i(value: Int)
var var
digit: Int digit: Int
n: Word n: Word
@ -193,42 +194,42 @@ begin
end end
end end
proc write_u(value: Word); proc write_u(value: Word)
begin begin
write_i(cast(value: Int)) write_i(cast(value: Int))
end end
proc is_digit(c: Char) -> Bool; proc is_digit(c: Char) -> Bool
begin begin
return cast(c: Int) >= cast('0': Int) & cast(c: Int) <= cast('9': Int) return cast(c: Int) >= cast('0': Int) & cast(c: Int) <= cast('9': Int)
end end
proc is_alpha(c: Char) -> Bool; proc is_alpha(c: Char) -> Bool
begin begin
return cast(c: Int) >= cast('A': Int) & cast(c: Int) <= cast('z': Int) return cast(c: Int) >= cast('A': Int) & cast(c: Int) <= cast('z': Int)
end end
proc is_alnum(c: Char) -> Bool; proc is_alnum(c: Char) -> Bool
begin begin
return is_digit(c) or is_alpha(c) return is_digit(c) or is_alpha(c)
end end
proc is_space(c: Char) -> Bool; proc is_space(c: Char) -> Bool
begin begin
return c = ' ' or c = '\n' or c = '\t' return c = ' ' or c = '\n' or c = '\t'
end end
proc substring(string: String, start: Word, count: Word) -> String; proc substring(string: String, start: Word, count: Word) -> String
begin begin
return String(string.ptr + start, count) return String(string.ptr + start, count)
end end
proc open_substring(string: String, start: Word) -> String; proc open_substring(string: String, start: Word) -> String
begin begin
return substring(string, start, string.length - start) return substring(string, start, string.length - start)
end end
proc string_dup(origin: String) -> String; proc string_dup(origin: String) -> String
var var
copy: ^Char copy: ^Char
begin begin
@ -238,7 +239,7 @@ begin
return String(copy, origin.length) return String(copy, origin.length)
end end
proc string_buffer_new() -> StringBuffer; proc string_buffer_new() -> StringBuffer
var var
result: StringBuffer result: StringBuffer
begin begin
@ -249,7 +250,7 @@ begin
return result return result
end end
proc string_buffer_push(buffer: ^StringBuffer, char: Char); proc string_buffer_push(buffer: ^StringBuffer, char: Char)
begin begin
if buffer^.size >= buffer^.capacity then if buffer^.size >= buffer^.capacity then
buffer^.capacity := buffer^.capacity + 1024u; buffer^.capacity := buffer^.capacity + 1024u;
@ -259,12 +260,12 @@ begin
buffer^.size := buffer^.size + 1u buffer^.size := buffer^.size + 1u
end end
proc string_buffer_pop(buffer: ^StringBuffer, count: Word); proc string_buffer_pop(buffer: ^StringBuffer, count: Word)
begin begin
buffer^.size := buffer^.size - count buffer^.size := buffer^.size - count
end end
proc string_buffer_clear(buffer: ^StringBuffer) -> String; proc string_buffer_clear(buffer: ^StringBuffer) -> String
var var
result: String result: String
begin begin
@ -277,12 +278,12 @@ end
End of standard procedures. End of standard procedures.
*) *)
proc make_position() -> Position; proc make_position() -> Position
begin begin
return Position(1u, 1u) return Position(1u, 1u)
end end
proc read_source(filename: ^Char) -> ^SourceFile; proc read_source(filename: ^Char) -> ^SourceFile
var var
result: ^SourceFile result: ^SourceFile
file_handle: ^FILE file_handle: ^FILE
@ -298,7 +299,7 @@ begin
return result return result
end end
proc escape_char(escape: Char, result: ^Char) -> Bool; proc escape_char(escape: Char, result: ^Char) -> Bool
var var
successful: Bool successful: Bool
begin begin
@ -344,7 +345,7 @@ begin
return successful return successful
end end
proc source_file_empty(source_input: ^Byte) -> Bool; proc source_file_empty(source_input: ^Byte) -> Bool
var var
source_file: ^SourceFile source_file: ^SourceFile
begin begin
@ -358,7 +359,7 @@ begin
return source_file^.size = 0u return source_file^.size = 0u
end end
proc source_file_head(source_input: ^Byte) -> Char; proc source_file_head(source_input: ^Byte) -> Char
var var
source_file: ^SourceFile source_file: ^SourceFile
begin begin
@ -367,7 +368,7 @@ begin
return source_file^.buffer[source_file^.index] return source_file^.buffer[source_file^.index]
end end
proc source_file_advance(source_input: ^Byte); proc source_file_advance(source_input: ^Byte)
var var
source_file: ^SourceFile source_file: ^SourceFile
begin begin
@ -376,34 +377,34 @@ begin
source_file^.index := source_file^.index + 1u source_file^.index := source_file^.index + 1u
end end
proc source_code_empty(source_code: ^SourceCode) -> Bool; proc source_code_empty(source_code: ^SourceCode) -> Bool
begin begin
return source_code^.empty(source_code^.input) return source_code^.empty(source_code^.input)
end end
proc source_code_head(source_code: SourceCode) -> Char; proc source_code_head(source_code: SourceCode) -> Char
begin begin
return source_code.head(source_code.input) return source_code.head(source_code.input)
end end
proc source_code_advance(source_code: ^SourceCode); proc source_code_advance(source_code: ^SourceCode)
begin begin
source_code^.advance(source_code^.input); source_code^.advance(source_code^.input);
source_code^.position.column := source_code^.position.column source_code^.position.column := source_code^.position.column
end end
proc source_code_break(source_code: ^SourceCode); proc source_code_break(source_code: ^SourceCode)
begin begin
source_code^.position.line := source_code^.position.line + 1u; source_code^.position.line := source_code^.position.line + 1u;
source_code^.position.column := 0u source_code^.position.column := 0u
end end
proc source_code_expect(source_code: ^SourceCode, expected: Char) -> Bool; proc source_code_expect(source_code: ^SourceCode, expected: Char) -> Bool
begin begin
return ~source_code_empty(source_code) & source_code_head(source_code^) = expected return ~source_code_empty(source_code) & source_code_head(source_code^) = expected
end end
proc skip_spaces(source_code: ^SourceCode); proc skip_spaces(source_code: ^SourceCode)
var var
current: Char current: Char
begin begin
@ -419,12 +420,12 @@ begin
end end
end end
proc is_ident(char: Char) -> Bool; proc is_ident(char: Char) -> Bool
begin begin
return is_alnum(char) or char = '_' return is_alnum(char) or char = '_'
end end
proc lex_identifier(source_code: ^SourceCode, token_content: ^StringBuffer); proc lex_identifier(source_code: ^SourceCode, token_content: ^StringBuffer)
var var
content_length: Word content_length: Word
begin begin
@ -434,7 +435,7 @@ begin
end end
end end
proc lex_comment(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool; proc lex_comment(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool
var var
trailing: Word trailing: Word
begin begin
@ -457,7 +458,7 @@ begin
return trailing = 2u return trailing = 2u
end end
proc lex_character(source_code: ^SourceCode, token_content: ^Char) -> Bool; proc lex_character(source_code: ^SourceCode, token_content: ^Char) -> Bool
var var
successful: Bool successful: Bool
begin begin
@ -479,7 +480,7 @@ begin
return successful return successful
end end
proc lex_string(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool; proc lex_string(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool
var var
token_end, constructed_string: ^Char token_end, constructed_string: ^Char
token_length: Word token_length: Word
@ -504,7 +505,7 @@ begin
return is_valid return is_valid
end end
proc lex_number(source_code: ^SourceCode, token_content: ^Int); proc lex_number(source_code: ^SourceCode, token_content: ^Int)
begin begin
token_content^ := 0; token_content^ := 0;
@ -515,7 +516,7 @@ begin
end end
end end
proc print_tokens(tokens: ^Token, tokens_size: Word); proc print_tokens(tokens: ^Token, tokens_size: Word)
var var
current_token: ^Token current_token: ^Token
i: Word i: Word
@ -549,8 +550,8 @@ begin
write_s("CONST") write_s("CONST")
| TokenKind._var: | TokenKind._var:
write_s("VAR") write_s("VAR")
| TokenKind.array: | TokenKind._case:
write_s("ARRAY") write_s("CASE")
| TokenKind._of: | TokenKind._of:
write_s("OF") write_s("OF")
| TokenKind._type: | TokenKind._type:
@ -559,8 +560,8 @@ begin
write_s("RECORD") write_s("RECORD")
| TokenKind._union: | TokenKind._union:
write_s("UNION") write_s("UNION")
| TokenKind.pointer: | TokenKind.pipe:
write_s("POINTER") write_s("|")
| TokenKind.to: | TokenKind.to:
write_s("TO") write_s("TO")
| TokenKind.boolean: | TokenKind.boolean:
@ -570,11 +571,11 @@ begin
| TokenKind._nil: | TokenKind._nil:
write_s("NIL") write_s("NIL")
| TokenKind.and: | TokenKind.and:
write_s("AND") write_s("&")
| TokenKind._or: | TokenKind._or:
write_s("OR") write_s("OR")
| TokenKind.not: | TokenKind.not:
write_s("NOT") write_s("~")
| TokenKind._return: | TokenKind._return:
write_s("RETURN") write_s("RETURN")
| TokenKind._cast: | TokenKind._cast:
@ -587,6 +588,9 @@ begin
write_c('<'); write_c('<');
write_s(current_token^.value.string); write_s(current_token^.value.string);
write_c('>') write_c('>')
| TokenKind.trait:
write_c('#');
write_s(current_token^.value.string)
| TokenKind.left_paren: | TokenKind.left_paren:
write_s("(") write_s("(")
| TokenKind.right_paren: | TokenKind.right_paren:
@ -665,7 +669,7 @@ begin
write_c('\n') write_c('\n')
end end
proc categorize_identifier(token_content: String) -> Token; proc categorize_identifier(token_content: String) -> Token
var var
current_token: Token current_token: Token
begin begin
@ -693,8 +697,8 @@ begin
current_token.kind := TokenKind._const current_token.kind := TokenKind._const
elsif "var" = token_content then elsif "var" = token_content then
current_token.kind := TokenKind._var current_token.kind := TokenKind._var
elsif "array" = token_content then elsif "case" = token_content then
current_token.kind := TokenKind.array current_token.kind := TokenKind._case
elsif "of" = token_content then elsif "of" = token_content then
current_token.kind := TokenKind._of current_token.kind := TokenKind._of
elsif "type" = token_content then elsif "type" = token_content then
@ -703,8 +707,6 @@ begin
current_token.kind := TokenKind._record current_token.kind := TokenKind._record
elsif "union" = token_content then elsif "union" = token_content then
current_token.kind := TokenKind._union current_token.kind := TokenKind._union
elsif "pointer" = token_content then
current_token.kind := TokenKind.pointer
elsif "to" = token_content then elsif "to" = token_content then
current_token.kind := TokenKind.to current_token.kind := TokenKind.to
elsif "true" = token_content then elsif "true" = token_content then
@ -715,12 +717,8 @@ begin
current_token.value.boolean_value := false current_token.value.boolean_value := false
elsif "nil" = token_content then elsif "nil" = token_content then
current_token.kind := TokenKind._nil current_token.kind := TokenKind._nil
elsif "and" = token_content then
current_token.kind := TokenKind.and
elsif "or" = token_content then elsif "or" = token_content then
current_token.kind := TokenKind._or current_token.kind := TokenKind._or
elsif "not" = token_content then
current_token.kind := TokenKind.not
elsif "return" = token_content then elsif "return" = token_content then
current_token.kind := TokenKind._return current_token.kind := TokenKind._return
elsif "cast" = token_content then elsif "cast" = token_content then
@ -735,7 +733,7 @@ begin
return current_token return current_token
end end
proc tokenize(source_code: SourceCode, tokens_size: ^Word) -> ^Token; proc tokenize(source_code: SourceCode, tokens_size: ^Word) -> ^Token
var var
tokens, current_token: ^Token tokens, current_token: ^Token
first_char: Char first_char: Char
@ -755,6 +753,12 @@ begin
if is_alpha(first_char) or first_char = '_' then if is_alpha(first_char) or first_char = '_' then
lex_identifier(@source_code, @token_buffer); lex_identifier(@source_code, @token_buffer);
current_token^ := categorize_identifier(string_buffer_clear(@token_buffer)) current_token^ := categorize_identifier(string_buffer_clear(@token_buffer))
elsif first_char = '#' then
source_code_advance(@source_code);
lex_identifier(@source_code, @token_buffer);
current_token^.kind := TokenKind.trait;
current_token^.value.string := string_dup(string_buffer_clear(@token_buffer))
elsif is_digit(first_char) then elsif is_digit(first_char) then
lex_number(@source_code, @current_token^.value.int_value); lex_number(@source_code, @current_token^.value.int_value);
@ -894,6 +898,15 @@ begin
elsif first_char = '!' then elsif first_char = '!' then
current_token^.kind := TokenKind.exclamation; current_token^.kind := TokenKind.exclamation;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = '&' then
current_token^.kind := TokenKind.and;
source_code_advance(@source_code)
elsif first_char = '~' then
current_token^.kind := TokenKind.not;
source_code_advance(@source_code)
elsif first_char = '|' then
current_token^.kind := TokenKind.pipe;
source_code_advance(@source_code)
else else
current_token^.kind := TokenKind.unknown; current_token^.kind := TokenKind.unknown;
source_code_advance(@source_code) source_code_advance(@source_code)
@ -912,7 +925,7 @@ begin
return tokens return tokens
end end
proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine; proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine
var var
parameter: ^^Char parameter: ^^Char
i: Int i: Int
@ -953,7 +966,7 @@ begin
return result return result
end end
proc process(argc: Int, argv: ^^Char) -> Int; proc process(argc: Int, argv: ^^Char) -> Int
var var
tokens: ^Token tokens: ^Token
tokens_size: Word tokens_size: Word

View File

@ -1,204 +0,0 @@
#include <stdio.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/reboot.h>
#define FILENAME_BUFFER_SIZE 256
size_t read_command(int descriptor, char *command_buffer)
{
ssize_t bytes_read = 0;
size_t read_so_far = 0;
while ((bytes_read = read(descriptor, command_buffer + read_so_far, FILENAME_BUFFER_SIZE - read_so_far - 1)) > 0)
{
read_so_far += bytes_read;
if (read_so_far >= FILENAME_BUFFER_SIZE - 1)
{
break;
}
}
command_buffer[read_so_far] = 0;
return read_so_far;
}
enum status
{
status_success,
status_failure,
status_warning,
status_fatal
};
unsigned int make_path(char *destination, const char *directory, const char *filename, const char *extension)
{
unsigned int i = 0;
for (; i < FILENAME_BUFFER_SIZE; i++)
{
if (directory[i] == 0)
{
break;
}
destination[i] = directory[i];
}
for (int j = 0; i < FILENAME_BUFFER_SIZE; i++, j++)
{
if (filename[j] == 0)
{
break;
}
destination[i] = filename[j];
}
if (extension == NULL)
{
goto done;
}
for (int j = 0; i < FILENAME_BUFFER_SIZE; i++, j++)
{
if (extension[j] == 0)
{
break;
}
destination[i] = extension[j];
}
done:
destination[i] = 0;
return i;
}
enum status run_test(const char *file_entry_name)
{
printf("Running %s. ", file_entry_name);
char filename[FILENAME_BUFFER_SIZE];
char command_buffer[FILENAME_BUFFER_SIZE];
char file_buffer[256];
int pipe_ends[2];
if (pipe(pipe_ends) == -1)
{
perror("pipe");
return status_fatal;
}
make_path(filename, "./tests/", file_entry_name, NULL);
int child_pid = fork();
if (child_pid == -1)
{
return status_fatal;
}
else if (child_pid == 0)
{
close(STDIN_FILENO);
close(STDERR_FILENO);
close(pipe_ends[0]); // Close the read end.
if (dup2(pipe_ends[1], STDOUT_FILENO) == -1)
{
perror("dup2");
}
else
{
execl(filename, filename);
perror("execl");
}
close(STDOUT_FILENO);
close(pipe_ends[1]);
_exit(1);
}
else
{
close(pipe_ends[1]); // Close the write end.
read_command(pipe_ends[0], command_buffer);
close(pipe_ends[0]);
int wait_status = 0;
make_path(filename, "./expectations/", file_entry_name, ".txt");
FILE *expectation_descriptor = fopen(filename, "r");
if (expectation_descriptor == NULL)
{
return status_warning;
}
size_t read_from_file = fread(file_buffer, 1, sizeof(file_buffer) - 1, expectation_descriptor);
fclose(expectation_descriptor);
file_buffer[read_from_file] = 0;
for (unsigned int i = 0; ; ++i)
{
if (command_buffer[i] == 0 && file_buffer[i] == 0)
{
fwrite("\n", 1, 1, stdout);
return status_success;
}
else if (command_buffer[i] != file_buffer[i])
{
printf("Failed. Got:\n%s", command_buffer);
return status_failure;
}
}
}
}
struct summary
{
size_t total;
size_t failure;
size_t success;
};
void walk()
{
DIR *directory_stream = opendir("./tests");
struct dirent *file_entry;
struct summary test_summary = { .total = 0, .failure = 0, .success = 0 };
while ((file_entry = readdir(directory_stream)) != NULL)
{
if (file_entry->d_name[0] == '.')
{
continue;
}
++test_summary.total;
switch (run_test(file_entry->d_name))
{
case status_failure:
++test_summary.failure;
break;
case status_success:
++test_summary.success;
break;
case status_warning:
break;
case status_fatal:
goto end_walk;
}
}
printf("Successful: %lu, Failed: %lu, Total: %lu.\n",
test_summary.success, test_summary.failure, test_summary.total);
end_walk:
closedir(directory_stream);
}
int main()
{
int dev_console = open("/dev/console", O_WRONLY);
if (dev_console != -1)
{
dup2(dev_console, STDOUT_FILENO);
walk();
close(dev_console);
}
sync();
reboot(RB_POWER_OFF);
return 1;
}