Allocate bigger memory regions dynamically
This commit is contained in:
		| @@ -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; | ||||
| @@ -245,6 +242,15 @@ proc _read_file(buffer: Word, size: Word); | ||||
| 	return _syscall(0, buffer, size, 0, 0, 0, 63) | ||||
| 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. | ||||
|  * | ||||
| @@ -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; | ||||
|  | ||||
| 	memory_free_pointer^ := name_length; | ||||
| 	memory_free_pointer := memory_free_pointer + 4; | ||||
| 	entry^ := name_length; | ||||
| 	entry := entry + 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; | ||||
|  | ||||
| @@ -3100,6 +3161,31 @@ begin | ||||
| 	return result | ||||
| 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. | ||||
|  * | ||||
| @@ -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. *) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user