Use colon instead of as to cast

This commit is contained in:
Eugen Wissner 2025-02-14 08:05:03 +01:00
parent c564847c6b
commit 634b6dafae
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 57 additions and 38 deletions

View File

@ -21,3 +21,25 @@ and a possbility to compile Elna programs for different platforms.
Flex and bison grammar specifications, `lexer.ll` and `parser.yy`, can be found Flex and bison grammar specifications, `lexer.ll` and `parser.yy`, can be found
in the `boot/` directory. in the `boot/` directory.
## Build
The frontend requires GCC 14.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
```
See `rake -T` for more tasks. The GCC source is under `build/tools`. The
installation path is `build/host/install`.

View File

@ -134,9 +134,6 @@ return {
cast { cast {
return yy::parser::make_CAST(this->location); return yy::parser::make_CAST(this->location);
} }
as {
return yy::parser::make_AS(this->location);
}
sizeof { sizeof {
return yy::parser::make_SIZEOF(this->location); return yy::parser::make_SIZEOF(this->location);
} }

View File

@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION %token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION
%token BEGIN_BLOCK END_BLOCK EXTERN DEFER %token BEGIN_BLOCK END_BLOCK EXTERN DEFER
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA %token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
%token AND OR NOT CAST AS SIZEOF %token AND OR NOT CAST SIZEOF
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS %token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
%token PLUS MINUS MULTIPLICATION DIVISION REMAINDER %token PLUS MINUS MULTIPLICATION DIVISION REMAINDER
%token ASSIGNMENT COLON HAT AT NIL ARROW %token ASSIGNMENT COLON HAT AT NIL ARROW
@ -189,7 +189,7 @@ call_expression: IDENTIFIER actual_parameter_list
$$ = new elna::boot::call_expression(elna::boot::make_position(@1), $1); $$ = new elna::boot::call_expression(elna::boot::make_position(@1), $1);
std::swap($$->arguments(), $2); std::swap($$->arguments(), $2);
} }
cast_expression: CAST LEFT_PAREN expression AS type_expression RIGHT_PAREN cast_expression: CAST LEFT_PAREN expression COLON type_expression RIGHT_PAREN
{ {
$$ = new elna::boot::cast_expression(elna::boot::make_position(@1), $5, $3); $$ = new elna::boot::cast_expression(elna::boot::make_position(@1), $5, $3);
} }
@ -403,9 +403,9 @@ optional_statements:
field_declaration: field_declaration:
IDENTIFIER COLON type_expression { $$ = std::make_pair($1, $3); } IDENTIFIER COLON type_expression { $$ = std::make_pair($1, $3); }
field_list: field_list:
field_declaration SEMICOLON field_list field_declaration field_list
{ {
std::swap($$, $3); std::swap($$, $2);
$$.emplace($$.cbegin(), $1); $$.emplace($$.cbegin(), $1);
} }
| field_declaration { $$.emplace_back($1); } | field_declaration { $$.emplace_back($1); }

View File

@ -63,46 +63,46 @@ const
type type
Position* = record Position* = record
line: Word; line: Word
column: Word column: Word
end end
Location* = record Location* = record
first: Position; first: Position
last: Position last: Position
end end
SourceCode = record SourceCode = record
position: Position; position: Position
text: String text: String
end end
TokenValue* = union TokenValue* = union
int_value: Int; int_value: Int
string_value: pointer to Char; string_value: pointer to Char
string: String; string: String
boolean_value: Bool; boolean_value: Bool
char_value: Char char_value: Char
end end
Token* = record Token* = record
kind: Int; kind: Int
value: TokenValue; value: TokenValue
location: Location location: Location
end end
FILE* = record FILE* = record
dummy: Int dummy: Int
end end
CommandLine* = record CommandLine* = record
input: pointer to Char; input: pointer to Char
tokenize: Bool; tokenize: Bool
syntax_tree: Bool syntax_tree: Bool
end end
Literal* = record Literal* = record
value: Int value: Int
end end
ConstantDefinition* = record ConstantDefinition* = record
name: pointer to Char; name: pointer to Char
body: pointer to Literal body: pointer to Literal
end end
ConstantPart* = record ConstantPart* = record
elements: pointer to pointer to ConstantDefinition; elements: pointer to pointer to ConstantDefinition
count: Word count: Word
end end
Program* = record Program* = record
@ -184,7 +184,7 @@ begin
digit := value % 10; digit := value % 10;
value := value / 10; value := value / 10;
buffer[n] := cast(cast('0' as Int) + digit as Char); buffer[n] := cast(cast('0': Int) + digit: Char);
n := n - 1u n := n - 1u
end; end;
while n < 10u do while n < 10u do
@ -200,12 +200,12 @@ end
proc is_digit(c: Char) -> Bool; proc is_digit(c: Char) -> Bool;
begin begin
return cast(c as Int) >= cast('0' as Int) and cast(c as Int) <= cast('9' as Int) return cast(c: Int) >= cast('0': Int) and 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 as Int) >= cast('A' as Int) and cast(c as Int) <= cast('z' as Int) return cast(c: Int) >= cast('A': Int) and cast(c: Int) <= cast('z': Int)
end end
proc is_alnum(c: Char) -> Bool; proc is_alnum(c: Char) -> Bool;
@ -232,7 +232,7 @@ proc string_dup(origin: String) -> String;
var var
copy: pointer to Char; copy: pointer to Char;
begin begin
copy := cast(malloc(origin.length) as pointer to Char); copy := cast(malloc(origin.length): pointer to Char);
strncpy(copy, origin.ptr, origin.length); strncpy(copy, origin.ptr, origin.length);
return String(copy, origin.length) return String(copy, origin.length)
@ -278,8 +278,8 @@ begin
if fread(input, source_size, 1, input_file) <> 1u then if fread(input, source_size, 1, input_file) <> 1u then
return false return false
end; end;
result^.length := cast(source_size as Word); result^.length := cast(source_size: Word);
result^.ptr := cast(input as pointer to Char); result^.ptr := cast(input: pointer to Char);
return true return true
end end
@ -413,8 +413,8 @@ begin
if token_end^ <> '\"' then if token_end^ <> '\"' then
return input return input
end; end;
token_length := cast(token_end - input as Word); token_length := cast(token_end - input: Word);
current_token^.value.string_value := cast(calloc(token_length, 1) as pointer to Char); current_token^.value.string_value := cast(calloc(token_length, 1): pointer to Char);
is_valid := true; is_valid := true;
constructed_string := current_token^.value.string_value; constructed_string := current_token^.value.string_value;
@ -671,7 +671,7 @@ begin
source_code := skip_spaces(source_code); source_code := skip_spaces(source_code);
while source_code.text.length <> 0u do while source_code.text.length <> 0u do
tokens := cast(reallocarray(tokens, tokens_size^ + 1u, sizeof(Token)) as pointer to Token); tokens := cast(reallocarray(tokens, tokens_size^ + 1u, sizeof(Token)): pointer to Token);
current_token := tokens + tokens_size^; current_token := tokens + tokens_size^;
first_char := source_code.text[1u]; first_char := source_code.text[1u];
@ -681,7 +681,7 @@ begin
elsif is_digit(first_char) then elsif is_digit(first_char) then
token_end := nil; token_end := nil;
current_token^.value.int_value := strtol(source_code.text.ptr, @token_end, 10); current_token^.value.int_value := strtol(source_code.text.ptr, @token_end, 10);
token_length := cast(token_end - source_code.text.ptr as Word); token_length := cast(token_end - source_code.text.ptr: Word);
if token_end^ = 'u' then if token_end^ = 'u' then
current_token^.kind := TOKEN_WORD; current_token^.kind := TOKEN_WORD;
@ -712,7 +712,7 @@ begin
source_code := advance_source(source_code, 1u) source_code := advance_source(source_code, 1u)
elsif first_char = '\'' then elsif first_char = '\'' then
token_end := lex_character(source_code.text.ptr + 1, current_token); token_end := lex_character(source_code.text.ptr + 1, current_token);
token_length := cast(token_end - source_code.text.ptr as Word); token_length := cast(token_end - source_code.text.ptr: Word);
if token_end^ = '\'' then if token_end^ = '\'' then
current_token^.kind := TOKEN_CHARACTER; current_token^.kind := TOKEN_CHARACTER;
@ -725,7 +725,7 @@ begin
if token_end^ = '"' then if token_end^ = '"' then
current_token^.kind := TOKEN_STRING; current_token^.kind := TOKEN_STRING;
token_length := cast(token_end - source_code.text.ptr as Word); token_length := cast(token_end - source_code.text.ptr: Word);
source_code := advance_source(source_code, token_length + 1u) source_code := advance_source(source_code, token_length + 1u)
end end
elsif first_char = '[' then elsif first_char = '[' then
@ -823,7 +823,7 @@ end
proc parse_literal(tokens: pointer to pointer to Token, tokens_size: pointer to Word) -> pointer to Literal; proc parse_literal(tokens: pointer to pointer to Token, tokens_size: pointer to Word) -> pointer to Literal;
begin begin
return cast(calloc(1, sizeof(Literal)) as pointer to Literal) return cast(calloc(1, sizeof(Literal)): pointer to Literal)
end end
proc parse_constant_definition(tokens: pointer to pointer to Token, proc parse_constant_definition(tokens: pointer to pointer to Token,
@ -831,9 +831,9 @@ proc parse_constant_definition(tokens: pointer to pointer to Token,
var var
result: pointer to ConstantDefinition; result: pointer to ConstantDefinition;
begin begin
result := cast(calloc(1, sizeof(ConstantDefinition)) as pointer to ConstantDefinition); result := cast(calloc(1, sizeof(ConstantDefinition)): pointer to ConstantDefinition);
result^.name := cast(malloc(strlen(tokens^^.value.string_value)) as pointer to Char); result^.name := cast(malloc(strlen(tokens^^.value.string_value)): pointer to Char);
strcpy(result^.name, tokens^^.value.string_value); strcpy(result^.name, tokens^^.value.string_value);
tokens^ := tokens^ + 2u; tokens^ := tokens^ + 2u;
@ -855,7 +855,7 @@ var
result: pointer to Program, result: pointer to Program,
current_constant: pointer to pointer to ConstantDefinition; current_constant: pointer to pointer to ConstantDefinition;
begin begin
result := cast(calloc(1, sizeof(Program)) as pointer to Program); result := cast(calloc(1, sizeof(Program)): pointer to Program);
result^.constants.elements := nil; result^.constants.elements := nil;
result^.constants.count := 0u; result^.constants.count := 0u;
@ -867,7 +867,7 @@ begin
while tokens_size^ > 0u and tokens^^.kind = TOKEN_IDENTIFIER do while tokens_size^ > 0u and tokens^^.kind = TOKEN_IDENTIFIER do
result^.constants.elements := cast( result^.constants.elements := cast(
reallocarray(result^.constants.elements, result^.constants.count + 1u, sizeof(pointer to ConstantDefinition)) reallocarray(result^.constants.elements, result^.constants.count + 1u, sizeof(pointer to ConstantDefinition))
as pointer to pointer to ConstantDefinition); : pointer to pointer to ConstantDefinition);
current_constant := result^.constants.elements + result^.constants.count; current_constant := result^.constants.elements + result^.constants.count;
result^.constants.count := result^.constants.count + 1u; result^.constants.count := result^.constants.count + 1u;
@ -887,7 +887,7 @@ var
result: pointer to CommandLine; result: pointer to CommandLine;
begin begin
i := 1; i := 1;
result := cast(malloc(sizeof(CommandLine)) as pointer to CommandLine); result := cast(malloc(sizeof(CommandLine)): pointer to CommandLine);
result^.tokenize := false; result^.tokenize := false;
result^.syntax_tree := false; result^.syntax_tree := false;
result^.input := nil; result^.input := nil;