diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna index b40e2e0..4209824 100644 --- a/boot/stage17/cl.elna +++ b/boot/stage17/cl.elna @@ -26,7 +26,9 @@ type name: Word; length: Word; body: Word; - stack: Word + stack: Word; + parameters: Word; + count: Word end; ElnaTreeNode = record kind: Word @@ -239,11 +241,6 @@ type kind: Word; _type: Word end; - ElnaSymbolParameterInfo = record - kind: Word; - offset: Word; - variable_type: Word - end; ElnaSymbolTemporaryInfo = record kind: Word; offset: Word; @@ -467,8 +464,8 @@ type allocate_stack, ret ); - ElnaTacOperand = (temporary, immediate, symbol, stack, pseudo, list); - ElnaRtlOperand = (register, immediate, symbol, offset, pseudo); + ElnaTacOperand = (temporary, immediate, symbol, pseudo, list); + ElnaRtlOperand = (register, immediate, symbol, pseudo, offset); ElnaRtlRegister = ( zero, ra, @@ -833,10 +830,6 @@ begin result := elna_rtl_instruction_create(ElnaRtlOperator.li); elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length) - elsif operand_type = ElnaTacOperand.stack then - result := elna_rtl_instruction_create(ElnaRtlOperator.lw); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value) elsif operand_type = ElnaTacOperand.symbol then result := elna_rtl_instruction_create(ElnaRtlOperator.la); elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); @@ -1074,13 +1067,7 @@ begin operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2); - if operand_type = ElnaTacOperand.stack then - result := elna_rtl_instruction_create(ElnaRtlOperator.add); - - elna_rtl_copy_operand(tac_instruction, 1, result); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0); - elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0) - elsif operand_type = ElnaTacOperand.symbol then + if operand_type = ElnaTacOperand.symbol then result := elna_rtl_instruction_create(ElnaRtlOperator.la); elna_rtl_copy_operand(tac_instruction, 1, result); @@ -1126,9 +1113,7 @@ begin operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2); - if operand_type = ElnaTacOperand.stack then - elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value) - elsif operand_type = ElnaTacOperand.pseudo then + if operand_type = ElnaTacOperand.pseudo then elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.pseudo, operand_value, operand_length) end; if operands = 0 then @@ -1589,7 +1574,7 @@ var stack_instruction: ^ElnaInstructionList; begin .elna_alloc_procedure_loop; - temporary_variable_counter := 32; + temporary_variable_counter := 4; variable_map := 0; elna_alloc_instructions(rtl_declaration^.body); @@ -1837,20 +1822,14 @@ end; proc _elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - lookup_result: ^ElnaSymbolParameterInfo; + lookup_result: ^ElnaSymbolTemporaryInfo; begin lookup_result := _symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length); if lookup_result <> nil then - if lookup_result^.kind = ElnaSymbolInfoKind.temporary_info then - operand_type^ := ElnaTacOperand.pseudo; - operand_value^ := variable_expression^.name; - operand_length^ := variable_expression^.length - else - operand_type^ := ElnaTacOperand.stack; - operand_value^ := lookup_result^.offset; - operand_length^ := 0 - end + operand_type^ := ElnaTacOperand.pseudo; + operand_value^ := variable_expression^.name; + operand_length^ := variable_expression^.length else operand_type^ := ElnaTacOperand.symbol; operand_value^ := variable_expression^.name; @@ -3365,27 +3344,6 @@ begin return result end; -(** - * Parameters: - * parameter_index - Parameter index. - * parameter_type - Parameter type. - *) -proc _parameter_info_create(parameter_index: Word, parameter_type: Word); -var - offset: Word; - result: ^ElnaSymbolParameterInfo; -begin - result := malloc(ElnaSymbolParameterInfo_size()); - result^.kind := ElnaSymbolInfoKind.parameter_info; - - (* Calculate the stack offset: 28 - (4 * parameter_counter) *) - offset := parameter_index * 4; - result^.offset := 28 - offset; - result^.variable_type := parameter_type; - - return result -end; - proc _type_info_create(type_representation: Word); var result: ^ElnaSymbolTypeInfo; @@ -3431,21 +3389,6 @@ begin return result end; -(** - * Parameters: - * parameter_index - Parameter index. - *) -proc elna_name_procedure_parameter(parser_node: ^ElnaTreeVariableDeclaration, parameter_index: Word, symbol_table: Word); -var - info: Word; - variable_type1: Word; -begin - variable_type1 := elna_name_type_expression(parser_node^._type); - - info := _parameter_info_create(parameter_index, variable_type1); - _symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info) -end; - (** * Parameters: * variable_index - Variable index. @@ -3552,39 +3495,43 @@ begin return result end; -proc _elna_tac_parameters(current_parameter: ^ElnaTreeDeclaration, new_symbol_table: Word); +proc _elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word); var - name_pointer: Word; - name_length: Word; - parameter_counter: Word; - instruction: Word; - first_instruction: Word; - current_instruction: Word; - symbol_info: ^ElnaSymbolParameterInfo; + ast_parameter: ^ElnaTreeDeclaration; + parameter_index: Word; + current_parameter: Word; + parameter_list: Word; begin - first_instruction := 0; - parameter_counter := 0; + ast_parameter := ast_list; + parameter_count^ := 0; + + .elna_tac_parameters_count; + if ast_parameter <> nil then + ast_parameter := ast_parameter^.next; + parameter_count^ := parameter_count^ + 1; + + goto elna_tac_parameters_count + end; + (* The parameters are saved as an array of name pointer + name length. *) + parameter_list := malloc(parameter_count^ * 8); + current_parameter := parameter_list; + + ast_parameter := ast_list; + parameter_index := 0; .elna_tac_parameters_loop; - if current_parameter <> 0 then - symbol_info := _symbol_table_lookup(new_symbol_table, current_parameter^.name, current_parameter^.length); + if parameter_index < parameter_count^ then + current_parameter^ := ast_parameter^.name; + current_parameter := current_parameter + 4; + current_parameter^ := ast_parameter^.length; + current_parameter := current_parameter + 4; - instruction := _elna_tac_instruction_create(ElnaTacOperator.store); - _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + parameter_counter, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, symbol_info^.offset, 0); - if first_instruction = nil then - first_instruction := instruction - else - elna_instruction_list_concatenate(current_instruction, instruction) - end; - current_instruction := instruction; - - parameter_counter := parameter_counter + 1; - - current_parameter := current_parameter^.next; + parameter_index := parameter_index + 1; + ast_parameter := ast_parameter^.next; goto elna_tac_parameters_loop end; - return first_instruction + + return parameter_list end; proc elna_rtl_global_declaration(tac_declaration: ^ElnaInstructionDeclaration); @@ -3601,9 +3548,48 @@ begin return result end; +proc elna_rtl_parameters(parameters: Word, count: Word); +var + result: Word; + current_instruction: Word; + last_instruction: Word; + parameter_index: Word; + parameter_name: Word; + name_length: Word; +begin + result := nil; + parameter_index := 0; + + .elna_rtl_parameters_loop; + if parameter_index < count then + parameter_name := parameters^; + parameters := parameters + 4; + name_length := parameters^; + parameters := parameters + 4; + + current_instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(current_instruction, 1, ElnaRtlOperand.pseudo, parameter_name, name_length); + elna_rtl_instruction_set_operand(current_instruction, 2, ElnaRtlOperand.register, 11 + parameter_index, 0); + + if result = nil then + result := current_instruction + else + elna_instruction_list_concatenate(last_instruction, current_instruction) + end; + last_instruction := current_instruction; + + parameter_index := parameter_index + 1; + goto elna_rtl_parameters_loop + end; + + return result +end; + proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration); var result: ^ElnaInstructionDeclaration; + body: ^ElnaInstructionList; + parameters: ^ElnaInstructionList; begin result := malloc(ElnaInstructionDeclaration_size()); @@ -3611,20 +3597,19 @@ begin result^.name := tac_declaration^.name; result^.length := tac_declaration^.length; result^.stack := tac_declaration^.stack; - result^.body := elna_rtl_instructions(tac_declaration^.body); + + parameters = elna_rtl_parameters(tac_declaration^.parameters, tac_declaration^.count); + body := elna_rtl_instructions(tac_declaration^.body); + result^.body := elna_instruction_list_concatenate(parameters, body); return result end; proc _elna_tac_procedure_declaration(parser_node: ElnaTreeProcedureDeclaration); var - current_parameter: Word; - new_symbol_table: Word; symbol_info: ^ElnaSymbolProcedureInfo; - instruction: Word; - first_instruction: Word; result: ^ElnaInstructionDeclaration; - result_size: Word; + parameter_count: Word; begin result := malloc(ElnaInstructionDeclaration_size()); @@ -3635,15 +3620,10 @@ begin result^.length := parser_node^.length; symbol_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length); - new_symbol_table := symbol_info^.symbol_table; - current_parameter := parser_node^.parameters; - first_instruction := _elna_tac_parameters(current_parameter, new_symbol_table); - - instruction := _elna_tac_statements(parser_node^.body, new_symbol_table); - first_instruction := elna_instruction_list_concatenate(first_instruction, instruction); - - result^.body := first_instruction; + result^.parameters := _elna_tac_parameters(parser_node^.parameters, @parameter_count); + result^.count := parameter_count; + result^.body := _elna_tac_statements(parser_node^.body, symbol_info^.symbol_table); return result end; @@ -4128,23 +4108,12 @@ end; proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration); var new_symbol_table: Word; - parameter_counter: Word; symbol_info: Word; - current_parameter: ^ElnaTreeDeclaration; begin new_symbol_table := _symbol_table_create(); symbol_info := _procedure_info_create(new_symbol_table); - current_parameter := parser_node^.parameters; - parameter_counter := 0; - .elna_name_procedure_declaration_parameter; - if current_parameter <> nil then - elna_name_procedure_parameter(current_parameter, parameter_counter, new_symbol_table); - parameter_counter := parameter_counter + 1; - - current_parameter := current_parameter^.next; - goto elna_name_procedure_declaration_parameter - end; + elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table); elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table); _symbol_table_enter(@symbol_table_global, parser_node^.name, parser_node^.length, symbol_info) @@ -4278,7 +4247,6 @@ end; proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: Word); var variable_info: ^ElnaSymbolInfo; - parameter_info: ^ElnaSymbolParameterInfo; temporary_info: ^ElnaSymbolTemporaryInfo; begin variable_info := _symbol_table_lookup(symbol_table, parser_node^.name, parser_node^.length); @@ -4286,11 +4254,7 @@ begin if variable_info = nil then variable_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length) end; - - if variable_info^.kind = ElnaSymbolInfoKind.parameter_info then - parameter_info := variable_info; - parser_node^.type_decoration := parameter_info^.variable_type - elsif variable_info^.kind = ElnaSymbolInfoKind.temporary_info then + if variable_info^.kind = ElnaSymbolInfoKind.temporary_info then temporary_info := variable_info; parser_node^.type_decoration := temporary_info^.variable_type end