diff --git a/Rakefile b/Rakefile index fe96b49..39aa6c6 100644 --- a/Rakefile +++ b/Rakefile @@ -47,12 +47,14 @@ task :convert do proc f(); var + x: ^ElnaLocation; y: ElnaLocation; begin + x := malloc(#size(ElnaLocation)); y.line := 1; y.column := 3; - x := y; - printf("# %i %i %i %i\\n\\0", x.line, x.column, y.line, y.column) + x^ := y; + printf("# %i %i %i %i\\n\\0", x^.line, x^.column, y.line, y.column) end; begin @@ -61,7 +63,6 @@ task :convert do elsif line.start_with?('var') && !seen_global_var current_stage << <<~FUN var - x: ElnaLocation; FUN else current_stage << line diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna index c2d9ad1..16de300 100644 --- a/boot/stage21/cl.elna +++ b/boot/stage21/cl.elna @@ -322,7 +322,7 @@ type parent: Word; symbols: ^ElnaSymbolEntry end; - ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info); + ElnaSymbolInfoKind = (type_info, temporary_info, procedure_info); ElnaSymbolInfo = record kind: ElnaSymbolInfoKind end; @@ -330,7 +330,6 @@ type kind: ElnaSymbolInfoKind; _type: ^ElnaType end; - (* ElnaSymbolTemporaryInfo.offset is 0 or 1, 0: local variable, 1: pseudo register *) ElnaSymbolTemporaryInfo = record kind: ElnaSymbolInfoKind; attr: Word; @@ -858,7 +857,7 @@ begin existing^.next := new end; -proc elna_tac_make_variable(operand_type: Word, operand_value: Word, operand_length: Word, symbol_table: ^ElnaSymbolTable); +proc elna_tac_make_variable(operand: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, variable_type: ^ElnaType); var buffer: Word; temporary_info: ^ElnaSymbolTemporaryInfo; @@ -868,12 +867,12 @@ begin sprintf(buffer, "$a%i\0", pseudo_counter); - operand_type^ := ElnaTacKind.variable; - operand_value^ := buffer; - operand_length^ := strlen(buffer); + operand^.kind := ElnaTacKind.variable; + operand^.value := buffer; + operand^.length := strlen(buffer); - temporary_info := temporary_info_create(1, word_type); - elna_symbol_table_enter(symbol_table, buffer, operand_length^, temporary_info) + temporary_info := temporary_info_create(1, variable_type); + elna_symbol_table_enter(symbol_table, buffer, operand^.length, temporary_info) end; proc elna_tac_instruction_set_operand(this: ^ElnaTacInstruction, n: Word, operand_type: Word, operand_value: Word, operand_length: Word); @@ -1215,14 +1214,22 @@ proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction var instruction: ^ElnaRtlInstruction; rtl_operand: ElnaRtlOperand; + pseudo_symbol: ^ElnaRtlObjectInfo; begin elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); - instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); + pseudo_symbol := elna_symbol_table_lookup(variable_map, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, - tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); - elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); - elna_list_append(instructions, instruction) + if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then + elna_rtl_memcpy(instructions, @rtl_operand, pseudo_symbol^.rtl_type, rtl_operand.kind, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) + else + instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); + elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); + elna_list_append(instructions, instruction) + end end; proc elna_rtl_copy_from_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); @@ -1254,7 +1261,11 @@ begin elna_rtl_instruction_set_operand(instruction, 2, target_type, target_value, target_length, 0); elna_list_append(instructions, instruction); - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + if source_operand^.kind = ElnaRtlKind.pseudo then + instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv) + else + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la) + end; elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, source_operand^.kind, source_operand^.value, source_operand^.length, 0); elna_list_append(instructions, instruction); @@ -2235,7 +2246,7 @@ var begin offset := _add_string(string_literal_node^.value); - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, word_type); instruction := elna_tac_instruction_create(ElnaTacOperator.get_address); elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.variable, "strings", 7); @@ -2443,6 +2454,7 @@ var operand_result: ElnaTacOperandResult; instruction: ^ElnaTacInstruction; base: ElnaTacOperand; + temporary_info: ^ElnaSymbolTemporaryInfo; begin if parser_node^.kind = ElnaTreeKind.unary_expression then operator := parser_node^.operator; @@ -2454,31 +2466,31 @@ begin elna_tac_designator(instructions, unary_operand, symbol_table, @operand_result, @base); if operator = '@' then - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, word_type); elna_tac_copy_address(instructions, @operand_result, @base, operand) elsif operator = '-' then - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, parser_node^.type_decoration); instruction := elna_tac_instruction_create(ElnaTacOperator.negate); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) elsif operator = '~' then - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, parser_node^.type_decoration); instruction := elna_tac_instruction_create(ElnaTacOperator.complement); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) elsif operand_result.kind = ElnaTacOperandType.dereferenced_pointer then - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, parser_node^.type_decoration); instruction := elna_tac_instruction_create(ElnaTacOperator.load); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) elsif operand_result.kind = ElnaTacOperandType.sub_object then - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, parser_node^.type_decoration); instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); @@ -2569,7 +2581,7 @@ begin pointer_type := parser_node^.type_decoration; instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr); - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, word_type); 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); @@ -2605,10 +2617,18 @@ proc elna_tac_binary_create(instructions: ^ElnaList, operator: ElnaTacOperator, rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); var instruction: ^ElnaTacInstruction; + lhs_symbol: ^ElnaSymbolTemporaryInfo; + variable_type: ^ElnaType; begin - instruction := elna_tac_instruction_create(operator); + if lhs^.kind = ElnaTacKind.variable then + lhs_symbol := elna_symbol_table_lookup(symbol_table, lhs^.value, lhs^.length); + variable_type := lhs_symbol^.variable_type + else + variable_type := word_type + end; + elna_tac_make_variable(operand, symbol_table, variable_type); - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + instruction := elna_tac_instruction_create(operator); 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, operand^.kind, operand^.value, operand^.length); @@ -2727,7 +2747,7 @@ begin parsed_expression := parsed_call^.callee; arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand)); - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, word_type); call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call); elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.label, parsed_expression^.name, parsed_expression^.length); @@ -2971,7 +2991,7 @@ begin end; if operand_result^.kind = ElnaTacOperandType.dereferenced_pointer then - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, word_type); instruction := elna_tac_instruction_create(ElnaTacOperator.add); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); @@ -3004,7 +3024,7 @@ begin element_type := aggregate_type^.base; elna_tac_binary_expression(instructions, array_access_expression^.index, symbol_table, @inter_operand); - elna_tac_make_variable(@index_operand.kind, @index_operand.value, @index_operand.length, symbol_table); + elna_tac_make_variable(@index_operand, symbol_table, word_type); instruction := elna_tac_instruction_create(ElnaTacOperator.subtract); elna_tac_instruction_set_operand(instruction, 1, inter_operand.kind, inter_operand.value, inter_operand.length); @@ -3014,7 +3034,7 @@ begin elna_tac_designator(instructions, array_access_expression^.array, symbol_table, @operand_result, @inter_operand); - elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + elna_tac_make_variable(operand, symbol_table, word_type); elna_tac_copy_address(instructions, @operand_result, @inter_operand, operand); instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr); @@ -3274,8 +3294,6 @@ end; proc elna_tac_statements(instructions: ^ElnaList, current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable); begin .elna_tac_statements_loop; - pseudo_counter := 0; - if current_statement <> nil then elna_tac_statement(instructions, current_statement, symbol_table); current_statement := current_statement^.next; @@ -4016,6 +4034,7 @@ begin result^.parameters := elna_tac_parameters(parser_node^.parameters, @parameter_count); result^.count := parameter_count; + pseudo_counter := 0; elna_tac_statements(@result^.body, parser_node^.body, symbol_info^.symbol_table); return result @@ -4944,30 +4963,18 @@ begin elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info) end; -(** - * Initializes the array with character classes. - *) -proc elna_lexer_classifications(); -var - code: Word; +proc elna_lexer_classifications1(); begin - code := 1; - - (* Set everything by default to invalid. *) - .elna_lexer_classifications_invalid; - classification[code] := ElnaLexerClass.invalid; - code := code + 1; - - if code < 129 then - goto elna_lexer_classifications_invalid - end; - classification[1] := ElnaLexerClass.eof; classification[10] := ElnaLexerClass.space; classification[11] := ElnaLexerClass.space; classification[14] := ElnaLexerClass.space; classification[33] := ElnaLexerClass.space; - classification[34] := ElnaLexerClass.single; + classification[34] := ElnaLexerClass.single +end; + +proc elna_lexer_classifications2(); +begin classification[35] := ElnaLexerClass.double_quote; classification[36] := ElnaLexerClass.number_sign; classification[37] := ElnaLexerClass.other; @@ -4997,7 +5004,11 @@ begin classification[61] := ElnaLexerClass.less; classification[62] := ElnaLexerClass.equals; classification[63] := ElnaLexerClass.greater; - classification[64] := ElnaLexerClass.other; + classification[64] := ElnaLexerClass.other +end; + +proc elna_lexer_classifications3(); +begin classification[65] := ElnaLexerClass.single; classification[66] := ElnaLexerClass.alpha; classification[67] := ElnaLexerClass.alpha; @@ -5031,7 +5042,11 @@ begin classification[95] := ElnaLexerClass.single; classification[96] := ElnaLexerClass.alpha; classification[97] := ElnaLexerClass.other; - classification[98] := ElnaLexerClass.hex; + classification[98] := ElnaLexerClass.hex +end; + +proc elna_lexer_classifications4(); +begin classification[99] := ElnaLexerClass.hex; classification[100] := ElnaLexerClass.hex; classification[101] := ElnaLexerClass.hex; @@ -5060,7 +5075,31 @@ begin classification[124] := ElnaLexerClass.other; classification[125] := ElnaLexerClass.single; classification[126] := ElnaLexerClass.other; - classification[127] := ElnaLexerClass.single; + classification[127] := ElnaLexerClass.single +end; + +(** + * Initializes the array with character classes. + *) +proc elna_lexer_classifications(); +var + code: Word; +begin + code := 1; + + (* Set everything by default to invalid. *) + .elna_lexer_classifications_invalid; + classification[code] := ElnaLexerClass.invalid; + code := code + 1; + + if code < 129 then + goto elna_lexer_classifications_invalid + end; + + elna_lexer_classifications1(); + elna_lexer_classifications2(); + elna_lexer_classifications3(); + elna_lexer_classifications4(); (* Set the remaining 129 - 256 bytes to transitionClassOther. *) .elna_lexer_classifications_other;