From 49c1258acb321a2e3dddc71d306afc2b60b2c1c7 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 14 Feb 2025 08:05:03 +0100 Subject: [PATCH] Use colon instead of as to cast --- README.md | 16 +++++++++++++ boot/lexer.ll | 3 --- boot/parser.yy | 8 +++---- source.elna | 62 +++++++++++++++++++++++++------------------------- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index c15d6a2..6a1124b 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,19 @@ and a possbility to compile Elna programs for different platforms. Flex and bison grammar specifications, `lexer.ll` and `parser.yy`, can be found 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 `rake boot`. +See `rake -T` for more tasks. diff --git a/boot/lexer.ll b/boot/lexer.ll index f0bbe8a..5411040 100644 --- a/boot/lexer.ll +++ b/boot/lexer.ll @@ -134,9 +134,6 @@ return { cast { return yy::parser::make_CAST(this->location); } -as { - return yy::parser::make_AS(this->location); - } sizeof { return yy::parser::make_SIZEOF(this->location); } diff --git a/boot/parser.yy b/boot/parser.yy index f59f8ab..dd75c07 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -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 BEGIN_BLOCK END_BLOCK EXTERN DEFER %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 PLUS MINUS MULTIPLICATION DIVISION REMAINDER %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); 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); } @@ -403,9 +403,9 @@ optional_statements: field_declaration: IDENTIFIER COLON type_expression { $$ = std::make_pair($1, $3); } field_list: - field_declaration SEMICOLON field_list + field_declaration field_list { - std::swap($$, $3); + std::swap($$, $2); $$.emplace($$.cbegin(), $1); } | field_declaration { $$.emplace_back($1); } diff --git a/source.elna b/source.elna index 51c6e9c..a3a2a1c 100644 --- a/source.elna +++ b/source.elna @@ -63,46 +63,46 @@ const type Position* = record - line: Word; + line: Word column: Word end Location* = record - first: Position; + first: Position last: Position end SourceCode = record - position: Position; + position: Position text: String end TokenValue* = union - int_value: Int; - string_value: pointer to Char; - string: String; - boolean_value: Bool; + int_value: Int + string_value: pointer to Char + string: String + boolean_value: Bool char_value: Char end Token* = record - kind: Int; - value: TokenValue; + kind: Int + value: TokenValue location: Location end FILE* = record dummy: Int end CommandLine* = record - input: pointer to Char; - tokenize: Bool; + input: pointer to Char + tokenize: Bool syntax_tree: Bool end Literal* = record value: Int end ConstantDefinition* = record - name: pointer to Char; + name: pointer to Char body: pointer to Literal end ConstantPart* = record - elements: pointer to pointer to ConstantDefinition; + elements: pointer to pointer to ConstantDefinition count: Word end Program* = record @@ -184,7 +184,7 @@ begin digit := 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 end; while n < 10u do @@ -200,12 +200,12 @@ end proc is_digit(c: Char) -> Bool; 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 proc is_alpha(c: Char) -> Bool; 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 proc is_alnum(c: Char) -> Bool; @@ -232,7 +232,7 @@ proc string_dup(origin: String) -> String; var copy: pointer to Char; begin - copy := cast(malloc(origin.length) as pointer to Char); + copy := cast(malloc(origin.length): pointer to Char); strncpy(copy, origin.ptr, origin.length); return String(copy, origin.length) @@ -278,8 +278,8 @@ begin if fread(input, source_size, 1, input_file) <> 1u then return false end; - result^.length := cast(source_size as Word); - result^.ptr := cast(input as pointer to Char); + result^.length := cast(source_size: Word); + result^.ptr := cast(input: pointer to Char); return true end @@ -413,8 +413,8 @@ begin if token_end^ <> '\"' then return input end; - token_length := cast(token_end - input as Word); - current_token^.value.string_value := cast(calloc(token_length, 1) as pointer to Char); + token_length := cast(token_end - input: Word); + current_token^.value.string_value := cast(calloc(token_length, 1): pointer to Char); is_valid := true; constructed_string := current_token^.value.string_value; @@ -671,7 +671,7 @@ begin source_code := skip_spaces(source_code); 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^; first_char := source_code.text[1u]; @@ -681,7 +681,7 @@ begin elsif is_digit(first_char) then token_end := nil; 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 current_token^.kind := TOKEN_WORD; @@ -712,7 +712,7 @@ begin source_code := advance_source(source_code, 1u) elsif first_char = '\'' then 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 current_token^.kind := TOKEN_CHARACTER; @@ -725,7 +725,7 @@ begin if token_end^ = '"' then 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) end 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; begin - return cast(calloc(1, sizeof(Literal)) as pointer to Literal) + return cast(calloc(1, sizeof(Literal)): pointer to Literal) end 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 result: pointer to ConstantDefinition; 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); tokens^ := tokens^ + 2u; @@ -855,7 +855,7 @@ var result: pointer to Program, current_constant: pointer to pointer to ConstantDefinition; 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.count := 0u; @@ -867,7 +867,7 @@ begin while tokens_size^ > 0u and tokens^^.kind = TOKEN_IDENTIFIER do result^.constants.elements := cast( 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; result^.constants.count := result^.constants.count + 1u; @@ -887,7 +887,7 @@ var result: pointer to CommandLine; begin i := 1; - result := cast(malloc(sizeof(CommandLine)) as pointer to CommandLine); + result := cast(malloc(sizeof(CommandLine)): pointer to CommandLine); result^.tokenize := false; result^.syntax_tree := false; result^.input := nil;