Allow extern variables
This commit is contained in:
		
							
								
								
									
										12
									
								
								boot/ast.cc
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								boot/ast.cc
									
									
									
									
									
								
							| @@ -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; | ||||
|   | ||||
| @@ -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 }; | ||||
|   | ||||
| @@ -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()); | ||||
|         } | ||||
|   | ||||
| @@ -774,6 +774,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) | ||||
|   | ||||
| @@ -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 }; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user