Allow extern variables

This commit is contained in:
2025-08-20 21:47:50 +02:00
parent 0c2a396320
commit 809e41bcc3
8 changed files with 45 additions and 12 deletions

View File

@@ -415,11 +415,23 @@ namespace elna::boot
{
}
variable_declaration::variable_declaration(const struct position position,
std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type,
std::monostate)
: node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), is_extern(true)
{
}
void variable_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
bool variable_declaration::has_initializer() const
{
return this->is_extern || this->body != nullptr;
}
type_expression& variable_declaration::variable_type()
{
return *m_variable_type;

View File

@@ -508,6 +508,12 @@ variable_declaration:
std::shared_ptr<boot::type_expression> shared_type{ $3 };
$$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type);
}
| identifier_definitions ":" type_expression ":=" "extern" ";"
{
std::shared_ptr<boot::type_expression> shared_type{ $3 };
$$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type,
std::monostate{});
}
| identifier_definitions ":" type_expression ":=" expression ";"
{
std::shared_ptr<boot::type_expression> shared_type{ $3 };

View File

@@ -609,7 +609,7 @@ namespace elna::boot
void declaration_visitor::visit(variable_declaration *declaration)
{
if (declaration->body != nullptr && declaration->identifiers.size() > 1)
if (declaration->has_initializer() && declaration->identifiers.size() > 1)
{
add_error<variable_initializer_error>(this->input_file, declaration->position());
}

View File

@@ -108,7 +108,7 @@ namespace elna::gcc
if (!is_assignable_from(unqualified_field, this->current_expression))
{
error_at(argument_location,
"cannot assign value of type '%s' to variable of type '%s'",
"Cannot assign value of type '%s' to variable of type '%s'",
print_type(TREE_TYPE(this->current_expression)).c_str(),
print_type(TREE_TYPE(record_fields)).c_str());
this->current_expression = error_mark_node;
@@ -756,6 +756,7 @@ namespace elna::gcc
get_identifier(variable_identifier.identifier.c_str()), this->current_expression);
bool result = this->symbols->enter(variable_identifier.identifier, declaration_tree);
// Set initializer if given.
if (declaration->body != nullptr)
{
declaration->body->accept(this);
@@ -774,6 +775,7 @@ namespace elna::gcc
{
DECL_INITIAL(declaration_tree) = elna_pointer_nil_node;
}
DECL_EXTERNAL(declaration_tree) = declaration->is_extern;
TREE_PUBLIC(declaration_tree) = variable_identifier.exported;
this->current_expression = NULL_TREE;
if (!result)

View File

@@ -348,12 +348,18 @@ namespace elna::boot
variable_declaration(const struct position position,
std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type,
expression *body = nullptr);
variable_declaration(const struct position position,
std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type,
std::monostate);
void accept(parser_visitor *visitor) override;
bool has_initializer() const;
const std::vector<identifier_definition> identifiers;
type_expression& variable_type();
expression *const body;
expression *const body{ nullptr };
const bool is_extern{ false };
};
/**

View File

@@ -16,6 +16,7 @@ proc write*(fd: Int, buf: Pointer, Word: Int) -> Int; extern;
proc write_s*(value: String);
begin
(* fwrite(cast(value.ptr: Pointer), value.length, 1u, stdout) *)
write(1, cast(value.ptr: Pointer), cast(value.length: Int))
end;

View File

@@ -6,14 +6,20 @@ module;
type
FILE* = record end;
proc fopen(pathname: ^Char, mode: ^Char) -> ^FILE; extern;
proc fclose(stream: ^FILE) -> Int; extern;
proc fseek(stream: ^FILE, off: Int, whence: Int) -> Int; extern;
proc rewind(stream: ^FILE); extern;
proc ftell(stream: ^FILE) -> Int; extern;
proc fflush(stream: ^FILE) -> Int; extern;
var
stdin*: ^FILE := extern;
stdout*: ^FILE := extern;
stderr*: ^FILE := extern;
proc fread(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word; extern;
proc fopen*(pathname: ^Char, mode: ^Char) -> ^FILE; extern;
proc fclose*(stream: ^FILE) -> Int; extern;
proc fseek*(stream: ^FILE, off: Int, whence: Int) -> Int; extern;
proc rewind*(stream: ^FILE); extern;
proc ftell*(stream: ^FILE) -> Int; extern;
proc fflush*(stream: ^FILE) -> Int; extern;
proc fread*(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word; extern;
proc fwrite*(ptr: Pointer, size: Word, nitems: Word, stream: ^FILE) -> Word; extern;
proc perror(s: ^Char); extern;

View File

@@ -624,7 +624,7 @@ end;
proc parse(tokens: ^Token, tokens_size: Word);
var
current_token: ^Token;
i: Word := 0;
i: Word := 0u;
begin
while i < tokens_size do
current_token := tokens + i;