diff options
Diffstat (limited to 'boot/stage19/cl.elna')
| -rw-r--r-- | boot/stage19/cl.elna | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/boot/stage19/cl.elna b/boot/stage19/cl.elna index 2fd12a0..76ee09b 100644 --- a/boot/stage19/cl.elna +++ b/boot/stage19/cl.elna @@ -252,7 +252,8 @@ type length: Word; body: Word; temporaries: Word; - parameters: Word + parameters: Word; + return_type: ^ElnaTreeNode end; ElnaTreeTypeDeclaration = record kind: ElnaTreeKind; @@ -528,7 +529,7 @@ type allocate_stack, ret ); - ElnaRtlKind = (register, immediate, symbol, pseudo, offset, pseudo_mem); + ElnaRtlKind = (register, immediate, symbol, pseudo, offset); ElnaRtlOperand = record kind: ElnaRtlKind; value: Word; @@ -1008,17 +1009,15 @@ begin return result end; -proc elna_rtl_call(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction); +proc elna_rtl_call(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); var argument_count: Word; current_argument: ^ElnaTacOperand; - argument_type: Word; - argument_value: Word; - argument_length: Word; argument_move: ^ElnaRtlInstruction; current_register: Word; first_instruction: Word; current_instruction: Word; + variable_info: ^ElnaRtlInfo; begin current_register := 0; first_instruction := nil; @@ -1031,15 +1030,12 @@ begin if argument_count > 0 then argument_count := argument_count - 1; - argument_type := current_argument^.kind; - argument_value := current_argument^.value; - argument_length := current_argument^.length; - current_argument := current_argument + #size(ElnaTacOperand); - - argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0); - elna_rtl_instruction_set_operand(argument_move, 2, argument_type, argument_value, argument_length); - + if current_argument^.kind = ElnaTacKind.pseudo then + argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0); + elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.pseudo, + current_argument^.value, current_argument^.length) + end; if first_instruction = nil then first_instruction := argument_move else @@ -1047,6 +1043,7 @@ begin end; current_instruction := argument_move; + current_argument := current_argument + #size(ElnaTacOperand); current_register := current_register + 1; goto elna_rtl_call_loop @@ -1119,7 +1116,7 @@ begin return result end; -proc elna_rtl_instruction(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction); +proc elna_rtl_instruction(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); var result: ^ElnaRtlInstruction; operands: ^ElnaRtlInstruction; @@ -1140,7 +1137,7 @@ begin elsif tac_instruction^.operator = ElnaTacOperator.store then result := elna_rtl_store(tac_instruction, next_instruction) elsif tac_instruction^.operator = ElnaTacOperator.proc_call then - result := elna_rtl_call(tac_instruction, next_instruction) + result := elna_rtl_call(tac_instruction, next_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.subtract then result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.sub) elsif tac_instruction^.operator = ElnaTacOperator.multiply then @@ -1591,7 +1588,7 @@ begin _write_c('\n') end; -proc elna_rtl_instructions(instruction: ^ElnaTacInstruction); +proc elna_rtl_instructions(instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var last_copy: ^ElnaRtlInstruction; current_copy: ^ElnaRtlInstruction; @@ -1599,7 +1596,7 @@ var first_copy: ^ElnaRtlInstruction; begin if instruction <> nil then - first_copy := elna_rtl_instruction(instruction, @current_copy); + first_copy := elna_rtl_instruction(instruction, @current_copy, variable_map); instruction := instruction^.next else first_copy := nil; @@ -1608,7 +1605,7 @@ begin .elna_rtl_instructions_start; if instruction <> nil then - next_copy := elna_rtl_instruction(instruction, @last_copy); + next_copy := elna_rtl_instruction(instruction, @last_copy, variable_map); instruction := instruction^.next; current_copy^.next := next_copy; @@ -2874,10 +2871,10 @@ begin elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length); elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacKind.symbol, condition_label, 0); - elna_instruction_list_concatenate(first_instruction, current_instruction); + first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); instruction := elna_tac_statements(parser_node^.statements, symbol_table); - if instruction <> 0 then + if instruction <> nil then elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction end; @@ -3563,10 +3560,16 @@ begin _elna_lexer_skip_token(); result^.parameters := parameter_head; - (* Skip semicolon and newline. *) + (* Skip semicolon or arrow. *) _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); + if token_kind = ElnaLexerKind.arrow then + result^.return_type := elna_parser_type_expression() + else + result^.return_type := nil + end; + parameter_head := elna_parser_var_part(); result^.temporaries := parameter_head; @@ -3713,17 +3716,17 @@ begin pseudo_symbol^.allocated := false; if elna_type_is_aggregate(variable_info^.variable_type) then - long_word := malloc(#size(ElnaRtlTypeWord)); - long_word^.kind := ElnaRtlTypeKind.long_word; - long_word^.size := variable_info^.variable_type^.size; - - pseudo_symbol^.rtl_type = long_word - else byte_array := malloc(#size(ElnaRtlTypeByteArray)); byte_array^.kind := ElnaRtlTypeKind.byte_array; byte_array^.size := variable_info^.variable_type^.size; - pseudo_symbol^.rtl_type = byte_array + pseudo_symbol^.rtl_type := byte_array + else + long_word := malloc(#size(ElnaRtlTypeWord)); + long_word^.kind := ElnaRtlTypeKind.long_word; + long_word^.size := variable_info^.variable_type^.size; + + pseudo_symbol^.rtl_type := long_word end; elna_symbol_table_enter(variable_map, current_entry^.name, current_entry^.length, pseudo_symbol); @@ -3749,9 +3752,9 @@ begin result^.length := tac_declaration^.length; 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); result^.variable_map := elna_rtl_symbol_table(tac_declaration^.symbol_table); + body := elna_rtl_instructions(tac_declaration^.body, result^.variable_map); + result^.body := elna_instruction_list_concatenate(parameters, body); return result end; @@ -5039,7 +5042,7 @@ begin return result end; -proc _elna_lexer_classify_keyword(position_start: Word, position_end: Word); +proc elna_lexer_classify_keyword(position_start: Word, position_end: Word); var result: Word; token_length: Word; @@ -5095,7 +5098,7 @@ begin return result end; -proc _elna_lexer_classify_finalize(start_position: Word); +proc elna_lexer_classify_finalize(start_position: Word); var character: Word; result: Word; @@ -5119,7 +5122,7 @@ begin return result end; -proc _elna_lexer_classify_single(start_position: Word); +proc elna_lexer_classify_single(start_position: Word); var character: Word; result: Word; @@ -5161,7 +5164,7 @@ begin return result end; -proc _elna_lexer_classify_composite(start_position: Word, one_before_last: Word); +proc elna_lexer_classify_composite(start_position: Word, one_before_last: Word); var first_character: Word; last_character: Word; @@ -5182,12 +5185,14 @@ begin if last_character = '=' then result := ElnaLexerKind.greater_equal end + elsif first_character = '-' then + result := ElnaLexerKind.arrow end; return result end; -proc _elna_lexer_classify_delimited(start_position: Word, end_position: Word); +proc elna_lexer_classify_delimited(start_position: Word, end_position: Word); var token_length: Word; delimiter: Word; @@ -5206,7 +5211,7 @@ begin return result end; -proc _elna_lexer_classify_integer(start_position: Word, end_position: Word); +proc elna_lexer_classify_integer(start_position: Word, end_position: Word); return ElnaLexerKind.integer end; @@ -5223,29 +5228,29 @@ begin elsif action_to_perform = ElnaLexerAction.single then lexer_state.finish := lexer_state.finish + 1; - intermediate := _elna_lexer_classify_single(lexer_state.start); + intermediate := elna_lexer_classify_single(lexer_state.start); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.eof then intermediate := ElnaLexerKind.eof; kind^ := intermediate elsif action_to_perform = ElnaLexerAction.finalize then - intermediate := _elna_lexer_classify_finalize(lexer_state.start); + intermediate := elna_lexer_classify_finalize(lexer_state.start); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.composite then - intermediate := _elna_lexer_classify_composite(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_composite(lexer_state.start, lexer_state.finish); kind^ := intermediate; lexer_state.finish := lexer_state.finish + 1 elsif action_to_perform = ElnaLexerAction.key_id then - intermediate := _elna_lexer_classify_keyword(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_keyword(lexer_state.start, lexer_state.finish); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.integer then - intermediate := _elna_lexer_classify_integer(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_integer(lexer_state.start, lexer_state.finish); kind^ := intermediate elsif action_to_perform = ElnaLexerAction.delimited then lexer_state.finish := lexer_state.finish + 1; - intermediate := _elna_lexer_classify_delimited(lexer_state.start, lexer_state.finish); + intermediate := elna_lexer_classify_delimited(lexer_state.start, lexer_state.finish); kind^ := intermediate end end; |
