summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-10-25 21:23:47 +0200
committerEugen Wissner <belka@caraus.de>2025-10-25 21:23:47 +0200
commit37a698da91e53f54ee55484e98bb6dfa1d12b9c6 (patch)
tree08141a3cfc4fe84f0d9cdd27daba954359973b40
parentb20632245560b70f0605c0df1e56d766f22b4938 (diff)
downloadelna-37a698da91e53f54ee55484e98bb6dfa1d12b9c6.tar.gz
Allocate bigger memory regions dynamically
-rw-r--r--boot/stage15.elna272
1 files changed, 180 insertions, 92 deletions
diff --git a/boot/stage15.elna b/boot/stage15.elna
index d317c5c..d3e157a 100644
--- a/boot/stage15.elna
+++ b/boot/stage15.elna
@@ -150,22 +150,19 @@ type
type_declaration,
module_declaration
);
- InfoKind = (type_info, parameter_info, temporary_info);
+ InfoKind = (type_info, parameter_info, temporary_info, procedure_info);
TypeKind = (primitive, enumeration);
var
- source_code: Array;
- compiler_strings: Array;
symbol_table_global: Array;
- symbol_table_local: Array;
+ compiler_strings: Array;
classification: Array;
- (* To reserve memory just add the value of needed bytes to the memory_free_pointer variable. *)
- memory: Array;
-
+ source_code: Word;
compiler_strings_position: Word;
compiler_strings_length: Word;
label_counter: Word;
+ symbol_table_store: Word;
(* Points to a segment of free memory. *)
memory_free_pointer: Word;
@@ -246,6 +243,15 @@ proc _read_file(buffer: Word, size: Word);
end;
(**
+ * MAP_ANONYMOUS is 32.
+ * PROT_READ | PORT_WRITE is (1 | 2).
+ * MAP_ANONYMOUS | MAP_PRIVATE is (32 | 2)
+ *)
+proc _mmap(length: Word);
+ return _syscall(0, length, 1 or 2, 32 or 2, -1, 0, 222)
+end;
+
+(**
* Writes to the standard output.
*
* Parameters:
@@ -363,7 +369,6 @@ begin
rhs := character <= 'Z';
return lhs & rhs
-
end;
(**
@@ -537,9 +542,10 @@ var
integer_token: Word;
integer_length: Word;
result: Word;
+ literal_size: Word;
begin
- result := memory_free_pointer;
- memory_free_pointer := memory_free_pointer + 12;
+ literal_size := _integer_literal_node_size();
+ result := _allocate(literal_size);
integer_token := _lexer_global_get_start();
integer_length := _lexer_global_get_end();
@@ -568,6 +574,10 @@ begin
_write_c('\n')
end;
+proc _character_literal_node_size();
+ return 12
+end;
+
proc _character_literal_node_get_value(this: Word);
begin
this := this + 4;
@@ -597,9 +607,10 @@ var
character: Word;
character_length: Word;
result: Word;
+ literal_size: Word;
begin
- result := memory_free_pointer;
- memory_free_pointer := memory_free_pointer + 12;
+ literal_size := _character_literal_node_size();
+ result := _allocate(literal_size);
character := _lexer_global_get_start();
character_length := _lexer_global_get_end();
@@ -685,7 +696,7 @@ begin
return result
end;
-proc _compile_variable_expression(variable_expression: Word);
+proc _compile_variable_expression(variable_expression: Word, symbol_table: Word);
var
name: Word;
name_token: Word;
@@ -694,7 +705,7 @@ begin
name := _variable_expression_get_name(variable_expression);
name_token := _variable_expression_get_length(variable_expression);
- lookup_result := _symbol_table_lookup(@symbol_table_local, name, name_token);
+ lookup_result := _symbol_table_lookup(symbol_table, name, name_token);
if lookup_result <> 0 then
_compile_local_designator(lookup_result)
else
@@ -841,7 +852,7 @@ begin
return simple_expression
end;
-proc _compile_simple_expression(parser_node: Word);
+proc _compile_simple_expression(parser_node: Word, symbol_table: Word);
var
is_address: Word;
node_kind: Word;
@@ -856,7 +867,7 @@ begin
elsif node_kind = NodeKind.integer_literal then
_compile_integer_literal(parser_node)
else
- _compile_variable_expression(parser_node);
+ _compile_variable_expression(parser_node, symbol_table);
is_address := 1
end;
return is_address
@@ -926,7 +937,7 @@ begin
return result
end;
-proc _compile_unary_expression(parser_node: Word);
+proc _compile_unary_expression(parser_node: Word, symbol_table: Word);
var
current_character: Word;
token_kind: Word;
@@ -947,8 +958,8 @@ begin
end;
if operator = '@' then
- _compile_designator(operand)
- elsif _compile_designator(operand) then
+ _compile_designator(operand, symbol_table)
+ elsif _compile_designator(operand, symbol_table) then
_write_z("\tlw t0, (t0) # Designator is an address.\n\0")
end;
if operator = '-' then
@@ -1067,7 +1078,7 @@ begin
return result
end;
-proc _compile_binary_expression(parser_node: Word);
+proc _compile_binary_expression(parser_node: Word, symbol_table: Word);
var
token_kind: Word;
expression_kind: Word;
@@ -1076,17 +1087,17 @@ begin
expression_kind := _node_get_kind(parser_node);
if expression_kind <> NodeKind.binary_expression then
- _compile_unary_expression(parser_node)
+ _compile_unary_expression(parser_node, symbol_table)
else
token_kind := _binary_expression_get_operator(parser_node);
operand_node := _binary_expression_get_lhs(parser_node);
- _compile_unary_expression(operand_node);
+ _compile_unary_expression(operand_node, symbol_table);
(* Save the value of the left expression on the stack. *)
_write_z("\tsw t0, 64(sp)\n\0");
operand_node := _binary_expression_get_rhs(parser_node);
- _compile_unary_expression(operand_node);
+ _compile_unary_expression(operand_node, symbol_table);
(* Load the left expression from the stack; *)
_write_z("\tlw t1, 64(sp)\n\0");
@@ -1122,14 +1133,6 @@ begin
end
end;
-proc _compile_expression();
-var
- parser_node: Word;
-begin
- parser_node := _parse_binary_expression();
- _compile_binary_expression(parser_node)
-end;
-
(* 4 bytes node kind + 4 byte pointer to variable expression + 4 * 7 for arguments. *)
proc _call_size();
return 44
@@ -1206,7 +1209,7 @@ begin
return result
end;
-proc _compile_call(parsed_call: Word);
+proc _compile_call(parsed_call: Word, symbol_table: Word);
var
name_length: Word;
name: Word;
@@ -1225,7 +1228,7 @@ begin
if parsed_expression = 0 then
goto compile_call_finalize
else
- _compile_binary_expression(parsed_expression);
+ _compile_binary_expression(parsed_expression, symbol_table);
(* Save the argument on the stack. *)
_write_z("\tsw t0, \0");
@@ -1553,7 +1556,7 @@ begin
return result
end;
-proc _compile_designator(parser_node: Word);
+proc _compile_designator(parser_node: Word, symbol_table: Word);
var
name_token: Word;
lookup_result: Word;
@@ -1567,17 +1570,17 @@ begin
if node_kind = NodeKind.dereference_expression then
parser_node := _dereference_expression_get_pointer(parser_node);
- _compile_simple_expression(parser_node);
+ _compile_simple_expression(parser_node, symbol_table);
_write_z("\tlw t0, (t0)\n\0")
elsif node_kind = NodeKind.field_access_expression then
_compile_enumeration_value(parser_node);
is_address := 0
elsif node_kind = NodeKind.call then
- _compile_call(parser_node);
+ _compile_call(parser_node, symbol_table);
_write_z("\tmv t0, a0\n\0");
is_address := 0
else
- is_address := _compile_simple_expression(parser_node)
+ is_address := _compile_simple_expression(parser_node, symbol_table)
end;
return is_address
end;
@@ -1634,19 +1637,19 @@ begin
return result
end;
-proc _compile_assignment_statement(parser_tree: Word);
+proc _compile_assignment_statement(parser_tree: Word, symbol_table: Word);
var
current_expression: Word;
begin
current_expression := _assignment_statement_get_assignee(parser_tree);
- _compile_designator(current_expression);
+ _compile_designator(current_expression, symbol_table);
(* Save the assignee address on the stack. *)
_write_z("\tsw t0, 60(sp)\n\0");
(* Compile the assignment. *)
current_expression := _assignment_statement_get_assignment(parser_tree);
- _compile_binary_expression(current_expression);
+ _compile_binary_expression(current_expression, symbol_table);
_write_z("\tlw t1, 60(sp)\n\tsw t0, (t1)\n\0")
end;
@@ -1691,12 +1694,12 @@ begin
return result
end;
-proc _compile_return_statement(parser_node: Word);
+proc _compile_return_statement(parser_node: Word, symbol_table: Word);
var
return_expression: Word;
begin
return_expression := _return_statement_get_returned(parser_node);
- _compile_binary_expression(return_expression);
+ _compile_binary_expression(return_expression, symbol_table);
_write_z("\tmv a0, t0\n\0")
end;
@@ -1739,14 +1742,14 @@ begin
return result
end;
-proc _compile_conditional_statements(parser_node: Word, after_end_label: Word);
+proc _compile_conditional_statements(parser_node: Word, after_end_label: Word, symbol_table: Word);
var
condition_label: Word;
current_node: Word;
begin
(* Compile condition. *)
current_node := _conditional_statements_get_condition(parser_node);
- _compile_binary_expression(current_node);
+ _compile_binary_expression(current_node, symbol_table);
(* condition_label is the label in front of the next elsif condition or end. *)
condition_label := label_counter;
@@ -1757,7 +1760,7 @@ begin
_write_c('\n');
current_node := _conditional_statements_get_statements(parser_node);
- _compile_statements(current_node);
+ _compile_statements(current_node, symbol_table);
_write_z("\tj \0");
_write_label(after_end_label);
@@ -1937,7 +1940,7 @@ begin
return first_statement
end;
-proc _compile_statements(parser_node: Word);
+proc _compile_statements(parser_node: Word, symbol_table: Word);
var
current_statement: Word;
begin
@@ -1945,13 +1948,13 @@ begin
.compile_statements_loop;
if current_statement <> 0 then
- _compile_statement(current_statement);
+ _compile_statement(current_statement, symbol_table);
current_statement := _statement_get_next(current_statement);
goto compile_statements_loop
end
end;
-proc _compile_if_statement(parser_node: Word);
+proc _compile_if_statement(parser_node: Word, symbol_table: Word);
var
current_node: Word;
after_end_label: Word;
@@ -1961,25 +1964,25 @@ begin
label_counter := label_counter + 1;
current_node := _if_statement_get_conditionals(parser_node);
- _compile_conditional_statements(current_node, after_end_label);
+ _compile_conditional_statements(current_node, after_end_label, symbol_table);
.compile_if_statement_loop;
current_node := _conditional_statements_get_next(current_node);
if current_node <> 0 then
- _compile_conditional_statements(current_node, after_end_label);
+ _compile_conditional_statements(current_node, after_end_label, symbol_table);
goto compile_if_statement_loop
end;
current_node := _if_statement_get_else(parser_node);
if current_node <> 0 then
- _compile_statements(current_node)
+ _compile_statements(current_node, symbol_table)
end;
_write_label(after_end_label);
_write_z(":\n\0")
end;
-proc _compile_statement(parser_node: Word);
+proc _compile_statement(parser_node: Word, symbol_table: Word);
var
statement_kind: Word;
begin
@@ -1988,15 +1991,15 @@ begin
if statement_kind = NodeKind.goto_statement then
_compile_goto_statement(parser_node)
elsif statement_kind = NodeKind.if_statement then
- _compile_if_statement(parser_node)
+ _compile_if_statement(parser_node, symbol_table)
elsif statement_kind = NodeKind.return_statement then
- _compile_return_statement(parser_node)
+ _compile_return_statement(parser_node, symbol_table)
elsif statement_kind = NodeKind.label_declaration then
_compile_label_declaration(parser_node)
elsif statement_kind = NodeKind.call then
- _compile_call(parser_node)
+ _compile_call(parser_node, symbol_table)
elsif statement_kind = NodeKind.assignment_statement then
- _compile_assignment_statement(parser_node)
+ _compile_assignment_statement(parser_node, symbol_table)
end
end;
@@ -2123,9 +2126,11 @@ var
member_count: Word;
result: Word;
type_expression_size: Word;
+ entry: Word;
+ previous_entry: Word;
begin
_lexer_skip_token();
- memory_start := memory_free_pointer;
+ memory_start := 0;
member_count := 0;
_lexer_read_token(@token_kind);
@@ -2133,16 +2138,25 @@ begin
goto parse_enumeration_type_expression_end
end;
.parse_enumeration_type_expression_loop;
+ entry := _allocate(12);
member_count := member_count + 1;
enumeration_name := _lexer_global_get_start();
name_length := _lexer_global_get_end() - enumeration_name;
- memory_free_pointer^ := enumeration_name;
- memory_free_pointer := memory_free_pointer + 4;
+ entry^ := enumeration_name;
+ entry := entry + 4;
+
+ entry^ := name_length;
+ entry := entry + 4;
- memory_free_pointer^ := name_length;
- memory_free_pointer := memory_free_pointer + 4;
+ entry^ := 0;
+ if memory_start = 0 then
+ memory_start := entry - 8
+ else
+ previous_entry^ := entry - 8
+ end;
+ previous_entry := entry;
(* Skip the identifier. *)
_lexer_skip_token();
@@ -2184,6 +2198,9 @@ var
result: Word;
memory_start: Word;
member_count: Word;
+ member_array_size: Word;
+ member_array_start: Word;
+ member_array_current: Word;
begin
(* The resulting structure is 16 bytes long. *)
result := _allocate(16);
@@ -2191,9 +2208,30 @@ begin
memory_start := _enumeration_type_expression_get_members(parser_node);
member_count := _enumeration_type_expression_get_length(parser_node);
+ (* Copy the list of enumeration members into an array of strings. *)
+ member_array_size := member_count * 8;
+ member_array_start := _allocate(member_array_size);
+ member_array_current := member_array_start;
+
+ .read_type_enumeration_loop;
+ if member_count > 0 then
+ member_array_current^ := memory_start^;
+ member_array_current := member_array_current + 4;
+ memory_start := memory_start + 4;
+
+ member_array_current^ := memory_start^;
+ member_array_current := member_array_current + 4;
+ memory_start := memory_start + 4;
+
+ memory_start := memory_start^;
+ member_count := member_count - 1;
+ goto read_type_enumeration_loop
+ end;
+ member_count := _enumeration_type_expression_get_length(parser_node);
+
_type_set_kind(result, TypeKind.enumeration);
_type_set_size(result, 4);
- _enumeration_type_set_members(result, memory_start);
+ _enumeration_type_set_members(result, member_array_start);
_enumeration_type_set_length(result, member_count);
return _type_info_create(result)
@@ -2273,7 +2311,7 @@ var
current_word: Word;
result: Word;
begin
- result := memory_free_pointer;
+ result := _allocate(8);
current_word := result;
current_word^ := InfoKind.parameter_info;
@@ -2283,8 +2321,6 @@ begin
offset := parameter_index * 4;
current_word^ := 88 - offset;
- memory_free_pointer := current_word + 4;
-
return result
end;
@@ -2299,15 +2335,13 @@ var
result: Word;
current_word: Word;
begin
- result := memory_free_pointer;
+ result := _allocate(8);
current_word := result;
current_word^ := InfoKind.type_info;
current_word := current_word + 4;
current_word^ := type_representation;
- memory_free_pointer := current_word + 4;
-
return result
end;
@@ -2321,7 +2355,7 @@ var
current_word: Word;
result: Word;
begin
- result := memory_free_pointer;
+ result := _allocate(8);
current_word := result;
current_word^ := InfoKind.temporary_info;
current_word := current_word + 4;
@@ -2329,7 +2363,24 @@ begin
(* Calculate the stack offset: 4 * variable_counter. *)
current_word^ := temporary_index * 4;
- memory_free_pointer := current_word + 4;
+ return result
+end;
+
+(**
+ * Parameters:
+ * symbol_table - Local symbol table.
+ *)
+proc _procedure_info_create(symbol_table: Word);
+var
+ current_word: Word;
+ result: Word;
+begin
+ result := _allocate(8);
+ current_word := result;
+ current_word^ := InfoKind.procedure_info;
+ current_word := current_word + 4;
+
+ current_word^ := symbol_table;
return result
end;
@@ -2338,7 +2389,7 @@ end;
* Parameters:
* parameter_index - Parameter index.
*)
-proc _read_procedure_parameter(parser_node: Word, parameter_index: Word);
+proc _read_procedure_parameter(parser_node: Word, parameter_index: Word, symbol_table: Word);
var
name_length: Word;
info: Word;
@@ -2352,7 +2403,7 @@ begin
_write_z(", \0");
info := _parameter_info_create(parameter_index);
- _symbol_table_enter(@symbol_table_local, name_position, name_length, info);
+ _symbol_table_enter(symbol_table, name_position, name_length, info);
info := _parameter_info_get_offset(info);
_write_i(info);
@@ -2364,7 +2415,7 @@ end;
* Parameters:
* variable_index - Variable index.
*)
-proc _read_procedure_temporary(parser_node: Word, variable_index: Word);
+proc _read_procedure_temporary(parser_node: Word, variable_index: Word, symbol_table: Word);
var
name_length: Word;
info: Word;
@@ -2374,10 +2425,10 @@ begin
name_length := _declaration_get_length(parser_node);
info := _temporary_info_create(variable_index);
- _symbol_table_enter(@symbol_table_local, name_position, name_length, info)
+ _symbol_table_enter(symbol_table, name_position, name_length, info)
end;
-proc _read_procedure_temporaries(parser_node: Word);
+proc _read_procedure_temporaries(parser_node: Word, symbol_table: Word);
var
temporary_counter: Word;
begin
@@ -2387,7 +2438,7 @@ begin
if parser_node = 0 then
goto read_procedure_temporaries_end
end;
- _read_procedure_temporary(parser_node, temporary_counter);
+ _read_procedure_temporary(parser_node, temporary_counter, symbol_table);
temporary_counter := temporary_counter + 1;
parser_node := _declaration_get_next(parser_node);
@@ -2558,9 +2609,11 @@ var
name_length: Word;
parameter_counter: Word;
current_parameter: Word;
+ new_symbol_table: Word;
+ symbol_info: Word;
begin
- (* Clear local symbol table. *)
- symbol_table_local := 0;
+ new_symbol_table := _symbol_table_create();
+ symbol_info := _procedure_info_create(new_symbol_table);
name_pointer := _declaration_get_name(parser_node);
name_length := _declaration_get_length(parser_node);
@@ -2584,7 +2637,7 @@ begin
if current_parameter = 0 then
goto compile_procedure_declaration_end
end;
- _read_procedure_parameter(current_parameter, parameter_counter);
+ _read_procedure_parameter(current_parameter, parameter_counter, new_symbol_table);
parameter_counter := parameter_counter + 1;
current_parameter := _declaration_get_next(current_parameter);
@@ -2593,10 +2646,12 @@ begin
.compile_procedure_declaration_end;
current_parameter := _procedure_declaration_get_temporaries(parser_node);
- _read_procedure_temporaries(current_parameter);
+ _read_procedure_temporaries(current_parameter, new_symbol_table);
+
+ _symbol_table_enter(@symbol_table_global, name_pointer, name_length, symbol_info);
current_parameter := _procedure_declaration_get_body(parser_node);
- _compile_statements(current_parameter);
+ _compile_statements(current_parameter, new_symbol_table);
(* Write the epilogue. *)
_write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\n\tret\n\0")
@@ -2851,8 +2906,8 @@ begin
name_length := _named_type_expression_get_length(variable_type);
if _lexer_compare_keyword("Array", 5, name, name_length) then
- (* Else we assume this is a zeroed 409600 bytes big array. *)
- _write_z(" .zero 409600\0")
+ (* Else we assume this is a zeroed 4096 bytes big array. *)
+ _write_z(" .zero 4096\0")
else
_write_z(" .word 0\n\0")
end;
@@ -2992,9 +3047,6 @@ var
begin
_write_z(".globl _start\n\n\0");
- current_part := _module_declaration_get_types(parser_node);
- _read_type_part(current_part);
-
current_part := _module_declaration_get_globals(parser_node);
_compile_var_part(current_part);
@@ -3024,11 +3076,20 @@ begin
_write_c('\n')
end;
+proc _read_module_declaration(parser_node: Word);
+var
+ current_part: Word;
+begin
+ current_part := _module_declaration_get_types(parser_node);
+ _read_type_part(current_part)
+end;
+
proc _compile();
var
parser_node: Word;
begin
parser_node := _parse_module_declaration();
+ _read_module_declaration(parser_node);
_compile_module_declaration(parser_node)
end;
@@ -3101,6 +3162,31 @@ begin
end;
(**
+ * Create a new local symbol table in the symbol memory region after the last
+ * known symbol table.
+ *)
+proc _symbol_table_create();
+var
+ new_symbol_table: Word;
+ table_length: Word;
+ current_table: Word;
+begin
+ new_symbol_table := symbol_table_store;
+
+ .symbol_table_create_loop;
+ table_length := new_symbol_table^;
+
+ if table_length <> 0 then
+ table_length := table_length * 12;
+ table_length := table_length + 4;
+ new_symbol_table := new_symbol_table + table_length;
+ goto symbol_table_create_loop
+ end;
+
+ return new_symbol_table
+end;
+
+(**
* Inserts a symbol into the table.
*
* Parameters:
@@ -3632,13 +3718,13 @@ end;
(**
* One time lexer initialization.
*)
-proc _lexer_initialize();
+proc _lexer_initialize(code_pointer: Word);
begin
_lexer_classifications();
_lexer_transitions();
- _lexer_global_set_start(@source_code);
- _lexer_global_set_end(@source_code)
+ _lexer_global_set_start(code_pointer);
+ _lexer_global_set_end(code_pointer)
end;
proc _lexer_next_transition();
@@ -3922,7 +4008,9 @@ end;
proc _initialize_global_state();
begin
compiler_strings_position := @compiler_strings;
- memory_free_pointer := @memory
+ memory_free_pointer := _mmap(495616);
+ source_code := _mmap(495616);
+ symbol_table_store := _mmap(495616)
end;
(*
@@ -3934,11 +4022,11 @@ var
offset: Word;
begin
_initialize_global_state();
- _lexer_initialize();
+ _lexer_initialize(source_code);
_symbol_table_build();
(* Read the source from the standard input. *)
- offset := @source_code;
+ offset := source_code;
.start_read;
(* Second argument is buffer size. Modifying update the source_code definition. *)