diff --git a/boot/stage19/cl.elna b/boot/stage19/cl.elna index 8959bfa..1c2000c 100644 --- a/boot/stage19/cl.elna +++ b/boot/stage19/cl.elna @@ -49,13 +49,13 @@ type ElnaTypePointer = record kind: ElnaTypeKind; size: Word; - base: Word + base: ^ElnaType end; ElnaTypeArray = record kind: ElnaTypeKind; size: Word; base: Word; - length: Word + length: ^ElnaType end; (* Abstract syntax tree nodes. *) @@ -135,8 +135,8 @@ type ElnaTreeBinaryExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; - lhs: Word; - rhs: Word; + lhs: ^ElnaTreeExpression; + rhs: ^ElnaTreeExpression; operator: Word end; ElnaTreeUnaryExpression = record @@ -2232,9 +2232,30 @@ var rhs_type: Word; rhs_value: Word; rhs_length: Word; + pointer_type: ^ElnaTypePointer; begin if parser_node^.kind <> ElnaTreeKind.binary_expression then first_instruction := elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length) + elsif parser_node^.operator = ElnaLexerKind.pipe then + first_instruction := elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs_type, @lhs_value, @lhs_length); + + instruction := elna_tac_unary_expression(parser_node^.rhs, symbol_table, @rhs_type, @rhs_value, @rhs_length); + first_instruction := elna_instruction_list_concatenate(first_instruction, instruction); + + elna_tac_generate_pseudo(operand_type, operand_value, operand_length, symbol_table); + pointer_type := parser_node^.lhs^.type_decoration; + + instruction := elna_tac_instruction_create(ElnaTacOperator.multiply); + elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^); + elna_tac_instruction_set_operand(instruction, 2, rhs_type, rhs_value, rhs_length); + elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.immediate, pointer_type^.base^.size, 0); + first_instruction := elna_instruction_list_concatenate(first_instruction, instruction); + + instruction := elna_tac_instruction_create(ElnaTacOperator.add); + elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^); + elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^); + elna_tac_instruction_set_operand(instruction, 3, lhs_type, lhs_value, lhs_length); + first_instruction := elna_instruction_list_concatenate(first_instruction, instruction) else first_instruction := elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs_type, @lhs_value, @lhs_length); @@ -2245,8 +2266,6 @@ begin instruction := elna_tac_instruction_create(ElnaTacOperator.add) elsif parser_node^.operator = ElnaLexerKind.minus then instruction := elna_tac_instruction_create(ElnaTacOperator.subtract) - elsif parser_node^.operator = ElnaLexerKind.pipe then - instruction := elna_tac_instruction_create(ElnaTacOperator.add) elsif parser_node^.operator = ElnaLexerKind.multiplication then instruction := elna_tac_instruction_create(ElnaTacOperator.multiply) elsif parser_node^.operator = ElnaLexerKind.and then diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna index ee0b555..46d6eaa 100644 --- a/boot/stage20/cl.elna +++ b/boot/stage20/cl.elna @@ -64,13 +64,13 @@ type kind: ElnaTypeKind; size: Word; alignment: Word; - base: Word + base: ^ElnaType end; ElnaTypeArray = record kind: ElnaTypeKind; size: Word; alignment: Word; - base: Word; + base: ^ElnaType; length: Word end; @@ -151,8 +151,8 @@ type ElnaTreeBinaryExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; - lhs: Word; - rhs: Word; + lhs: ^ElnaTreeExpression; + rhs: ^ElnaTreeExpression; operator: Word end; ElnaTreeUnaryExpression = record @@ -515,7 +515,7 @@ type ElnaTacInstruction = record next: Word; operator: ElnaTacOperator; - operands: [3]ElnaTacOperand + operands: [4]ElnaTacOperand end; ElnaTacProcedure = record next: Word; @@ -988,6 +988,37 @@ begin return result end; +proc elna_rtl_add_ptr(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +var + result: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; +begin + result := elna_rtl_instruction_create(ElnaRtlOperator.li); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.pseudo, + tac_instruction^.operands[4].value, tac_instruction^.operands[4].length, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.immediate, tac_instruction^.operands[3].value, 0, 0); + elna_list_append(instructions, result); + + result := elna_rtl_instruction_create(ElnaRtlOperator.mul); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.pseudo, + tac_instruction^.operands[4].value, tac_instruction^.operands[4].length, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.pseudo, + tac_instruction^.operands[4].value, tac_instruction^.operands[4].length, 0); + elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand); + elna_rtl_instruction_set_operand(result, 3, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); + elna_list_append(instructions, result); + + result := elna_rtl_instruction_create(ElnaRtlOperator.add); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.pseudo, + tac_instruction^.operands[4].value, tac_instruction^.operands[4].length, 0); + elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); + elna_rtl_instruction_set_operand(result, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlKind.pseudo, + tac_instruction^.operands[4].value, tac_instruction^.operands[4].length, 0); + + elna_list_append(instructions, result) +end; + proc elna_rtl_binary_equality(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, instruction_kind: ElnaRtlOperator, variable_map: ^ElnaSymbolTable); var @@ -1124,7 +1155,7 @@ begin argument_count := argument_count - 1; elna_rtl_load_operand_value(instructions, current_argument, ElnaRtlRegister.a0 + current_register, variable_map); - current_argument := current_argument + #size(ElnaTacOperand); + current_argument := current_argument | 1; current_register := current_register + 1; goto elna_rtl_call_loop @@ -1251,6 +1282,8 @@ begin elna_rtl_get_address(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.add then elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add, variable_map) + elsif tac_instruction^.operator = ElnaTacOperator.add_ptr then + elna_rtl_add_ptr(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.load then elna_rtl_load(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.copy_from_offset then @@ -2410,17 +2443,20 @@ begin return result end; -proc elna_tac_sum_create(operator: ElnaTacOperator, lhs: ^ElnaTacOperand, rhs: ^ElnaTacOperand, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction; +proc elna_tac_sum_create(parser_node: ^ElnaTreeBinaryExpression, lhs: ^ElnaTacOperand, + rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction; var instruction: ^ElnaTacInstruction; + pointer_type: ^ElnaTypePointer; begin - instruction := elna_tac_instruction_create(operator); + pointer_type := parser_node^.lhs^.type_decoration; + instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr); elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); - elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); - elna_tac_instruction_set_operand(instruction, 2, lhs^.kind, lhs^.value, lhs^.length); - elna_tac_instruction_set_operand(instruction, 3, rhs^.kind, rhs^.value, rhs^.length); + elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length); + elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length); + elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 0); + elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length); return instruction end; @@ -2458,7 +2494,7 @@ begin elsif parser_node^.operator = ElnaLexerKind.minus then instruction := elna_tac_binary_create(ElnaTacOperator.subtract, @lhs, @rhs, symbol_table, operand) elsif parser_node^.operator = ElnaLexerKind.pipe then - instruction := elna_tac_sum_create(ElnaTacOperator.add, @lhs, @rhs, symbol_table, operand) + instruction := elna_tac_sum_create(parser_node, @lhs, @rhs, symbol_table, operand) elsif parser_node^.operator = ElnaLexerKind.multiplication then instruction := elna_tac_binary_create(ElnaTacOperator.multiply, @lhs, @rhs, symbol_table, operand) elsif parser_node^.operator = ElnaLexerKind.and then