diff --git a/Rakefile b/Rakefile index f66b9eb..c2f5be5 100644 --- a/Rakefile +++ b/Rakefile @@ -49,12 +49,18 @@ task :convert do x: ElnaLocation; y: ElnaLocation; begin + y.line := 1; + y.column := 3; x := y; + printf("# %i %i %i %i\\n\\0", x.line, x.column, y.line, y.column) end; + begin + f(); FUN + else + current_stage << line end - current_stage << line end end end diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna index 4636589..5cf3744 100644 --- a/boot/stage21/cl.elna +++ b/boot/stage21/cl.elna @@ -210,6 +210,11 @@ type array: Word; index: ^ElnaTreeExpression end; + ElnaTreeEnumeration = record + name: Word; + length: Word; + next: Word + end; ElnaTreeEnumerationTypeExpression = record kind: ElnaTreeKind; members: Word; @@ -637,14 +642,23 @@ type size: Word; alignment: Word end; + ElnaRtlInfoKind = (object_info, static_info); ElnaRtlInfo = record - counter: Word; + kind: ElnaRtlInfoKind + end; + ElnaRtlStaticInfo = record + kind: ElnaRtlInfoKind; + rtl_type: ^ElnaRtlType + end; + ElnaRtlObjectInfo = record + kind: ElnaRtlInfoKind; rtl_type: ^ElnaRtlType; + counter: Word; allocated: Word end; var - symbol_table_global: [1024]Word; + symbol_table_global: ^ElnaSymbolTable; compiler_strings: [1024]Word; classification: [256]Word; @@ -672,7 +686,7 @@ var * * Returns the length in a0. *) -proc _string_length(string: Word); +proc _string_length(string: Word) -> Word; var counter: Word; current_byte: Word; @@ -802,7 +816,7 @@ end; (** * Appends a new element to the end of the list. *) -proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode); +proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode) -> ^ElnaListNode; begin if element <> nil then if list^.first = nil then @@ -877,13 +891,13 @@ begin return result end; -proc elna_rtl_instruction_create(kind: Word); +proc elna_rtl_instruction_create(operator: ElnaRtlOperator) -> ^ElnaRtlInstruction; var result: ^ElnaRtlInstruction; begin result := malloc(#size(ElnaRtlInstruction)); - result^.operator := kind; + result^.operator := operator; result^.next := nil; return result @@ -936,7 +950,7 @@ proc elna_rtl_operand_value(instructions: ^ElnaList, tac_operand: ^ElnaTacOperan rtl_operand: ^ElnaRtlOperand) -> ^ElnaRtlInfo; var instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; begin pseudo_symbol := nil; @@ -1082,7 +1096,7 @@ end; proc elna_rtl_operand_address(variable_map: ^ElnaSymbolTable, addressable: ^ElnaTacOperand, target_operand: ^ElnaRtlOperand) -> ^ElnaRtlInstruction; var - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; instruction: ^ElnaRtlInstruction; begin pseudo_symbol := elna_symbol_table_lookup(variable_map, addressable^.value, addressable^.length); @@ -1097,8 +1111,6 @@ begin elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo_mem, addressable^.value, addressable^.length, 0) else - (* Debug - printf("# %.*s, %i\n\0", addressable^.length, addressable^.value, pseudo_symbol^.rtl_type^.kind); *) elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, addressable^.value, addressable^.length, 0) end; @@ -1154,7 +1166,6 @@ var current_argument: ^ElnaTacOperand; instruction: ^ElnaRtlInstruction; current_register: Word; - variable_info: ^ElnaRtlInfo; begin current_register := 0; current_argument := tac_instruction^.operands[2].value; @@ -1254,7 +1265,8 @@ var instruction: ^ElnaRtlInstruction; source_operand: ElnaRtlOperand; target_operand: ElnaRtlOperand; - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; + byte_array: ^ElnaRtlTypeByteArray; begin elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand); pseudo_symbol := elna_symbol_table_lookup(variable_map, @@ -1262,8 +1274,8 @@ begin if pseudo_symbol = nil then elna_rtl_generate_pseudo(@target_operand, variable_map); - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); elna_rtl_instruction_set_operand(instruction, 1, target_operand.kind, target_operand.value, target_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); @@ -1273,19 +1285,40 @@ begin elna_rtl_instruction_set_operand(instruction, 1, source_operand.kind, source_operand.value, source_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length, 0); elna_list_append(instructions, instruction) - else + elsif source_operand.kind = ElnaRtlKind.pseudo then instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); 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, source_operand.kind, source_operand.value, source_operand.length, 0); elna_list_append(instructions, instruction); + else + byte_array := pseudo_symbol^.rtl_type; + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); + elna_list_append(instructions, instruction); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + 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); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a2, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, byte_array^.size, 0, 0); + elna_list_append(instructions, instruction); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0); + elna_list_append(instructions, instruction) end end; proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; begin if tac_instruction^.operator = ElnaTacOperator.get_address then elna_rtl_get_address(instructions, tac_instruction, variable_map) @@ -1370,7 +1403,7 @@ begin elna_list_append(instructions, result) end; -proc elna_riscv_instruction_name(instruction_kind: Word); +proc elna_riscv_instruction_name(instruction_kind: ElnaRtlOperator) -> Word; var argument_count: Word; begin @@ -1483,9 +1516,10 @@ begin end end; -proc elna_alloc_variable(operand_value: Word, operand_length: Word, variable_map: ^ElnaSymbolTable); +proc elna_alloc_variable(operand_value: Word, operand_length: Word, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlObjectInfo; var - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; pseudo_type: ^ElnaRtlTypeByteArray; begin pseudo_symbol := elna_symbol_table_lookup(variable_map, operand_value, operand_length); @@ -1516,7 +1550,7 @@ end; proc elna_alloc_operation_target(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; store_instruction: ^ElnaRtlInstruction; begin if instruction^.operands[1].kind = ElnaRtlKind.pseudo then @@ -1537,7 +1571,7 @@ end; proc elna_alloc_load_address(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); var - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; begin (* pseudo or pseudo_mem. *) if instruction^.operands[2].kind <> ElnaRtlKind.data then @@ -1553,10 +1587,11 @@ begin end end; -proc elna_alloc_store(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_alloc_store(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var store_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; begin instruction := elna_alloc_operand(instructions, instruction, 1, ElnaRtlRegister.t0, variable_map); @@ -1580,10 +1615,11 @@ begin return instruction end; -proc elna_alloc_load(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_alloc_load(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var new_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; begin if instruction^.operands[2].kind = ElnaRtlKind.pseudo then pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, @@ -1606,9 +1642,10 @@ begin return elna_alloc_operation_target(instructions, instruction, variable_map) end; -proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; destination_pseudo: Word; source_pseudo: Word; begin @@ -1652,7 +1689,7 @@ proc elna_alloc_operand(instructions: ^ElnaList, instruction: ^ElnaRtlInstructio number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var main_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; begin if instruction^.operands[number].kind = ElnaRtlKind.pseudo then pseudo_symbol := elna_alloc_variable(instruction^.operands[number].value, @@ -1674,28 +1711,25 @@ begin return instruction end; -proc elna_alloc_binary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; -var - new_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; +proc elna_alloc_binary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; begin instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t0, variable_map); instruction := elna_alloc_operand(instructions, instruction, 3, ElnaRtlRegister.t1, variable_map); return elna_alloc_operation_target(instructions, instruction, variable_map) end; -proc elna_alloc_unary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; -var - new_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; +proc elna_alloc_unary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; begin instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t0, variable_map); return elna_alloc_operation_target(instructions, instruction, variable_map) end; -proc elna_alloc_instruction(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; +proc elna_alloc_instruction(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; new_instruction: ^ElnaRtlInstruction; begin if instruction^.operator = ElnaRtlOperator.mv then @@ -1896,7 +1930,7 @@ begin end end; -proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule); +proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule) -> ^ElnaInstructionModule; var result: ^ElnaInstructionModule; begin @@ -2020,7 +2054,7 @@ begin return result end; -proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor); +proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNilLiteral; var result: ^ElnaTreeNilLiteral; begin @@ -2166,7 +2200,7 @@ var parser_node: ^ElnaTreeExpression; token: ^ElnaLexerToken; begin - parser_node := 0; + parser_node := nil; token := elna_lexer_peek(cursor); if token^.kind = ElnaLexerKind.character then @@ -2187,7 +2221,8 @@ begin return parser_node end; -proc elna_parser_dereference_expression(cursor: ^ElnaLexerCursor, simple_expression: Word); +proc elna_parser_dereference_expression(cursor: ^ElnaLexerCursor, + simple_expression: ^ElnaTreeExpression) -> ^ElnaTreeDereferenceExpression; var result: ^ElnaTreeDereferenceExpression; begin @@ -2201,9 +2236,9 @@ begin return result end; -proc elna_parser_designator(cursor: ^ElnaLexerCursor); +proc elna_parser_designator(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression; var - simple_expression: Word; + simple_expression: ^ElnaTreeExpression; token: ^ElnaLexerToken; begin simple_expression := elna_parser_simple_expression(cursor); @@ -2234,7 +2269,7 @@ var parser_node: ^ElnaTreeNamedTypeExpression; begin parser_node := trait_node^.argument; - symbol := elna_symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length); + symbol := elna_symbol_table_lookup(symbol_table_global, parser_node^.name, parser_node^.length); info_type := symbol^._type; operand^.kind := ElnaTacKind.constant; @@ -2262,7 +2297,7 @@ begin end end; -proc elna_parser_unary_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_unary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression; var result: ^ElnaTreeUnaryExpression; operand: Word; @@ -2322,7 +2357,8 @@ begin end end; -proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); +proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression, + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); var token_kind: Word; operator: Word; @@ -2379,10 +2415,10 @@ begin end end; -proc elna_parser_binary_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_binary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression; var - lhs_node: Word; - rhs_node: Word; + lhs_node: ^ElnaTreeExpression; + rhs_node: ^ElnaTreeExpression; result: ^ElnaTreeBinaryExpression; token: ^ElnaLexerToken; begin @@ -2433,7 +2469,7 @@ begin elna_lexer_read(cursor); rhs_node := elna_parser_unary_expression(cursor) end; - if rhs_node <> 0 then + if rhs_node <> nil then result := malloc(#size(ElnaTreeBinaryExpression)); result^.kind := ElnaTreeKind.binary_expression; @@ -2555,7 +2591,7 @@ begin end end; -proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: Word); +proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: ^ElnaTreeExpression) -> ^ElnaTreeCall; var result: ^ElnaTreeCall; argument_number: Word; @@ -2603,7 +2639,8 @@ begin return result end; -proc elna_tac_call(instructions: ^ElnaList, parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); +proc elna_tac_call(instructions: ^ElnaList, parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, + operand: ^ElnaTacOperand); var parsed_expression: ^ElnaTreeVariableExpression; arguments_operand: ^ElnaTacOperand; @@ -2633,7 +2670,7 @@ begin elna_list_append(instructions, call_instruction) end; -proc elna_parser_goto_statement(cursor: ^ElnaLexerCursor); +proc elna_parser_goto_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeGotoStatement; var result: ^ElnaTreeGotoStatement; token: ^ElnaLexerToken; @@ -2667,9 +2704,9 @@ begin elna_list_append(instructions, instruction) end; -proc elna_parser_label_declaration(cursor: ^ElnaLexerCursor); +proc elna_parser_label_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeLabelDeclaration; var - result: ^ElnaTreeGotoStatement; + result: ^ElnaTreeLabelDeclaration; token: ^ElnaLexerToken; begin elna_lexer_read(cursor); @@ -2703,7 +2740,7 @@ var enumeration_type_name: ^ElnaTreeVariableExpression; begin enumeration_type_name := field_access_expression^.aggregate; - symbol_info := elna_symbol_table_lookup(@symbol_table_global, + symbol_info := elna_symbol_table_lookup(symbol_table_global, enumeration_type_name^.name, enumeration_type_name^.length); enumeration_type := symbol_info^._type; @@ -2730,7 +2767,8 @@ begin end end; -proc elna_parser_field_access_expression(cursor: ^ElnaLexerCursor, aggregate: Word); +proc elna_parser_field_access_expression(cursor: ^ElnaLexerCursor, + aggregate: ^ElnaTreeExpression) -> ^ElnaTreeFieldAccessExpression; var result: ^ElnaTreeFieldAccessExpression; token: ^ElnaLexerToken; @@ -2750,7 +2788,8 @@ begin return result end; -proc elna_parser_array_access_expression(cursor: ^ElnaLexerCursor, array: Word); +proc elna_parser_array_access_expression(cursor: ^ElnaLexerCursor, + array: ^ElnaTreeExpression) -> ^ElnaTreeArrayAccessExpression; var result: ^ElnaTreeArrayAccessExpression; begin @@ -2909,7 +2948,7 @@ begin elna_list_append(instructions, instruction) end; -proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: Word); +proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: ^ElnaTreeNode) -> ^ElnaTreeAssignStatement; var result: ^ElnaTreeAssignStatement; begin @@ -2960,9 +2999,9 @@ begin elna_list_append(instructions, instruction) end; -proc elna_parser_return_statement(cursor: ^ElnaLexerCursor); +proc elna_parser_return_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeReturnStatement; var - returned: Word; + returned: ^ElnaTreeExpression; label_length: Word; result: ^ElnaTreeReturnStatement; begin @@ -3009,7 +3048,7 @@ begin fflush(nil) end; -proc elna_parser_conditional_statements(cursor: ^ElnaLexerCursor); +proc elna_parser_conditional_statements(cursor: ^ElnaLexerCursor) -> ^ElnaTreeConditionalStatements; var result: ^ElnaTreeConditionalStatements; begin @@ -3056,7 +3095,7 @@ begin elna_tac_label(instructions, condition_label, 0) end; -proc elna_parser_if_statement(cursor: ^ElnaLexerCursor); +proc elna_parser_if_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeIfStatement; var result: ^ElnaTreeIfStatement; previous_conditional: ^ElnaTreeConditionalStatements; @@ -3091,9 +3130,10 @@ begin return result end; -proc elna_parser_statement(cursor: ^ElnaLexerCursor); +proc elna_parser_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement; var - result : ^ElnaTreeNode; + result: ^ElnaTreeStatement; + designator: ^ElnaTreeNode; token: ^ElnaLexerToken; begin result := nil; @@ -3108,10 +3148,12 @@ begin elsif token^.kind = ElnaLexerKind.dot then result := elna_parser_label_declaration(cursor) elsif token^.kind = ElnaLexerKind.identifier then - result := elna_parser_designator(cursor); + designator := elna_parser_designator(cursor); - if result^.kind <> ElnaTreeKind.call then - result := elna_parser_assign_statement(cursor, result) + if designator^.kind <> ElnaTreeKind.call then + result := elna_parser_assign_statement(cursor, designator) + else + result := designator end end; return result @@ -3224,7 +3266,7 @@ begin _write_c(register_number + '0') end; -proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeRecordTypeExpression; var entry: ^ElnaTreeField; result: ^ElnaTreeRecordTypeExpression; @@ -3273,35 +3315,33 @@ begin return result end; -proc elna_parser_enumeration_type_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_enumeration_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeEnumerationTypeExpression; var - memory_start: Word; - member_count: Word; result: ^ElnaTreeEnumerationTypeExpression; - entry: Word; - previous_entry: Word; + entry: ^ElnaTreeEnumeration; + previous_entry: ^ElnaTreeEnumeration; token: ^ElnaLexerToken; begin elna_lexer_read(cursor); - memory_start := 0; - member_count := 0; + + result := malloc(#size(ElnaTreeEnumerationTypeExpression)); + result^.kind := ElnaTreeKind.enumeration_type_expression; + result^.members := nil; + result^.length := 0; .elna_parser_enumeration_type_expression_loop; token := elna_lexer_read(cursor); - entry := malloc(12); - member_count := member_count + 1; + entry := malloc(#size(ElnaTreeEnumeration)); + result^.length := result^.length + 1; - entry^ := token^.start; - entry := entry + 4; + entry^.name := token^.start; + entry^.length := token^.length; + entry^.next := nil; - entry^ := token^.length; - entry := entry + 4; - - entry^ := 0; - if memory_start = 0 then - memory_start := entry - 8 + if result^.members = nil then + result^.members := entry else - previous_entry^ := entry - 8 + previous_entry^.next := entry end; previous_entry := entry; @@ -3310,12 +3350,6 @@ begin if token^.kind = ElnaLexerKind.comma then goto elna_parser_enumeration_type_expression_loop end; - result := malloc(#size(ElnaTreeEnumerationTypeExpression)); - - result^.kind := ElnaTreeKind.enumeration_type_expression; - result^.members := memory_start; - result^.length := member_count; - return result end; @@ -3331,7 +3365,7 @@ end; * * Returns enumeration type description. *) -proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression); +proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression) -> ^ElnaTypeEnumeration; var result: ^ElnaTypeEnumeration; memory_start: Word; @@ -3373,7 +3407,7 @@ begin return result end; -proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression); +proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression) -> ^ElnaTypePointer; var result: ^ElnaTypePointer; begin @@ -3387,7 +3421,7 @@ begin return result end; -proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression); +proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression) -> ^ElnaTypeArray; var base: ^ElnaType; result: ^ElnaTypeArray; @@ -3409,34 +3443,30 @@ begin return result end; -proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression); +proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression) -> ^ElnaTypeRecord; var result: ^ElnaTypeRecord; - memory_start: Word; - member_count: Word; - member_array_start: Word; + tree_field: ^ElnaTreeField; + member_array_start: ^ElnaTypeField; member_array_current: ^ElnaTypeField; field_type: ^ElnaType; begin result := malloc(#size(ElnaTypeRecord)); + result^.kind := ElnaTypeKind._record; result^.size := 0; result^.alignment := 0; + result^.length := 0; + result^.members := malloc(parser_node^.length * #size(ElnaTypeField)); - memory_start := parser_node^.members; - member_count := parser_node^.length; - - member_array_start := malloc(member_count * #size(ElnaTypeField)); - member_array_current := member_array_start; + tree_field := parser_node^.members; + member_array_current := result^.members; .elna_name_type_record_loop; - if member_count > 0 then - member_array_current^.name := memory_start^; - memory_start := memory_start + 4; + if result^.length < parser_node^.length then + member_array_current^.name := tree_field^.name; + member_array_current^.length := tree_field^.length; - member_array_current^.length := memory_start^; - memory_start := memory_start + 4; - - field_type := elna_name_type_expression(memory_start^); + field_type := elna_name_type_expression(tree_field^.type_expression); result^.size := result^.size + field_type^.size; if field_type^.alignment > result^.alignment then result^.alignment := field_type^.alignment @@ -3444,21 +3474,16 @@ begin member_array_current^.field_type := field_type; member_array_current := member_array_current + 1; - memory_start := memory_start + 4; - memory_start := memory_start^; - member_count := member_count - 1; + tree_field := tree_field^.next; + result^.length := result^.length + 1; goto elna_name_type_record_loop end; - result^.kind := ElnaTypeKind._record; - result^.members := member_array_start; - result^.length := parser_node^.length; - return result end; -proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNamedTypeExpression; var result: ^ElnaTreeNamedTypeExpression; token: ^ElnaLexerToken; @@ -3473,7 +3498,7 @@ begin return result end; -proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreePointerTypeExpression; var result: ^ElnaTreePointerTypeExpression; begin @@ -3486,7 +3511,7 @@ begin return result end; -proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeArrayTypeExpression; var result: ^ElnaTreeArrayTypeExpression; begin @@ -3504,9 +3529,9 @@ begin return result end; -proc elna_parser_type_expression(cursor: ^ElnaLexerCursor); +proc elna_parser_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNode; var - result: Word; + result: ^ElnaTreeNode; token: ^ElnaLexerToken; begin result := nil; @@ -3526,16 +3551,16 @@ begin return result end; -proc elna_name_type_expression(parser_node: ^ElnaTreeNode); +proc elna_name_type_expression(parser_node: ^ElnaTreeNode) -> ^ElnaType; var named_type_expression: ^ElnaTreeNamedTypeExpression; type_symbol: ^ElnaSymbolTypeInfo; - result: Word; + result: ^ElnaType; begin if parser_node^.kind = ElnaTreeKind.named_type_expression then named_type_expression := parser_node; - type_symbol := elna_symbol_table_lookup(@symbol_table_global, + type_symbol := elna_symbol_table_lookup(symbol_table_global, named_type_expression^.name, named_type_expression^.length); result := type_symbol^._type elsif parser_node^.kind = ElnaTreeKind.enumeration_type_expression then @@ -3551,7 +3576,7 @@ begin return result end; -proc type_info_create(type_representation: Word); +proc type_info_create(type_representation: Word) -> ^ElnaSymbolTypeInfo; var result: ^ElnaSymbolTypeInfo; begin @@ -3567,7 +3592,7 @@ end; * attr - Local variable attributes. * temporary_type - Local variable type. *) -proc temporary_info_create(attr: Word, temporary_type: Word); +proc temporary_info_create(attr: Word, temporary_type: ^ElnaType) -> ^ElnaSymbolTemporaryInfo; var result: ^ElnaSymbolTemporaryInfo; begin @@ -3585,7 +3610,7 @@ end; * Parameters: * symbol_table - Local symbol table. *) -proc procedure_info_create(symbol_table: ^ElnaSymbolTable); +proc procedure_info_create(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolProcedureInfo; var result: ^ElnaSymbolProcedureInfo; begin @@ -3699,7 +3724,7 @@ begin return result end; -proc elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word); +proc elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word) -> ^Word; var ast_parameter: ^ElnaTreeDeclaration; parameter_index: Word; @@ -3738,7 +3763,7 @@ begin return parameter_list end; -proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable); +proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable; var result: ^ElnaRtlStaticVariable; begin @@ -3752,7 +3777,7 @@ begin return result end; -proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word); +proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word) -> ^ElnaRtlInstruction; var result: ^ElnaRtlInstruction; instruction: ^ElnaRtlInstruction; @@ -3794,15 +3819,16 @@ begin return lhs or rhs end; -proc elna_rtl_generate_pseudo(operand: ^ElnaRtlOperand, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInfo; +proc elna_rtl_generate_pseudo(operand: ^ElnaRtlOperand, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlObjectInfo; var - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; pseudo_type: ^ElnaRtlTypeWord; buffer: Word; begin operand^.kind := ElnaRtlKind.pseudo; pseudo_counter := pseudo_counter + 1; - pseudo_symbol := malloc(#size(ElnaRtlInfo)); + pseudo_symbol := malloc(#size(ElnaRtlObjectInfo)); + pseudo_symbol^.kind := ElnaRtlInfoKind.object_info; buffer := malloc(7); sprintf(buffer, "$b%i\0", pseudo_counter); @@ -3820,28 +3846,27 @@ begin return pseudo_symbol end; -proc elna_rtl_symbol_table(symbol_table: ^ElnaSymbolTable); +proc elna_rtl_symbol_table(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolTable; var variable_map: ^ElnaSymbolTable; count: Word; current_entry: ^ElnaSymbolEntry; - pseudo_symbol: ^ElnaRtlInfo; + pseudo_symbol: ^ElnaRtlObjectInfo; variable_info: ^ElnaSymbolTemporaryInfo; byte_array: ^ElnaRtlTypeByteArray; long_word: ^ElnaRtlTypeWord; begin - variable_map := malloc(16384); - variable_map^.count := 0; - + variable_map := elna_symbol_table_create(); count := symbol_table^.count; - current_entry := @symbol_table^.symbols; + current_entry := symbol_table^.symbols; .elna_rtl_symbol_table_loop; if count > 0 then variable_info := current_entry^.symbol_info; - pseudo_symbol := malloc(#size(ElnaRtlInfo)); + pseudo_symbol := malloc(#size(ElnaRtlObjectInfo)); pseudo_symbol^.allocated := false; + pseudo_symbol^.kind := ElnaRtlInfoKind.object_info; if elna_type_is_aggregate(variable_info^.variable_type) then byte_array := malloc(#size(ElnaRtlTypeByteArray)); @@ -3867,7 +3892,7 @@ begin return variable_map; end; -proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure); +proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure) -> ^ElnaRtlProcedure; var result: ^ElnaRtlProcedure; begin @@ -3887,7 +3912,7 @@ begin return result end; -proc elna_tac_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration); +proc elna_tac_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) -> ^ElnaTacProcedure; var symbol_info: ^ElnaSymbolProcedureInfo; result: ^ElnaTacProcedure; @@ -3902,7 +3927,7 @@ begin result^.name := parser_node^.name; result^.length := parser_node^.length; - symbol_info := elna_symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length); + symbol_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name, parser_node^.length); result^.symbol_table := symbol_info^.symbol_table; @@ -3943,7 +3968,7 @@ begin return result end; -proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable); +proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable; var current_copy: ^ElnaRtlStaticVariable; next_copy: ^ElnaRtlStaticVariable; @@ -3971,7 +3996,7 @@ begin return first_copy end; -proc elna_rtl_procedures(tac_procedure: ^ElnaTacProcedure); +proc elna_rtl_procedures(tac_procedure: ^ElnaTacProcedure) -> ^ElnaRtlProcedure; var current_copy: ^ElnaRtlProcedure; next_copy: ^ElnaRtlProcedure; @@ -4043,7 +4068,7 @@ begin end end; -proc elna_parser_type_declaration(cursor: ^ElnaLexerCursor); +proc elna_parser_type_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeTypeDeclaration; var result: ^ElnaTreeTypeDeclaration; token: ^ElnaLexerToken; @@ -4066,25 +4091,20 @@ end; proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration); var - type_name: Word; - name_length: Word; - type_info: Word; + symbol_type: ^ElnaType; + type_info: ^ElnaSymbolTypeInfo; begin - type_name := parser_node^.name; - name_length := parser_node^.length; + symbol_type := elna_name_type_expression(parser_node^._type); + type_info := type_info_create(symbol_type); - parser_node := parser_node^._type; - type_info := elna_name_type_expression(parser_node); - type_info := type_info_create(type_info); - - elna_symbol_table_enter(@symbol_table_global, type_name, name_length, type_info) + elna_symbol_table_enter(symbol_table_global, parser_node^.name, parser_node^.length, type_info) end; proc elna_type_type_declaration(parser_node: Word); begin end; -proc elna_parser_type_part(cursor: ^ElnaLexerCursor); +proc elna_parser_type_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration; var parser_node: ^ElnaTreeDeclaration; result: ^ElnaTreeDeclaration; @@ -4120,7 +4140,7 @@ begin return result end; -proc elna_parser_variable_declaration(cursor: ^ElnaLexerCursor); +proc elna_parser_variable_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableDeclaration; var variable_type: Word; result: ^ElnaTreeVariableDeclaration; @@ -4143,13 +4163,13 @@ begin return result end; -proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration); +proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration) -> ^ElnaTacStaticVariable; var result: ^ElnaTacStaticVariable; variable_info: ^ElnaSymbolTemporaryInfo; begin result := malloc(#size(ElnaTacStaticVariable)); - variable_info := elna_symbol_table_lookup(@symbol_table_global, parser_tree^.name, parser_tree^.length); + variable_info := elna_symbol_table_lookup(symbol_table_global, parser_tree^.name, parser_tree^.length); result^.next := nil; result^.name := parser_tree^.name; @@ -4159,14 +4179,14 @@ begin return result end; -proc elna_parser_var_part(cursor: ^ElnaLexerCursor); +proc elna_parser_var_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration; var - result: Word; - variable_node: Word; + result: ^ElnaTreeDeclaration; + variable_node: ^ElnaTreeDeclaration; current_declaration: ^ElnaTreeDeclaration; token: ^ElnaLexerToken; begin - result := 0; + result := nil; token := elna_lexer_peek(cursor); if token^.kind <> ElnaLexerKind._var then @@ -4185,7 +4205,7 @@ begin (* Skip semicolon. *) elna_lexer_read(cursor); - if result = 0 then + if result = nil then result := variable_node else current_declaration^.next := variable_node @@ -4198,20 +4218,20 @@ begin return result end; -proc elna_tac_var_part(parser_node: ^ElnaTreeDeclaration); +proc elna_tac_var_part(parser_node: ^ElnaTreeDeclaration) -> ^ElnaTacStaticVariable; var node: ^ElnaTacStaticVariable; current_variable: ^ElnaTacStaticVariable; first_variable: ^ElnaTacStaticVariable; begin - first_variable := 0; - if parser_node = 0 then + first_variable := nil; + if parser_node = nil then goto elna_tac_var_part_end end; .elna_tac_var_part_loop; node := elna_tac_variable_declaration(parser_node); - if first_variable = 0 then + if first_variable = nil then first_variable := node else current_variable^.next := node @@ -4219,7 +4239,7 @@ begin current_variable := node; parser_node := parser_node^.next; - if parser_node <> 0 then + if parser_node <> nil then goto elna_tac_var_part_loop end; @@ -4273,7 +4293,7 @@ begin return result end; -proc elna_tac_program_body(parser_node: ^ElnaTreeStatement); +proc elna_tac_program_body(parser_node: ^ElnaTreeStatement) -> ^ElnaTacProcedure; var result: ^ElnaTacProcedure; symbol_info: ^ElnaSymbolProcedureInfo; @@ -4286,7 +4306,7 @@ begin result^.name := "main"; result^.length := 4; - symbol_info := elna_symbol_table_lookup(@symbol_table_global, "main", 4); + symbol_info := elna_symbol_table_lookup(symbol_table_global, "main", 4); result^.symbol_table := symbol_info^.symbol_table; @@ -4298,7 +4318,7 @@ begin return result end; -proc elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration); +proc elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) -> ^ElnaInstructionModule; var result: ^ElnaInstructionModule; code: ^ElnaTacProcedure; @@ -4338,7 +4358,7 @@ begin elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table); elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table); - elna_symbol_table_enter(@symbol_table_global, parser_node^.name, parser_node^.length, symbol_info) + elna_symbol_table_enter(symbol_table_global, parser_node^.name, parser_node^.length, symbol_info) end; proc elna_name_program_body(parser_node: ^ElnaTreeStatement); @@ -4349,7 +4369,7 @@ begin new_symbol_table := elna_symbol_table_create(); symbol_info := procedure_info_create(new_symbol_table); - elna_symbol_table_enter(@symbol_table_global, "main", 4, symbol_info) + elna_symbol_table_enter(symbol_table_global, "main", 4, symbol_info) end; proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable); @@ -4453,7 +4473,7 @@ proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral); var symbol_info: ^ElnaSymbolTypeInfo; begin - symbol_info := elna_symbol_table_lookup(@symbol_table_global, "Bool", 4); + symbol_info := elna_symbol_table_lookup(symbol_table_global, "Bool", 4); parser_node^.type_decoration := symbol_info^._type end; @@ -4461,7 +4481,7 @@ proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral); var symbol_info: ^ElnaSymbolTypeInfo; begin - symbol_info := elna_symbol_table_lookup(@symbol_table_global, "Pointer", 7); + symbol_info := elna_symbol_table_lookup(symbol_table_global, "Pointer", 7); parser_node^.type_decoration := symbol_info^._type end; @@ -4473,7 +4493,7 @@ begin variable_info := elna_symbol_table_lookup(symbol_table, parser_node^.name, parser_node^.length); if variable_info = nil then - variable_info := elna_symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length) + variable_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name, parser_node^.length) end; if variable_info^.kind = ElnaSymbolInfoKind.temporary_info then temporary_info := variable_info; @@ -4532,7 +4552,7 @@ begin (* Check whether the field access is an enumeration value. *) if variable_expression^.kind = ElnaTreeKind.variable_expression then - symbol_info := elna_symbol_table_lookup(@symbol_table_global, variable_expression^.name, variable_expression^.length); + symbol_info := elna_symbol_table_lookup(symbol_table_global, variable_expression^.name, variable_expression^.length); if symbol_info <> nil then type_kind := symbol_info; @@ -4625,7 +4645,7 @@ proc elna_type_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) var procedure_info: ^ElnaSymbolProcedureInfo; begin - procedure_info := elna_symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length); + procedure_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name, parser_node^.length); elna_type_statements(parser_node^.body, procedure_info^.symbol_table) end; @@ -4645,7 +4665,7 @@ begin current_part := parser_node^.globals; .elna_name_module_declaration_global; if current_part <> nil then - elna_name_procedure_temporary(current_part, @symbol_table_global); + elna_name_procedure_temporary(current_part, symbol_table_global); current_part := current_part^.next; goto elna_name_module_declaration_global @@ -4736,7 +4756,7 @@ begin symbol_table_length := symbol_table^.count; (* Go to the first symbol position. *) - current_entry := @symbol_table^.symbols; + current_entry := symbol_table^.symbols; .symbol_table_lookup_loop; if symbol_table_length = 0 then @@ -4776,7 +4796,8 @@ proc elna_symbol_table_create(); var new_symbol_table: ^ElnaSymbolTable; begin - new_symbol_table := malloc(12288); + new_symbol_table := malloc(#size(ElnaSymbolTable)); + new_symbol_table^.symbols := malloc(16384); new_symbol_table^.count := 0; return new_symbol_table @@ -4796,8 +4817,7 @@ var symbol_pointer: ^ElnaSymbolEntry; begin (* Calculate the offset for the new symbol. *) - symbol_pointer := @symbol_table^.symbols; - symbol_pointer := symbol_pointer + symbol_table^.count; + symbol_pointer := symbol_table^.symbols + symbol_table^.count; symbol_pointer^.name := symbol_name; symbol_pointer^.length := name_length; @@ -4811,9 +4831,10 @@ proc elna_symbol_table_build(); var current_info: ^ElnaSymbolTypeInfo; current_type: ^ElnaType; + global_pointer: ^Word; begin (* Set the table length to 0. *) - symbol_table_global := 0; + symbol_table_global := elna_symbol_table_create(); (* Enter built-in symbols. *) word_type := malloc(#size(ElnaType)); @@ -4821,28 +4842,28 @@ begin word_type^.size := 4; word_type^.alignment := 4; current_info := type_info_create(word_type); - elna_symbol_table_enter(@symbol_table_global, "Word", 4, current_info); + elna_symbol_table_enter(symbol_table_global, "Word", 4, current_info); current_type := malloc(#size(ElnaType)); current_type^.kind := ElnaTypeKind.primitive; current_type^.size := 4; current_type^.alignment := 4; current_info := type_info_create(current_type); - elna_symbol_table_enter(@symbol_table_global, "Pointer", 7, current_info); + elna_symbol_table_enter(symbol_table_global, "Pointer", 7, current_info); current_type := malloc(#size(ElnaType)); current_type^.kind := ElnaTypeKind.primitive; current_type^.size := 1; current_type^.alignment := 1; current_info := type_info_create(current_type); - elna_symbol_table_enter(@symbol_table_global, "Bool", 4, current_info); + elna_symbol_table_enter(symbol_table_global, "Bool", 4, current_info); current_type := malloc(#size(ElnaType)); current_type^.kind := ElnaTypeKind.primitive; current_type^.size := 1; current_type^.alignment := 1; current_info := type_info_create(current_type); - elna_symbol_table_enter(@symbol_table_global, "Char", 4, current_info); + elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info); end;