Use array range beginning with one

This commit is contained in:
2025-07-17 11:44:42 +02:00
parent 34abb6b4f5
commit 32d4683315
4 changed files with 370 additions and 372 deletions

View File

@ -154,7 +154,9 @@ namespace elna::gcc
} }
else if (constant_expression != boolean_true_node) else if (constant_expression != boolean_true_node)
{ {
this->current_expression = call_built_in(call_location, "__builtin_trap", void_type_node); tree assert_expression = call_built_in(call_location, "__builtin_trap", void_type_node);
this->current_expression = build3(COND_EXPR, void_type_node, this->current_expression,
NULL_TREE, assert_expression);
} }
else else
{ {
@ -486,7 +488,6 @@ namespace elna::gcc
{ {
gcc_unreachable(); gcc_unreachable();
} }
if (left_type == elna_bool_type_node) if (left_type == elna_bool_type_node)
{ {
return build2_loc(expression_location, logical_code, elna_bool_type_node, left, right); return build2_loc(expression_location, logical_code, elna_bool_type_node, left, right);
@ -497,8 +498,7 @@ namespace elna::gcc
} }
else else
{ {
error_at(expression_location, error_at(expression_location, "Invalid operands of type '%s' and '%s' for operator %s",
"Invalid operands of type '%s' and '%s' for operator %s",
print_type(left_type).c_str(), print_type(right_type).c_str(), print_type(left_type).c_str(), print_type(right_type).c_str(),
elna::boot::print_binary_operator(expression->operation())); elna::boot::print_binary_operator(expression->operation()));
return error_mark_node; return error_mark_node;
@ -810,21 +810,18 @@ namespace elna::gcc
this->current_expression = error_mark_node; this->current_expression = error_mark_node;
return; return;
} }
if (this->current_expression != elna_word_type_node) tree offset = fold_convert(elna_word_type_node, this->current_expression);
{
this->current_expression = convert(elna_word_type_node, this->current_expression);
}
tree offset = build2(MINUS_EXPR, elna_word_type_node, this->current_expression, size_one_node);
if (TREE_CODE(TREE_TYPE(designator)) == ARRAY_TYPE) if (TREE_CODE(TREE_TYPE(designator)) == ARRAY_TYPE)
{ {
tree element_type = TREE_TYPE(TREE_TYPE(designator)); tree element_type = TREE_TYPE(TREE_TYPE(designator));
this->current_expression = build4_loc(location, this->current_expression = build4_loc(location,
ARRAY_REF, element_type, designator, offset, NULL_TREE, NULL_TREE); ARRAY_REF, element_type, designator, offset, size_one_node, NULL_TREE);
} }
else if (TREE_TYPE(designator) == elna_string_type_node) else if (TREE_TYPE(designator) == elna_string_type_node)
{ {
offset = build2(MINUS_EXPR, elna_word_type_node, offset, size_one_node);
tree string_ptr = build3_loc(location, COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node), tree string_ptr = build3_loc(location, COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
designator, elna_string_ptr_field_node, NULL_TREE); designator, elna_string_ptr_field_node, NULL_TREE);

View File

@ -21,7 +21,6 @@ along with GCC; see the file COPYING3. If not see
#include "function.h" #include "function.h"
#include "stor-layout.h" #include "stor-layout.h"
#include "fold-const.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
namespace elna::gcc namespace elna::gcc
@ -248,9 +247,8 @@ namespace elna::gcc
tree build_static_array_type(tree type, const std::uint64_t size) tree build_static_array_type(tree type, const std::uint64_t size)
{ {
tree lower_bound = build_int_cst_type(integer_type_node, 0);
tree upper_bound = build_int_cst_type(integer_type_node, size); tree upper_bound = build_int_cst_type(integer_type_node, size);
tree range_type = build_range_type(integer_type_node, lower_bound, upper_bound); tree range_type = build_range_type(integer_type_node, size_one_node, upper_bound);
return build_array_type(type, range_type); return build_array_type(type, range_type);
} }

View File

@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h" #include "tree.h"
#include "tree-iterator.h" #include "tree-iterator.h"
#include "stringpool.h" #include "stringpool.h"
#include "fold-const.h"
#include "elna/boot/ast.h" #include "elna/boot/ast.h"
#include "elna/boot/symbol.h" #include "elna/boot/symbol.h"
@ -97,6 +98,8 @@ namespace elna::gcc
tree fndecl_type = build_function_type(return_type, TYPE_ARG_TYPES(*builtin)); tree fndecl_type = build_function_type(return_type, TYPE_ARG_TYPES(*builtin));
tree builtin_addr = build1_loc(call_location, ADDR_EXPR, build_pointer_type(fndecl_type), *builtin); tree builtin_addr = build1_loc(call_location, ADDR_EXPR, build_pointer_type(fndecl_type), *builtin);
return build_call_nary(return_type, builtin_addr, sizeof...(Args), arguments...); tree argument_trees[sizeof...(Args)] = {arguments...};
return fold_build_call_array(return_type, builtin_addr, sizeof...(Args), argument_trees);
} }
} }

View File

@ -196,10 +196,10 @@ begin
end; end;
while value <> 0 do while value <> 0 do
digit := value % 10; digit := value % 10;
value := value / 10; value := value / 10;
buffer[n] := cast(cast('0': Int) + digit: 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
n := n + 1u; n := n + 1u;
@ -309,7 +309,7 @@ begin
if source_file^.index > source_file^.size then if source_file^.index > source_file^.size then
source_file^.size := fread(cast(@source_file^.buffer: Pointer), 1u, 1024u, source_file^.handle); source_file^.size := fread(cast(@source_file^.buffer: Pointer), 1u, 1024u, source_file^.handle);
source_file^.index := 1u source_file^.index := 1u
end; end;
return source_file^.size = 0u return source_file^.size = 0u
@ -366,41 +366,41 @@ var
successful: Bool; successful: Bool;
begin begin
if escape = 'n' then if escape = 'n' then
result^ := '\n'; result^ := '\n';
successful := true successful := true
elsif escape = 'a' then elsif escape = 'a' then
result^ := '\a'; result^ := '\a';
successful := true successful := true
elsif escape = 'b' then elsif escape = 'b' then
result^ := '\b'; result^ := '\b';
successful := true successful := true
elsif escape = 't' then elsif escape = 't' then
result^ := '\t'; result^ := '\t';
successful := true successful := true
elsif escape = 'f' then elsif escape = 'f' then
result^ := '\f'; result^ := '\f';
successful := true successful := true
elsif escape = 'r' then elsif escape = 'r' then
result^ := '\r'; result^ := '\r';
successful := true successful := true
elsif escape = 'v' then elsif escape = 'v' then
result^ := '\v'; result^ := '\v';
successful := true successful := true
elsif escape = '\\' then elsif escape = '\\' then
result^ := '\\'; result^ := '\\';
successful := true successful := true
elsif escape = '\'' then elsif escape = '\'' then
result^ := '\''; result^ := '\'';
successful := true successful := true
elsif escape = '"' then elsif escape = '"' then
result^ := '"'; result^ := '"';
successful := true successful := true
elsif escape = '?' then elsif escape = '?' then
result^ := '\?'; result^ := '\?';
successful := true successful := true
elsif escape = '0' then elsif escape = '0' then
result^ := '\0'; result^ := '\0';
successful := true successful := true
else else
successful := false successful := false
end; end;
@ -417,8 +417,8 @@ begin
if current = '\n' then if current = '\n' then
source_code_break(source_code) source_code_break(source_code)
end; end;
source_code_advance(source_code) source_code_advance(source_code)
end end
end; end;
@ -433,7 +433,7 @@ var
begin begin
while ~source_code_empty(source_code) & lexer_is_ident(source_code_head(source_code^)) do while ~source_code_empty(source_code) & lexer_is_ident(source_code_head(source_code^)) do
string_buffer_push(token_content, source_code_head(source_code^)); string_buffer_push(token_content, source_code_head(source_code^));
source_code_advance(source_code) source_code_advance(source_code)
end end
end; end;
@ -445,15 +445,15 @@ begin
while ~source_code_empty(source_code) & trailing < 2u do while ~source_code_empty(source_code) & trailing < 2u do
if source_code_head(source_code^) = '*' then if source_code_head(source_code^) = '*' then
string_buffer_push(token_content, '*'); string_buffer_push(token_content, '*');
trailing := 1u trailing := 1u
elsif source_code_head(source_code^) = ')' & trailing = 1u then elsif source_code_head(source_code^) = ')' & trailing = 1u then
string_buffer_pop(token_content, 1u); string_buffer_pop(token_content, 1u);
trailing := 2u trailing := 2u
else else
string_buffer_push(token_content, source_code_head(source_code^)); string_buffer_push(token_content, source_code_head(source_code^));
trailing := 0u trailing := 0u
end; end;
source_code_advance(source_code) source_code_advance(source_code)
end; end;
@ -471,9 +471,9 @@ begin
source_code_advance(source_code); source_code_advance(source_code);
successful := ~source_code_empty(source_code) & lexer_escape(source_code_head(source_code^), token_content) successful := ~source_code_empty(source_code) & lexer_escape(source_code_head(source_code^), token_content)
else else
token_content^ := source_code_head(source_code^); token_content^ := source_code_head(source_code^);
successful := true successful := true
end end
end; end;
if successful then if successful then
@ -524,64 +524,64 @@ var
current_token: Token; current_token: Token;
begin begin
if token_content = "if" then if token_content = "if" then
current_token.kind := TokenKind._if current_token.kind := TokenKind._if
elsif token_content = "then" then elsif token_content = "then" then
current_token.kind := TokenKind._then current_token.kind := TokenKind._then
elsif token_content = "else" then elsif token_content = "else" then
current_token.kind := TokenKind._else current_token.kind := TokenKind._else
elsif token_content = "elsif" then elsif token_content = "elsif" then
current_token.kind := TokenKind._elsif current_token.kind := TokenKind._elsif
elsif token_content = "while" then elsif token_content = "while" then
current_token.kind := TokenKind._while current_token.kind := TokenKind._while
elsif token_content = "do" then elsif token_content = "do" then
current_token.kind := TokenKind._do current_token.kind := TokenKind._do
elsif token_content = "proc" then elsif token_content = "proc" then
current_token.kind := TokenKind._proc current_token.kind := TokenKind._proc
elsif token_content = "begin" then elsif token_content = "begin" then
current_token.kind := TokenKind._begin current_token.kind := TokenKind._begin
elsif token_content = "end" then elsif token_content = "end" then
current_token.kind := TokenKind._end current_token.kind := TokenKind._end
elsif token_content = "extern" then elsif token_content = "extern" then
current_token.kind := TokenKind._extern current_token.kind := TokenKind._extern
elsif token_content = "const" then elsif token_content = "const" then
current_token.kind := TokenKind._const current_token.kind := TokenKind._const
elsif token_content = "var" then elsif token_content = "var" then
current_token.kind := TokenKind._var current_token.kind := TokenKind._var
elsif token_content = "case" then elsif token_content = "case" then
current_token.kind := TokenKind._case current_token.kind := TokenKind._case
elsif token_content = "of" then elsif token_content = "of" then
current_token.kind := TokenKind._of current_token.kind := TokenKind._of
elsif token_content = "type" then elsif token_content = "type" then
current_token.kind := TokenKind._type current_token.kind := TokenKind._type
elsif token_content = "record" then elsif token_content = "record" then
current_token.kind := TokenKind._record current_token.kind := TokenKind._record
elsif token_content = "union" then elsif token_content = "union" then
current_token.kind := TokenKind._union current_token.kind := TokenKind._union
elsif token_content = "true" then elsif token_content = "true" then
current_token.kind := TokenKind.boolean; current_token.kind := TokenKind.boolean;
current_token.value.boolean_value := true current_token.value.boolean_value := true
elsif token_content = "false" then elsif token_content = "false" then
current_token.kind := TokenKind.boolean; current_token.kind := TokenKind.boolean;
current_token.value.boolean_value := false current_token.value.boolean_value := false
elsif token_content = "nil" then elsif token_content = "nil" then
current_token.kind := TokenKind.null current_token.kind := TokenKind.null
elsif token_content = "or" then elsif token_content = "or" then
current_token.kind := TokenKind._or current_token.kind := TokenKind._or
elsif token_content = "return" then elsif token_content = "return" then
current_token.kind := TokenKind._return current_token.kind := TokenKind._return
elsif token_content = "cast" then elsif token_content = "cast" then
current_token.kind := TokenKind._cast current_token.kind := TokenKind._cast
elsif token_content = "defer" then elsif token_content = "defer" then
current_token.kind := TokenKind._defer current_token.kind := TokenKind._defer
elsif token_content = "program" then elsif token_content = "program" then
current_token.kind := TokenKind._program current_token.kind := TokenKind._program
elsif token_content = "module" then elsif token_content = "module" then
current_token.kind := TokenKind._module current_token.kind := TokenKind._module
elsif token_content = "import" then elsif token_content = "import" then
current_token.kind := TokenKind._import current_token.kind := TokenKind._import
else else
current_token.kind := TokenKind.identifier; current_token.kind := TokenKind.identifier;
current_token.value.string := string_dup(token_content) current_token.value.string := string_dup(token_content)
end; end;
return current_token return current_token
@ -611,162 +611,162 @@ begin
lexer_identifier(@source_code, token_buffer); lexer_identifier(@source_code, token_buffer);
current_token := lexer_categorize(string_buffer_clear(token_buffer)) current_token := lexer_categorize(string_buffer_clear(token_buffer))
elsif first_char = '#' then elsif first_char = '#' then
source_code_advance(@source_code); source_code_advance(@source_code);
lexer_identifier(@source_code, token_buffer); lexer_identifier(@source_code, token_buffer);
current_token.kind := TokenKind.trait; current_token.kind := TokenKind.trait;
current_token.value.string := string_dup(string_buffer_clear(token_buffer)) current_token.value.string := string_dup(string_buffer_clear(token_buffer))
elsif is_digit(first_char) then elsif is_digit(first_char) then
lexer_number(@source_code, @current_token.value.int_value); lexer_number(@source_code, @current_token.value.int_value);
if source_code_expect(@source_code, 'u') then if source_code_expect(@source_code, 'u') then
current_token.kind := TokenKind.word; current_token.kind := TokenKind.word;
source_code_advance(@source_code) source_code_advance(@source_code)
else else
current_token.kind := TokenKind.integer current_token.kind := TokenKind.integer
end end
elsif first_char = '(' then elsif first_char = '(' then
source_code_advance(@source_code); source_code_advance(@source_code);
if source_code_empty(@source_code) then if source_code_empty(@source_code) then
current_token.kind := TokenKind.left_paren current_token.kind := TokenKind.left_paren
elsif source_code_head(source_code) = '*' then elsif source_code_head(source_code) = '*' then
source_code_advance(@source_code); source_code_advance(@source_code);
if lexer_comment(@source_code, token_buffer) then if lexer_comment(@source_code, token_buffer) then
current_token.value.string := string_dup(string_buffer_clear(token_buffer)); current_token.value.string := string_dup(string_buffer_clear(token_buffer));
current_token.kind := TokenKind.comment current_token.kind := TokenKind.comment
else else
current_token.kind := TokenKind.unknown current_token.kind := TokenKind.unknown
end end
else else
current_token.kind := TokenKind.left_paren current_token.kind := TokenKind.left_paren
end end
elsif first_char = ')' then elsif first_char = ')' then
current_token.kind := TokenKind.right_paren; current_token.kind := TokenKind.right_paren;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = '\'' then elsif first_char = '\'' then
source_code_advance(@source_code); source_code_advance(@source_code);
if lexer_character(@source_code, @current_token.value.char_value) & source_code_expect(@source_code, '\'') then if lexer_character(@source_code, @current_token.value.char_value) & source_code_expect(@source_code, '\'') then
current_token.kind := TokenKind.character; current_token.kind := TokenKind.character;
source_code_advance(@source_code) source_code_advance(@source_code)
else else
current_token.kind := TokenKind.unknown current_token.kind := TokenKind.unknown
end end
elsif first_char = '"' then elsif first_char = '"' then
source_code_advance(@source_code); source_code_advance(@source_code);
if lexer_string(@source_code, token_buffer) then if lexer_string(@source_code, token_buffer) then
current_token.kind := TokenKind.string; current_token.kind := TokenKind.string;
current_token.value.string := string_dup(string_buffer_clear(token_buffer)) current_token.value.string := string_dup(string_buffer_clear(token_buffer))
else else
current_token.kind := TokenKind.unknown current_token.kind := TokenKind.unknown
end end
elsif first_char = '[' then elsif first_char = '[' then
current_token.kind := TokenKind.left_square; current_token.kind := TokenKind.left_square;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = ']' then elsif first_char = ']' then
current_token.kind := TokenKind.right_square; current_token.kind := TokenKind.right_square;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = '>' then elsif first_char = '>' then
source_code_advance(@source_code); source_code_advance(@source_code);
if source_code_empty(@source_code) then if source_code_empty(@source_code) then
current_token.kind := TokenKind.greater_than current_token.kind := TokenKind.greater_than
elsif source_code_head(source_code) = '=' then elsif source_code_head(source_code) = '=' then
current_token.kind := TokenKind.greater_equal; current_token.kind := TokenKind.greater_equal;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif source_code_head(source_code) = '>' then elsif source_code_head(source_code) = '>' then
current_token.kind := TokenKind.shift_right; current_token.kind := TokenKind.shift_right;
source_code_advance(@source_code) source_code_advance(@source_code)
else else
current_token.kind := TokenKind.greater_than current_token.kind := TokenKind.greater_than
end end
elsif first_char = '<' then elsif first_char = '<' then
source_code_advance(@source_code); source_code_advance(@source_code);
if source_code_empty(@source_code) then
current_token.kind := TokenKind.less_than
elsif source_code_head(source_code) = '=' then
current_token.kind := TokenKind.less_equal;
source_code_advance(@source_code)
elsif source_code_head(source_code) = '<' then
current_token.kind := TokenKind.shift_left;
source_code_advance(@source_code)
elsif source_code_head(source_code) = '>' then
current_token.kind := TokenKind.not_equal;
source_code_advance(@source_code)
else
current_token.kind := TokenKind.less_than
end
elsif first_char = '=' then
current_token.kind := TokenKind.equal;
source_code_advance(@source_code)
elsif first_char = ';' then
current_token.kind := TokenKind.semicolon;
source_code_advance(@source_code)
elsif first_char = '.' then
current_token.kind := TokenKind.dot;
source_code_advance(@source_code)
elsif first_char = ',' then
current_token.kind := TokenKind.comma;
source_code_advance(@source_code)
elsif first_char = '+' then
current_token.kind := TokenKind.plus;
source_code_advance(@source_code)
elsif first_char = '-' then
source_code_advance(@source_code);
if source_code_empty(@source_code) then if source_code_empty(@source_code) then
current_token.kind := TokenKind.minus current_token.kind := TokenKind.less_than
elsif source_code_head(source_code) = '>' then elsif source_code_head(source_code) = '=' then
current_token.kind := TokenKind.arrow; current_token.kind := TokenKind.less_equal;
source_code_advance(@source_code) source_code_advance(@source_code)
else elsif source_code_head(source_code) = '<' then
current_token.kind := TokenKind.minus current_token.kind := TokenKind.shift_left;
end source_code_advance(@source_code)
elsif first_char = '*' then elsif source_code_head(source_code) = '>' then
current_token.kind := TokenKind.multiplication; current_token.kind := TokenKind.not_equal;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = '/' then else
current_token.kind := TokenKind.division; current_token.kind := TokenKind.less_than
source_code_advance(@source_code) end
elsif first_char = '%' then elsif first_char = '=' then
current_token.kind := TokenKind.remainder; current_token.kind := TokenKind.equal;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = ':' then elsif first_char = ';' then
source_code_advance(@source_code); current_token.kind := TokenKind.semicolon;
source_code_advance(@source_code)
elsif first_char = '.' then
current_token.kind := TokenKind.dot;
source_code_advance(@source_code)
elsif first_char = ',' then
current_token.kind := TokenKind.comma;
source_code_advance(@source_code)
elsif first_char = '+' then
current_token.kind := TokenKind.plus;
source_code_advance(@source_code)
elsif first_char = '-' then
source_code_advance(@source_code);
if source_code_empty(@source_code) then if source_code_empty(@source_code) then
current_token.kind := TokenKind.colon current_token.kind := TokenKind.minus
elsif source_code_head(source_code) = '=' then elsif source_code_head(source_code) = '>' then
current_token.kind := TokenKind.assignment; current_token.kind := TokenKind.arrow;
source_code_advance(@source_code) source_code_advance(@source_code)
else else
current_token.kind := TokenKind.colon current_token.kind := TokenKind.minus
end end
elsif first_char = '*' then
current_token.kind := TokenKind.multiplication;
source_code_advance(@source_code)
elsif first_char = '/' then
current_token.kind := TokenKind.division;
source_code_advance(@source_code)
elsif first_char = '%' then
current_token.kind := TokenKind.remainder;
source_code_advance(@source_code)
elsif first_char = ':' then
source_code_advance(@source_code);
if source_code_empty(@source_code) then
current_token.kind := TokenKind.colon
elsif source_code_head(source_code) = '=' then
current_token.kind := TokenKind.assignment;
source_code_advance(@source_code)
else
current_token.kind := TokenKind.colon
end
elsif first_char = '^' then elsif first_char = '^' then
current_token.kind := TokenKind.hat; current_token.kind := TokenKind.hat;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = '@' then elsif first_char = '@' then
current_token.kind := TokenKind.at; current_token.kind := TokenKind.at;
source_code_advance(@source_code) source_code_advance(@source_code)
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 elsif first_char = '&' then
current_token.kind := TokenKind.and; current_token.kind := TokenKind.and;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = '~' then elsif first_char = '~' then
current_token.kind := TokenKind.not; current_token.kind := TokenKind.not;
source_code_advance(@source_code) source_code_advance(@source_code)
elsif first_char = '|' then elsif first_char = '|' then
current_token.kind := TokenKind.pipe; current_token.kind := TokenKind.pipe;
source_code_advance(@source_code) 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)
end; end;
return current_token return current_token
@ -785,16 +785,16 @@ begin
lexer_spaces(@source_code); lexer_spaces(@source_code);
while ~source_code_empty(@source_code) do while ~source_code_empty(@source_code) do
current_token := lexer_next(source_code, @token_buffer); current_token := lexer_next(source_code, @token_buffer);
if current_token.kind <> TokenKind.unknown then if current_token.kind <> TokenKind.unknown then
lexer_add_token(@lexer, current_token); lexer_add_token(@lexer, current_token);
lexer_spaces(@source_code) lexer_spaces(@source_code)
else else
write_s("Lexical analysis error on \""); write_s("Lexical analysis error on \"");
write_c(source_code_head(source_code)); write_c(source_code_head(source_code));
write_s("\".\n") write_s("\".\n")
end end
end; end;
return lexer return lexer
@ -824,12 +824,12 @@ begin
elsif strcmp(parameter^, "--parse\0".ptr) = 0 then elsif strcmp(parameter^, "--parse\0".ptr) = 0 then
result^.parse := true result^.parse := true
elsif parameter^^ <> '-' then elsif parameter^^ <> '-' then
if result^.input <> nil then if result^.input <> nil then
write_s("Fatal error: Only one source file can be given.\n"); write_s("Fatal error: Only one source file can be given.\n");
result := nil result := nil
else else
result^.input := parameter^ result^.input := parameter^
end end
else else
write_s("Fatal error: Unknown command line options: "); write_s("Fatal error: Unknown command line options: ");
@ -843,7 +843,7 @@ begin
end; end;
if result <> nil & result^.input = nil then if result <> nil & result^.input = nil then
write_s("Fatal error: no input files.\n"); write_s("Fatal error: no input files.\n");
result := nil result := nil
end; end;
return result return result
@ -863,151 +863,151 @@ begin
current_token := tokens + i; current_token := tokens + i;
case current_token^.kind of case current_token^.kind of
TokenKind._if: TokenKind._if:
write_s("IF") write_s("IF")
| TokenKind._then: | TokenKind._then:
write_s("THEN") write_s("THEN")
| TokenKind._else: | TokenKind._else:
write_s("ELSE") write_s("ELSE")
| TokenKind._elsif: | TokenKind._elsif:
write_s("ELSIF") write_s("ELSIF")
| TokenKind._while: | TokenKind._while:
write_s("WHILE") write_s("WHILE")
| TokenKind._do: | TokenKind._do:
write_s("DO") write_s("DO")
| TokenKind._proc: | TokenKind._proc:
write_s("PROC") write_s("PROC")
| TokenKind._begin: | TokenKind._begin:
write_s("BEGIN") write_s("BEGIN")
| TokenKind._end: | TokenKind._end:
write_s("END") write_s("END")
| TokenKind._extern: | TokenKind._extern:
write_s("EXTERN") write_s("EXTERN")
| TokenKind._const: | TokenKind._const:
write_s("CONST") write_s("CONST")
| TokenKind._var: | TokenKind._var:
write_s("VAR") write_s("VAR")
| TokenKind._case: | TokenKind._case:
write_s("CASE") write_s("CASE")
| TokenKind._of: | TokenKind._of:
write_s("OF") write_s("OF")
| TokenKind._type: | TokenKind._type:
write_s("TYPE") write_s("TYPE")
| TokenKind._record: | TokenKind._record:
write_s("RECORD") write_s("RECORD")
| TokenKind._union: | TokenKind._union:
write_s("UNION") write_s("UNION")
| TokenKind.pipe: | TokenKind.pipe:
write_s("|") write_s("|")
| TokenKind.to: | TokenKind.to:
write_s("TO") write_s("TO")
| TokenKind.boolean: | TokenKind.boolean:
write_s("BOOLEAN<"); write_s("BOOLEAN<");
write_b(current_token^.value.boolean_value); write_b(current_token^.value.boolean_value);
write_c('>') write_c('>')
| TokenKind.null: | TokenKind.null:
write_s("NIL") write_s("NIL")
| TokenKind.and: | TokenKind.and:
write_s("&") write_s("&")
| TokenKind._or: | TokenKind._or:
write_s("OR") write_s("OR")
| TokenKind.not: | TokenKind.not:
write_s("~") write_s("~")
| TokenKind._return: | TokenKind._return:
write_s("RETURN") write_s("RETURN")
| TokenKind._cast: | TokenKind._cast:
write_s("CAST") write_s("CAST")
| TokenKind.shift_left: | TokenKind.shift_left:
write_s("<<") write_s("<<")
| TokenKind.shift_right: | TokenKind.shift_right:
write_s(">>") write_s(">>")
| TokenKind.identifier: | TokenKind.identifier:
write_c('<'); write_c('<');
write_s(current_token^.value.string); write_s(current_token^.value.string);
write_c('>') write_c('>')
| TokenKind.trait: | TokenKind.trait:
write_c('#'); write_c('#');
write_s(current_token^.value.string) write_s(current_token^.value.string)
| TokenKind.left_paren: | TokenKind.left_paren:
write_s("(") write_s("(")
| TokenKind.right_paren: | TokenKind.right_paren:
write_s(")") write_s(")")
| TokenKind.left_square: | TokenKind.left_square:
write_s("[") write_s("[")
| TokenKind.right_square: | TokenKind.right_square:
write_s("]") write_s("]")
| TokenKind.greater_equal: | TokenKind.greater_equal:
write_s(">=") write_s(">=")
| TokenKind.less_equal: | TokenKind.less_equal:
write_s("<=") write_s("<=")
| TokenKind.greater_than: | TokenKind.greater_than:
write_s(">") write_s(">")
| TokenKind.less_than: | TokenKind.less_than:
write_s("<") write_s("<")
| TokenKind.equal: | TokenKind.equal:
write_s("=") write_s("=")
| TokenKind.not_equal: | TokenKind.not_equal:
write_s("<>") write_s("<>")
| TokenKind.semicolon: | TokenKind.semicolon:
write_c(';') write_c(';')
| TokenKind.dot: | TokenKind.dot:
write_c('.') write_c('.')
| TokenKind.comma: | TokenKind.comma:
write_c(',') write_c(',')
| TokenKind.plus: | TokenKind.plus:
write_c('+') write_c('+')
| TokenKind.minus: | TokenKind.minus:
write_c('-') write_c('-')
| TokenKind.multiplication: | TokenKind.multiplication:
write_c('*') write_c('*')
| TokenKind.division: | TokenKind.division:
write_c('/') write_c('/')
| TokenKind.remainder: | TokenKind.remainder:
write_c('%') write_c('%')
| TokenKind.assignment: | TokenKind.assignment:
write_s(":=") write_s(":=")
| TokenKind.colon: | TokenKind.colon:
write_c(':') write_c(':')
| TokenKind.hat: | TokenKind.hat:
write_c('^') write_c('^')
| TokenKind.at: | TokenKind.at:
write_c('@') write_c('@')
| TokenKind.comment: | TokenKind.comment:
write_s("(* COMMENT *)") write_s("(* COMMENT *)")
| TokenKind.integer: | TokenKind.integer:
write_c('<'); write_c('<');
write_i(current_token^.value.int_value); write_i(current_token^.value.int_value);
write_c('>') write_c('>')
| TokenKind.word: | TokenKind.word:
write_c('<'); write_c('<');
write_i(current_token^.value.int_value); write_i(current_token^.value.int_value);
write_s("u>") write_s("u>")
| TokenKind.character: | TokenKind.character:
write_c('<'); write_c('<');
write_i(cast(current_token^.value.char_value: Int)); write_i(cast(current_token^.value.char_value: Int));
write_s("c>") write_s("c>")
| TokenKind.string: | TokenKind.string:
write_s("\"...\"") write_s("\"...\"")
| TokenKind._defer: | TokenKind._defer:
write_s("DEFER") write_s("DEFER")
| TokenKind.exclamation: | TokenKind.exclamation:
write_c('!') write_c('!')
| TokenKind.arrow: | TokenKind.arrow:
write_s("->") write_s("->")
| TokenKind._program: | TokenKind._program:
write_s("PROGRAM") write_s("PROGRAM")
| TokenKind._module: | TokenKind._module:
write_s("MODULE") write_s("MODULE")
| TokenKind._import: | TokenKind._import:
write_s("IMPORT") write_s("IMPORT")
else else
write_s("UNKNOWN<"); write_s("UNKNOWN<");
write_i(cast(current_token^.kind: Int)); write_i(cast(current_token^.kind: Int));
write_c('>') write_c('>')
end; end;
write_c(' '); write_c(' ');
i := i + 1u i := i + 1u
end; end;
write_c('\n') write_c('\n')
end; end;
@ -1052,22 +1052,22 @@ begin
if return_code = 0 then if return_code = 0 then
source_file := read_source(command_line^.input); source_file := read_source(command_line^.input);
if source_file = nil then if source_file = nil then
perror(command_line^.input); perror(command_line^.input);
return_code := 3 return_code := 3
end end
end; end;
if return_code = 0 then if return_code = 0 then
defer defer
fclose(source_file^.handle) fclose(source_file^.handle)
end; end;
source_code.position := TextLocation(1u, 1u); source_code.position := TextLocation(1u, 1u);
source_code.input := cast(source_file: Pointer); source_code.input := cast(source_file: Pointer);
source_code.empty := source_file_empty; source_code.empty := source_file_empty;
source_code.head := source_file_head; source_code.head := source_file_head;
source_code.advance := source_file_advance; source_code.advance := source_file_advance;
return_code := compile_in_stages(command_line, source_code) return_code := compile_in_stages(command_line, source_code)
end; end;