diff --git a/Rakefile b/Rakefile index 4cb08d0..db9b0fa 100644 --- a/Rakefile +++ b/Rakefile @@ -36,30 +36,19 @@ end desc 'Convert previous stage language into the current stage language' task :convert do - File.open('boot/stage22/cl.elna', 'w') do |current_stage| - seen_proc = false - seen_global_var = false - File.readlines('boot/stage21/cl.elna').each do |line| - seen_proc = true if line.start_with? 'proc' - seen_proc = false if line.start_with? 'end' - if line.start_with?('begin') && !seen_proc - current_stage << <<~FUN - proc f(); - var - x: ElnaRtlObjectInfo; - begin - x.allocated := true - end; + File.open('boot/stage23/cl.elna', 'w') do |current_stage| + seen_var = false - begin - f(); - FUN - elsif line.start_with?('var') && !seen_global_var - current_stage << <<~FUN - var - FUN - elsif line.end_with?("allocated: Word\n") - current_stage << "\t\tallocated: Bool\n" + File.readlines('boot/stage22/cl.elna').each do |line| + if line.start_with? 'var' + seen_var = true + current_stage << "var\n" + elsif line.start_with? 'begin' + seen_var = false + current_stage << "begin\n" + elsif seen_var && line.end_with?(";\n") + current_stage << line[0..-3] + current_stage << "\n" else current_stage << line end diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna index d00c3b6..bd54ecd 100644 --- a/boot/stage21/cl.elna +++ b/boot/stage21/cl.elna @@ -3991,10 +3991,16 @@ begin result^.parameters := parameter_head; (* Skip semicolon or arrow. *) - token := elna_lexer_read(cursor); + token := elna_lexer_peek(cursor); if token^.kind = ElnaLexerKind.arrow then + elna_lexer_read(cursor); result^.return_type := elna_parser_type_expression(cursor); + token := elna_lexer_peek(cursor); + if token^.kind = ElnaLexerKind.semicolon then + elna_lexer_read(cursor) + end + elsif token^.kind = ElnaLexerKind.semicolon then elna_lexer_read(cursor) else result^.return_type := nil @@ -4270,8 +4276,10 @@ begin current_declaration := parser_node; (* Skip semicolon. *) - elna_lexer_read(cursor); - + token := elna_lexer_peek(cursor); + if token^.kind = ElnaLexerKind.semicolon then + elna_lexer_read(cursor) + end; goto elna_parser_procedures_loop end; return result @@ -4393,8 +4401,10 @@ begin elna_lexer_read(cursor); result^.type_expression := elna_parser_type_expression(cursor); - elna_lexer_read(cursor); - + token := elna_lexer_peek(cursor); + if token^.kind = ElnaLexerKind.semicolon then + elna_lexer_read(cursor); + end; return result end; @@ -4512,8 +4522,10 @@ begin variable_node := elna_parser_variable_declaration(cursor); (* Skip semicolon. *) - elna_lexer_read(cursor); - + token := elna_lexer_peek(cursor); + if token^.kind = ElnaLexerKind.semicolon then + elna_lexer_read(cursor) + end; if result = nil then result := variable_node else @@ -6032,4 +6044,4 @@ begin else exit(4) end -end; +end. diff --git a/boot/stage22/cl.elna b/boot/stage22/cl.elna index dafbbf6..80f1520 100644 --- a/boot/stage22/cl.elna +++ b/boot/stage22/cl.elna @@ -10,19 +10,19 @@ program; type ElnaListNode = record next: Word - end; + end ElnaList = record first: ^ElnaListNode; last: ^ElnaListNode - end; + end ElnaLocation = record line: Word; column: Word - end; + end ElnaPosition = record start_location: ElnaLocation; end_location: ElnaLocation - end; + end (** * List of intermediate representation items. @@ -30,47 +30,47 @@ type ElnaInstructionModule = record data: Word; code: Word - end; + end (* Type representation. *) - ElnaTypeKind = (primitive, enumeration, _record, pointer, array); + ElnaTypeKind = (primitive, enumeration, _record, pointer, array) ElnaType = record kind: ElnaTypeKind; size: Word; alignment: Word - end; + end ElnaTypeEnumeration = record kind: ElnaTypeKind; size: Word; alignment: Word; members: Word; length: Word - end; + end ElnaTypeField = record name: ElnaTypeKind; length: Word; field_type: ^ElnaType - end; + end ElnaTypeRecord = record kind: ElnaTypeKind; size: Word; alignment: Word; members: Word; length: Word - end; + end ElnaTypePointer = record kind: ElnaTypeKind; size: Word; alignment: Word; base: ^ElnaType - end; + end ElnaTypeArray = record kind: ElnaTypeKind; size: Word; alignment: Word; base: ^ElnaType; length: Word - end; + end (* Abstract syntax tree nodes. *) ElnaTreeKind = ( @@ -102,73 +102,73 @@ type trait_expression, array_access_expression, _cast - ); + ) ElnaTreeNode = record kind: ElnaTreeKind - end; + end ElnaTreeTypeExpression = record kind: ElnaTreeKind - end; + end ElnaTreeExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType - end; + end ElnaTreeIntegerLiteral = record kind: ElnaTreeKind; type_decoration: ^ElnaType; value: Word - end; + end ElnaTreeCharacterLiteral = record kind: ElnaTreeKind; type_decoration: ^ElnaType; value: ^Char; length: Word - end; + end ElnaTreeNilLiteral = record kind: ElnaTreeKind; type_decoration: ^ElnaType - end; + end ElnaTreeBooleanLiteral = record kind: ElnaTreeKind; type_decoration: ^ElnaType; value: Word - end; + end ElnaTreeStringLiteral = record kind: ElnaTreeKind; type_decoration: ^ElnaType; value: Word; length: Word - end; + end ElnaTreeVariableExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; name: Word; length: Word - end; + end ElnaTreeCastExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; expression: ^ElnaTreeExpression; type_expression: ^ElnaTreeTypeExpression - end; + end ElnaTreeDereferenceExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; pointer: Word - end; + end ElnaTreeBinaryExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; lhs: ^ElnaTreeExpression; rhs: ^ElnaTreeExpression; operator: Word - end; + end ElnaTreeUnaryExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; operand: ^ElnaTreeExpression; operator: Word - end; + end (** * All statements are chained into a list. Next contains a pointer to the next @@ -177,90 +177,90 @@ type ElnaTreeStatement = record kind: ElnaTreeKind; next: Word - end; + end ElnaTreeIfStatement = record kind: ElnaTreeKind; next: Word; conditionals: Word; _else: ^ElnaTreeStatement - end; + end ElnaTreeGotoStatement = record kind: ElnaTreeKind; next: Word; label: Word; length: Word - end; + end ElnaTreeAssignStatement = record kind: ElnaTreeKind; next: Word; assignee: Word; assignment: ^ElnaTreeExpression - end; + end ElnaTreeReturnStatement = record kind: ElnaTreeKind; next: Word; returned: ^ElnaTreeExpression - end; + end ElnaTreeLabelDeclaration = record kind: ElnaTreeKind; next: Word; label: Word; length: Word - end; + end ElnaTreeFieldAccessExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; aggregate: Word; field: Word; length: Word - end; + end ElnaTreeArrayAccessExpression = record kind: ElnaTreeKind; type_decoration: ^ElnaType; array: Word; index: ^ElnaTreeExpression - end; + end ElnaTreeEnumeration = record name: Word; length: Word; next: Word - end; + end ElnaTreeEnumerationTypeExpression = record kind: ElnaTreeKind; members: Word; length: Word - end; + end ElnaTreeField = record name: Word; length: Word; type_expression: ^ElnaTreeTypeExpression; next: Word - end; + end ElnaTreeRecordTypeExpression = record kind: ElnaTreeKind; members: ^ElnaTreeField; length: Word - end; + end ElnaTreeNamedTypeExpression = record kind: ElnaTreeKind; name: Word; length: Word - end; + end ElnaTreePointerTypeExpression = record kind: ElnaTreeKind; base: ^ElnaTreeTypeExpression - end; + end ElnaTreeArrayTypeExpression = record kind: ElnaTreeKind; base: ^ElnaTreeTypeExpression; length: Word - end; + end ElnaTreeTraitExpression = record kind: ElnaTreeKind; name: Word; length: Word; argument: Word - end; + end (** * Conditional statements is a list of pairs: condition and statements. * Used for example to represent if and elsif blocks with beloning statements. @@ -269,13 +269,13 @@ type condition: ^ElnaTreeExpression; statements: ^ElnaTreeStatement; next: Word - end; + end ElnaTreeDeclaration = record kind: ElnaTreeKind; next: Word; name: Word; length: Word - end; + end ElnaTreeProcedureDeclaration = record kind: ElnaTreeKind; next: Word; @@ -285,74 +285,74 @@ type temporaries: Word; parameters: Word; return_type: ^ElnaTreeTypeExpression - end; + end ElnaTreeModuleDeclaration = record kind: ElnaTreeKind; types: Word; globals: Word; procedures: ^ElnaTreeProcedureDeclaration; body: ^ElnaTreeStatement - end; + end ElnaTreeTypeDeclaration = record kind: ElnaTreeKind; next: Word; name: Word; length: Word; type_expression: ^ElnaTreeTypeExpression - end; + end ElnaTreeVariableDeclaration = record kind: ElnaTreeKind; next: Word; name: Word; length: Word; type_expression: Word - end; + end ElnaTreeExpressionList = record expression: ^ElnaTreeBinaryExpression; next: Word - end; + end ElnaTreeCall = record kind: ElnaTreeKind; next: Word; callee: ^ElnaTreeVariableExpression; arguments: ^ElnaTreeExpressionList; count: Word - end; + end (* Symbol table information. *) ElnaSymbolEntry = record name: Word; length: Word; symbol_info: Word - end; + end ElnaSymbolTable = record count: Word; parent: Word; symbols: ^ElnaSymbolEntry - end; - ElnaSymbolInfoKind = (type_info, temporary_info, procedure_info); + end + ElnaSymbolInfoKind = (type_info, temporary_info, procedure_info) ElnaSymbolInfo = record kind: ElnaSymbolInfoKind - end; + end ElnaSymbolTypeInfo = record kind: ElnaSymbolInfoKind; _type: ^ElnaType - end; + end ElnaSymbolTemporaryInfo = record kind: ElnaSymbolInfoKind; attr: Word; variable_type: ^ElnaType - end; + end ElnaSymbolProcedureInfo = record kind: ElnaSymbolInfoKind; symbol_table: ^ElnaSymbolTable - end; + end ElnaError = record next: Word - end; + end - ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited); + ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited) ElnaLexerState = ( start, colon, @@ -373,12 +373,12 @@ type number_sign, trait, finish - ); + ) ElnaLexerTransition = record action: ElnaLexerAction; next_state: ElnaLexerState - end; + end (** * Classification table assigns each possible character to a group (class). All * characters of the same group a handled equivalently. @@ -407,7 +407,7 @@ type less, other, number_sign - ); + ) ElnaLexerKind = ( identifier, _const, @@ -472,20 +472,20 @@ type word, _goto, eof - ); + ) ElnaLexerToken = record kind: ElnaLexerKind; start: Word; length: Word; position: ElnaPosition - end; + end ElnaLexerCursor = record state: ElnaLexerState; start: ^Char; finish: ^Char; token: ^ElnaLexerToken; position: ElnaPosition - end; + end ElnaTacOperator = ( get_address, @@ -518,8 +518,8 @@ type _return, add_ptr, nop - ); - ElnaTacKind = (list, label, constant, variable); + ) + ElnaTacKind = (list, label, constant, variable) (* - If value is a variable or label, length is its name length. @@ -530,12 +530,12 @@ type kind: ElnaTacKind; value: Word; length: Word - end; + end ElnaTacInstruction = record next: Word; operator: ElnaTacOperator; operands: [4]ElnaTacOperand - end; + end ElnaTacProcedure = record next: Word; name: Word; @@ -544,18 +544,18 @@ type parameters: Word; count: Word; symbol_table: ^ElnaSymbolTable - end; + end ElnaTacStaticVariable = record next: Word; name: Word; length: Word; body: Word - end; - ElnaTacOperandType = (plain_object, dereferenced_pointer, sub_object); + end + ElnaTacOperandType = (plain_object, dereferenced_pointer, sub_object) ElnaTacOperandResult = record kind: ElnaTacOperandType; offset: Word - end; + end ElnaRtlOperator = ( li, @@ -586,45 +586,45 @@ type allocate_stack, ret, nop - ); - ElnaRtlKind = (register, immediate, data, pseudo, memory, pseudo_mem); + ) + ElnaRtlKind = (register, immediate, data, pseudo, memory, pseudo_mem) ElnaRtlOperand = record kind: ElnaRtlKind; value: Word; length: Word; offset: Word - end; + end ElnaRtlStaticVariable = record next: Word; name: Word; length: Word; body: Word - end; + end ElnaRtlProcedure = record next: Word; name: Word; length: Word; body: ElnaList; variable_map: ^ElnaSymbolTable - end; - ElnaRtlTypeKind = (byte, long_word, byte_array); + end + ElnaRtlTypeKind = (byte, long_word, byte_array) ElnaRtlType = record kind: ElnaRtlTypeKind - end; + end ElnaRtlTypeWord = record kind: ElnaRtlTypeKind - end; + end ElnaRtlTypeByteArray = record kind: ElnaRtlTypeKind; size: Word; alignment: Word - end; + end ElnaRtlInstruction = record next: Word; operator: ElnaRtlOperator; operands: [3]ElnaRtlOperand; types: [2]^ElnaRtlType - end; + end ElnaRtlRegister = ( zero, ra, @@ -658,44 +658,44 @@ type t4, t5, t6 - ); - ElnaRtlInfoKind = (object_info, static_info); + ) + ElnaRtlInfoKind = (object_info, static_info) ElnaRtlInfo = record kind: ElnaRtlInfoKind - end; + end ElnaRtlStaticInfo = record kind: ElnaRtlInfoKind; rtl_type: ^ElnaRtlType - end; + end ElnaRtlObjectInfo = record kind: ElnaRtlInfoKind; rtl_type: ^ElnaRtlType; counter: Word; allocated: Bool - end; + end var - symbol_table_global: ^ElnaSymbolTable; - variable_map_global: ^ElnaSymbolTable; - compiler_strings: [1024]Word; + symbol_table_global: ^ElnaSymbolTable + variable_map_global: ^ElnaSymbolTable + compiler_strings: [1024]Word - classification: [256]Word; + classification: [256]Word (** * Lexer state is saved after the transition tables. * Each transition table entry is 8 bytes long. The table has 19 rows (transition states) * and 23 columns (character classes), so 3496 = 8 * 19 * 23. *) - transition_table: [19][23]ElnaLexerTransition; - word_type: ^ElnaType; - char_type: ^ElnaType; - bool_type: ^ElnaType; + transition_table: [19][23]ElnaLexerTransition + word_type: ^ElnaType + char_type: ^ElnaType + bool_type: ^ElnaType - source_code: Word; - compiler_strings_position: ^Char; - compiler_strings_length: Word; - label_counter: Word; - temporary_variable_counter: Word; - pseudo_counter: Word; + source_code: Word + compiler_strings_position: ^Char + compiler_strings_length: Word + label_counter: Word + temporary_variable_counter: Word + pseudo_counter: Word (** * Adds a string to the global, read-only string storage. @@ -705,12 +705,12 @@ var * * Returns the offset from the beginning of the storage to the new string in a0. *) -proc _add_string(string: ^Char) -> Word; +proc _add_string(string: ^Char) -> Word var - contents: Word; - result: Word; - current_byte: Char; - length_to_copy: Word; + contents: Word + result: Word + current_byte: Char + length_to_copy: Word begin contents := string + 1; result := compiler_strings_length; @@ -731,7 +731,7 @@ begin compiler_strings_position := compiler_strings_position + length_to_copy; return result -end; +end (** * Writes to the standard output. @@ -740,10 +740,10 @@ end; * buffer - Buffer. * size - Buffer length. *) -proc _write_s(buffer: Word, size: Word); +proc _write_s(buffer: Word, size: Word) begin write(1, buffer, size) -end; +end (** * Writes a number to the standard output. @@ -751,11 +751,11 @@ end; * Parameters: * number - Whole number. *) -proc _write_i(number: Word); +proc _write_i(number: Word) begin printf("%i\0", number); fflush(nil) -end; +end (** * Writes a character from a0 into the standard output. @@ -763,21 +763,21 @@ end; * Parameters: * character - Character to write. *) -proc _write_c(character: Word); +proc _write_c(character: Word) begin write(1, @character, 1) -end; +end -proc elna_list_initialize(list: ^ElnaList); +proc elna_list_initialize(list: ^ElnaList) begin list^.first := nil; list^.last := nil -end; +end (** * Appends a new element to the end of the list. *) -proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode) -> ^ElnaListNode; +proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode) -> ^ElnaListNode begin if element <> nil then if list^.first = nil then @@ -788,24 +788,24 @@ begin list^.last := element end; return element -end; +end (** * Prepends a new element to the beginning of the given list. *) -proc elna_list_prepend(list: ^ElnaList, element: ^ElnaListNode); +proc elna_list_prepend(list: ^ElnaList, element: ^ElnaListNode) begin element^.next := list^.first; list^.first := element; if list^.last = nil then list^.last := element end -end; +end (** * Inserts a new element after an existing one into the given list. *) -proc elna_list_insert(list: ^ElnaList, existing: ^ElnaListNode, new: ^ElnaListNode); +proc elna_list_insert(list: ^ElnaList, existing: ^ElnaListNode, new: ^ElnaListNode) begin if existing^.next = nil then list^.last := new @@ -813,12 +813,12 @@ begin new^.next := existing^.next end; existing^.next := new -end; +end -proc elna_tac_make_variable(operand: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, variable_type: ^ElnaType); +proc elna_tac_make_variable(operand: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, variable_type: ^ElnaType) var - buffer: Word; - temporary_info: ^ElnaSymbolTemporaryInfo; + buffer: Word + temporary_info: ^ElnaSymbolTemporaryInfo begin pseudo_counter := pseudo_counter + 1; buffer := malloc(7); @@ -831,18 +831,18 @@ begin temporary_info := temporary_info_create(1, variable_type); elna_symbol_table_enter(symbol_table, buffer, operand^.length, temporary_info) -end; +end -proc elna_tac_instruction_set_operand(this: ^ElnaTacInstruction, n: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc elna_tac_instruction_set_operand(this: ^ElnaTacInstruction, n: Word, operand_type: Word, operand_value: Word, operand_length: Word) begin this^.operands[n].kind := operand_type; this^.operands[n].value := operand_value; this^.operands[n].length := operand_length -end; +end -proc elna_tac_instruction_create(kind: Word) -> ^ElnaTacInstruction; +proc elna_tac_instruction_create(kind: Word) -> ^ElnaTacInstruction var - result: ^ElnaTacInstruction; + result: ^ElnaTacInstruction begin result := malloc(#size(ElnaTacInstruction)); @@ -850,11 +850,11 @@ begin result^.next := nil; return result -end; +end -proc elna_rtl_instruction_create(operator: ElnaRtlOperator) -> ^ElnaRtlInstruction; +proc elna_rtl_instruction_create(operator: ElnaRtlOperator) -> ^ElnaRtlInstruction var - result: ^ElnaRtlInstruction; + result: ^ElnaRtlInstruction begin result := malloc(#size(ElnaRtlInstruction)); @@ -864,24 +864,24 @@ begin result^.types[2] := nil; return result -end; +end proc elna_rtl_instruction_set_operand(this: ^ElnaRtlInstruction, n: Word, operand_type: Word, - operand_value: Word, operand_length: Word, operand_offset: Word); + operand_value: Word, operand_length: Word, operand_offset: Word) begin this^.operands[n].kind := operand_type; this^.operands[n].value := operand_value; this^.operands[n].length := operand_length; this^.operands[n].offset := operand_offset -end; +end (** * Loads or moves the value from a TAC operand into the given register. *) proc elna_rtl_hardware_value(instructions: ^ElnaList, operand: ^ElnaTacOperand, - into: ElnaRtlRegister, variable_map: ^ElnaSymbolTable); + into: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction begin if operand^.kind = ElnaTacKind.constant then instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); @@ -894,14 +894,14 @@ begin elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length, 0); elna_list_append(instructions, instruction) end -end; +end proc elna_rtl_operand_value(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, variable_map: ^ElnaSymbolTable, - rtl_operand: ^ElnaRtlOperand) -> ^ElnaRtlInfo; + rtl_operand: ^ElnaRtlOperand) -> ^ElnaRtlInfo var - instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlObjectInfo; - rtl_type: ^ElnaRtlType; + instruction: ^ElnaRtlInstruction + pseudo_symbol: ^ElnaRtlObjectInfo + rtl_type: ^ElnaRtlType begin pseudo_symbol := nil; @@ -929,13 +929,13 @@ begin end end; return pseudo_symbol -end; +end proc elna_rtl_binary_arithmetic(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, - operation: ElnaRtlOperator, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + operation: ElnaRtlOperator, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - result: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; + result: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand begin result := elna_rtl_instruction_create(operation); elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.pseudo, @@ -949,14 +949,14 @@ begin elna_list_append(instructions, result); return result -end; +end -proc elna_rtl_add_ptr(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_add_ptr(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - result: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; - intermediate: ElnaRtlOperand; - rtl_type: ^ElnaRtlType; + result: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand + intermediate: ElnaRtlOperand + rtl_type: ^ElnaRtlType begin rtl_type := malloc(#size(ElnaRtlTypeWord)); rtl_type^.kind := ElnaRtlTypeKind.long_word; @@ -982,13 +982,13 @@ begin elna_rtl_instruction_set_operand(result, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); elna_rtl_instruction_set_operand(result, 3, intermediate.kind, intermediate.value, intermediate.length, 0); elna_list_append(instructions, result) -end; +end proc elna_rtl_binary_equality(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, - instruction_kind: ElnaRtlOperator, variable_map: ^ElnaSymbolTable); + instruction_kind: ElnaRtlOperator, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - target_operand: ^ElnaRtlOperand; + instruction: ^ElnaRtlInstruction + target_operand: ^ElnaRtlOperand begin instruction := elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._xor, variable_map); target_operand := @instruction^.operands[1]; @@ -997,13 +997,13 @@ begin elna_rtl_instruction_set_operand(instruction, 1, target_operand^.kind, target_operand^.value, target_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) -end; +end proc elna_rtl_set_less_than(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, - lhs: Word, rhs: Word, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + lhs: Word, rhs: Word, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - slt_instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; + slt_instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand begin slt_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); elna_rtl_instruction_set_operand(slt_instruction, 1, ElnaRtlKind.pseudo, @@ -1017,14 +1017,14 @@ begin elna_list_append(instructions, slt_instruction); return slt_instruction -end; +end proc elna_rtl_binary_comparison(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, - lhs: Word, rhs: Word, variable_map: ^ElnaSymbolTable); + lhs: Word, rhs: Word, variable_map: ^ElnaSymbolTable) var - slt_instruction: ^ElnaRtlInstruction; - xor_instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; + slt_instruction: ^ElnaRtlInstruction + xor_instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand begin slt_instruction := elna_rtl_set_less_than(instructions, tac_instruction, lhs, rhs, variable_map); @@ -1036,13 +1036,13 @@ begin elna_rtl_instruction_set_operand(xor_instruction, 3, ElnaRtlKind.immediate, 1, 0, 0); elna_list_append(instructions, xor_instruction) -end; +end proc elna_rtl_operand_address(variable_map: ^ElnaSymbolTable, - addressable: ^ElnaTacOperand, target_operand: ^ElnaRtlOperand) -> ^ElnaRtlInstruction; + addressable: ^ElnaTacOperand, target_operand: ^ElnaRtlOperand) -> ^ElnaRtlInstruction var - pseudo_symbol: ^ElnaRtlObjectInfo; - instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlObjectInfo + instruction: ^ElnaRtlInstruction begin pseudo_symbol := elna_symbol_table_lookup(variable_map, addressable^.value, addressable^.length); instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); @@ -1065,12 +1065,12 @@ begin addressable^.value, addressable^.length, 0) end; return instruction -end; +end -proc elna_rtl_get_address(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_get_address(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; + instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand begin rtl_operand.kind := ElnaRtlKind.pseudo; rtl_operand.value := tac_instruction^.operands[2].value; @@ -1078,13 +1078,13 @@ begin instruction := elna_rtl_operand_address(variable_map, @tac_instruction^.operands[1], @rtl_operand); elna_list_append(instructions, instruction) -end; +end proc elna_rtl_conditional_jump(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, - condition: ElnaRtlOperator, variable_map: ^ElnaSymbolTable); + condition: ElnaRtlOperator, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; + instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand begin instruction := elna_rtl_instruction_create(condition); elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); @@ -1093,12 +1093,12 @@ begin tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); elna_list_append(instructions, instruction) -end; +end -proc elna_rtl_unary(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, rtl_operator: ElnaRtlOperator, variable_map: ^ElnaSymbolTable); +proc elna_rtl_unary(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, rtl_operator: ElnaRtlOperator, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; + instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand begin elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); @@ -1108,14 +1108,14 @@ begin 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_call(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_call(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - argument_count: Word; - current_argument: ^ElnaTacOperand; - instruction: ^ElnaRtlInstruction; - current_register: Word; + argument_count: Word + current_argument: ^ElnaTacOperand + instruction: ^ElnaRtlInstruction + current_register: Word begin current_register := 0; current_argument := tac_instruction^.operands[2].value; @@ -1142,14 +1142,14 @@ begin tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); elna_list_append(instructions, instruction) -end; +end -proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; - pseudo_symbol: ^ElnaRtlObjectInfo; - rtl_type: ^ElnaRtlType; + instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand + pseudo_symbol: ^ElnaRtlObjectInfo + rtl_type: ^ElnaRtlType begin if tac_instruction^.operands[1].kind = ElnaTacKind.variable then pseudo_symbol := elna_symbol_table_lookup(variable_map, @@ -1186,16 +1186,16 @@ begin instruction^.types[1] := rtl_type; elna_list_append(instructions, instruction) end; -end; +end -proc elna_rtl_copy_to_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_copy_to_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - target_operand: ElnaRtlOperand; - source_operand: ElnaRtlOperand; - pseudo_symbol: ^ElnaRtlObjectInfo; - rtl_type: ^ElnaRtlType; - address_type: ^ElnaRtlType; + instruction: ^ElnaRtlInstruction + target_operand: ElnaRtlOperand + source_operand: ElnaRtlOperand + pseudo_symbol: ^ElnaRtlObjectInfo + rtl_type: ^ElnaRtlType + address_type: ^ElnaRtlType begin if tac_instruction^.operands[1].kind = ElnaTacKind.variable then pseudo_symbol := elna_symbol_table_lookup(variable_map, @@ -1226,7 +1226,6 @@ begin elna_list_append(instructions, instruction); elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type); - rtl_type := nil end end; @@ -1244,13 +1243,13 @@ begin instruction^.types[1] := rtl_type; elna_list_append(instructions, instruction) end -end; +end -proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; - pseudo_symbol: ^ElnaRtlObjectInfo; + instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand + pseudo_symbol: ^ElnaRtlObjectInfo begin elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); pseudo_symbol := elna_symbol_table_lookup(variable_map, @@ -1278,13 +1277,13 @@ begin elna_list_append(instructions, instruction) end -end; +end -proc elna_rtl_copy_from_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_copy_from_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; - pseudo_symbol: ^ElnaRtlObjectInfo; + instruction: ^ElnaRtlInstruction + rtl_operand: ElnaRtlOperand + pseudo_symbol: ^ElnaRtlObjectInfo begin pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length); @@ -1325,11 +1324,11 @@ begin elna_list_append(instructions, instruction); instruction^.types[1] := pseudo_symbol^.rtl_type end -end; +end -proc elna_rtl_memcpy(instructions: ^ElnaList, byte_array: ^ElnaRtlTypeByteArray); +proc elna_rtl_memcpy(instructions: ^ElnaList, byte_array: ^ElnaRtlTypeByteArray) var - instruction: ElnaRtlInstruction; + instruction: ElnaRtlInstruction begin instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a2, 0, 0); @@ -1339,13 +1338,13 @@ begin 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_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; - source_operand: ElnaRtlOperand; - pseudo_symbol: ^ElnaRtlObjectInfo; + instruction: ^ElnaRtlInstruction + source_operand: ElnaRtlOperand + pseudo_symbol: ^ElnaRtlObjectInfo begin pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); @@ -1372,11 +1371,11 @@ begin elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type) end -end; +end -proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction begin if tac_instruction^.operator = ElnaTacOperator.get_address then elna_rtl_get_address(instructions, tac_instruction, variable_map) @@ -1452,21 +1451,21 @@ begin tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0); elna_list_append(instructions, instruction) end -end; +end -proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word); +proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word) var - result: ^ElnaTacInstruction; + result: ^ElnaTacInstruction begin result := elna_tac_instruction_create(ElnaTacOperator.label); elna_tac_instruction_set_operand(result, 1, ElnaTacKind.label, counter, length); elna_list_append(instructions, result) -end; +end proc elna_riscv_instruction_name(instruction_kind: ElnaRtlOperator, - source_type: ^ElnaRtlType, destination_type: ^ElnaRtlType) -> Word; + source_type: ^ElnaRtlType, destination_type: ^ElnaRtlType) -> Word var - argument_count: Word; + argument_count: Word begin if instruction_kind = ElnaRtlOperator.li then argument_count := 2; @@ -1550,17 +1549,17 @@ begin _write_s("\tbnez", 5) end; return argument_count -end; +end -proc elna_riscv_register(register: Word); +proc elna_riscv_register(register: Word) begin printf("x%i\0", register - 1); fflush(nil) -end; +end -proc elna_riscv_operand(instruction: ^ElnaRtlInstruction, n: Word); +proc elna_riscv_operand(instruction: ^ElnaRtlInstruction, n: Word) var - operand_type: Word; + operand_type: Word begin operand_type := instruction^.operands[n].kind; @@ -1583,14 +1582,14 @@ begin else _write_s(instruction^.operands[n].value, instruction^.operands[n].length) end -end; +end proc elna_alloc_variable(operand_value: Word, operand_length: Word, - variable_map: ^ElnaSymbolTable) -> ^ElnaRtlObjectInfo; + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlObjectInfo var - pseudo_symbol: ^ElnaRtlObjectInfo; - pseudo_type: ^ElnaRtlTypeByteArray; - type_size: Word; + pseudo_symbol: ^ElnaRtlObjectInfo + pseudo_type: ^ElnaRtlTypeByteArray + type_size: Word begin pseudo_symbol := elna_symbol_table_lookup(variable_map, operand_value, operand_length); if pseudo_symbol = nil then @@ -1614,7 +1613,7 @@ begin end; .elna_alloc_variable_end; return pseudo_symbol -end; +end (** * If the first operand of an instruction is an operation target and expected @@ -1622,10 +1621,10 @@ end; * to a temporary register and preserves its value in the following instruction. *) proc elna_alloc_operation_target(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - pseudo_symbol: ^ElnaRtlObjectInfo; - store_instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlObjectInfo + store_instruction: ^ElnaRtlInstruction begin if instruction^.operands[1].kind = ElnaRtlKind.pseudo then store_instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); @@ -1642,11 +1641,11 @@ begin instruction := store_instruction end; return instruction -end; +end -proc elna_alloc_load_address(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_alloc_load_address(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) var - pseudo_symbol: ^ElnaRtlObjectInfo; + pseudo_symbol: ^ElnaRtlObjectInfo begin (* pseudo or pseudo_mem. *) if instruction^.operands[2].kind <> ElnaRtlKind.data then @@ -1664,13 +1663,13 @@ begin if instruction^.operands[1].kind = ElnaRtlKind.pseudo then elna_alloc_operation_target(instructions, instruction, variable_map) end -end; +end proc elna_alloc_store(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - store_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlObjectInfo; + store_instruction: ^ElnaRtlInstruction + pseudo_symbol: ^ElnaRtlObjectInfo begin instruction := elna_alloc_operand(instructions, instruction, 1, ElnaRtlRegister.t0, variable_map); @@ -1696,19 +1695,19 @@ begin instruction := store_instruction end; return instruction -end; +end proc elna_alloc_load(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - new_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlObjectInfo; + new_instruction: ^ElnaRtlInstruction + pseudo_symbol: ^ElnaRtlObjectInfo begin if instruction^.operands[2].kind = ElnaRtlKind.pseudo then pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length, variable_map); new_instruction := malloc(#size(ElnaRtlInstruction)); - memcpy(new_instruction, instruction, #size(ElnaRtlInstruction)); + new_instruction^ := instruction^; new_instruction^.next := nil; elna_rtl_instruction_set_operand(new_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.t0, 0, @@ -1726,20 +1725,20 @@ begin instruction := new_instruction end; return elna_alloc_operation_target(instructions, instruction, variable_map) -end; +end proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - load_instruction: ^ElnaRtlInstruction; - source_operand: ElnaRtlOperand; - target_operand: ElnaRtlOperand; - pseudo_symbol: ^ElnaRtlObjectInfo; - destination_pseudo: Word; - source_pseudo: Word; + load_instruction: ^ElnaRtlInstruction + source_operand: ElnaRtlOperand + target_operand: ElnaRtlOperand + pseudo_symbol: ^ElnaRtlObjectInfo + destination_pseudo: Word + source_pseudo: Word begin - memcpy(@target_operand, @instruction^.operands[1], #size(ElnaRtlOperand)); - memcpy(@source_operand, @instruction^.operands[2], #size(ElnaRtlOperand)); + target_operand := instruction^.operands[1]; + source_operand := instruction^.operands[2]; destination_pseudo := target_operand.kind = ElnaRtlKind.pseudo; source_pseudo := source_operand.kind = ElnaRtlKind.pseudo; @@ -1749,7 +1748,7 @@ begin if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then load_instruction := malloc(#size(ElnaRtlInstruction)); - memcpy(load_instruction, instruction, #size(ElnaRtlInstruction)); + load_instruction^ := instruction^; load_instruction^.next := nil; instruction^.operator = ElnaRtlOperator.la; @@ -1774,7 +1773,7 @@ begin if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then load_instruction := malloc(#size(ElnaRtlInstruction)); - memcpy(load_instruction, instruction, #size(ElnaRtlInstruction)); + load_instruction^ := instruction^; load_instruction^.next := nil; instruction^.operator = ElnaRtlOperator.la; @@ -1798,7 +1797,7 @@ begin if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then load_instruction := malloc(#size(ElnaRtlInstruction)); - memcpy(load_instruction, instruction, #size(ElnaRtlInstruction)); + load_instruction^ := instruction^; load_instruction^.next := nil; instruction^.operator := ElnaRtlOperator.la; @@ -1816,7 +1815,7 @@ begin instruction^.types[1] := pseudo_symbol^.rtl_type end; return instruction -end; +end (** * Move the operand value from the pseudo register into a hardware register if needed. @@ -1824,18 +1823,18 @@ end; * current instruction and returns the new current instruction. *) proc elna_alloc_operand(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - main_instruction: ^ElnaRtlInstruction; - load_instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlObjectInfo; + main_instruction: ^ElnaRtlInstruction + load_instruction: ^ElnaRtlInstruction + pseudo_symbol: ^ElnaRtlObjectInfo begin if instruction^.operands[number].kind = ElnaRtlKind.pseudo then pseudo_symbol := elna_alloc_variable(instruction^.operands[number].value, instruction^.operands[number].length, variable_map); main_instruction := malloc(#size(ElnaRtlInstruction)); - memcpy(main_instruction, instruction, #size(ElnaRtlInstruction)); + main_instruction^ := instruction^; main_instruction^.next := nil; elna_rtl_instruction_set_operand(main_instruction, number, ElnaRtlKind.register, target, 0, 0); @@ -1867,28 +1866,28 @@ begin instruction := main_instruction end; return instruction -end; +end proc elna_alloc_binary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - variable_map: ^ElnaSymbolTable) -> ^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; +end proc elna_alloc_unary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - variable_map: ^ElnaSymbolTable) -> ^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; +end proc elna_alloc_instruction(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, - variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction var - pseudo_symbol: ^ElnaRtlObjectInfo; - new_instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlObjectInfo + new_instruction: ^ElnaRtlInstruction begin if instruction^.operator = ElnaRtlOperator.mv then instruction := elna_alloc_move(instructions, instruction, variable_map) @@ -1946,13 +1945,13 @@ begin elna_alloc_operation_target(instructions, instruction, variable_map) end; return instruction^.next -end; +end -proc elna_riscv_instruction(instruction: ^ElnaRtlInstruction); +proc elna_riscv_instruction(instruction: ^ElnaRtlInstruction) var - argument_count: Word; - current_argument: Word; - operand_value: Word; + argument_count: Word + current_argument: Word + operand_value: Word begin argument_count := 0; @@ -2004,9 +2003,9 @@ begin end; _write_c(10) -end; +end -proc elna_rtl_instructions(instructions: ^ElnaList, instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_instructions(instructions: ^ElnaList, instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable) begin .elna_rtl_instructions_start; if instruction <> nil then @@ -2015,11 +2014,11 @@ begin goto elna_rtl_instructions_start end -end; +end -proc elna_alloc_instructions(instructions: ^ElnaList, variable_map: ^ElnaSymbolTable); +proc elna_alloc_instructions(instructions: ^ElnaList, variable_map: ^ElnaSymbolTable) var - instruction: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction begin instruction := instructions^.first; @@ -2030,9 +2029,9 @@ begin goto elna_alloc_instructions_start end -end; +end -proc elna_riscv_instructions(instruction: ^ElnaRtlInstruction); +proc elna_riscv_instructions(instruction: ^ElnaRtlInstruction) begin .elna_riscv_instructions_start; if instruction <> nil then @@ -2040,11 +2039,11 @@ begin instruction := instruction^.next; goto elna_riscv_instructions_start end -end; +end -proc elna_alloc_procedure(rtl_declaration: ^ElnaRtlProcedure); +proc elna_alloc_procedure(rtl_declaration: ^ElnaRtlProcedure) var - stack_instruction: ^ElnaRtlInstruction; + stack_instruction: ^ElnaRtlInstruction begin .elna_alloc_procedure_loop; temporary_variable_counter := 0; @@ -2064,9 +2063,9 @@ begin if rtl_declaration <> nil then goto elna_alloc_procedure_loop end -end; +end -proc elna_riscv_procedure(procedure: ^ElnaRtlProcedure); +proc elna_riscv_procedure(procedure: ^ElnaRtlProcedure) begin .elna_riscv_procedure_loop; @@ -2084,9 +2083,9 @@ begin if procedure <> nil then goto elna_riscv_procedure_loop end -end; +end -proc elna_riscv_variable(variable: ^ElnaRtlStaticVariable); +proc elna_riscv_variable(variable: ^ElnaRtlStaticVariable) begin .elna_riscv_variable_loop; if variable <> 0 then @@ -2097,16 +2096,16 @@ begin goto elna_riscv_variable_loop end -end; +end -proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule) -> ^ElnaInstructionModule; +proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule) -> ^ElnaInstructionModule var - result: ^ElnaInstructionModule; - count: Word; - current_entry: ^ElnaSymbolEntry; - pseudo_symbol: ^ElnaRtlStaticInfo; - variable_info: ^ElnaSymbolTemporaryInfo; - info: ^ElnaSymbolInfo; + result: ^ElnaInstructionModule + count: Word + current_entry: ^ElnaSymbolEntry + pseudo_symbol: ^ElnaRtlStaticInfo + variable_info: ^ElnaSymbolTemporaryInfo + info: ^ElnaSymbolInfo begin result := malloc(#size(ElnaInstructionModule)); result^.data := elna_rtl_globals(tac_module^.data); @@ -2139,14 +2138,14 @@ begin result^.code := elna_rtl_procedures(tac_module^.code); return result -end; +end -proc elna_alloc_module(pair: ^ElnaInstructionModule); +proc elna_alloc_module(pair: ^ElnaInstructionModule) begin elna_alloc_procedure(pair^.code) -end; +end -proc _align_at(address: Word, alignment: Word) -> Word; +proc _align_at(address: Word, alignment: Word) -> Word begin if address % alignment then address := address + alignment @@ -2155,12 +2154,12 @@ begin address := address * alignment; return address -end; +end -proc elna_fixup_instructions(instructions: ^ElnaList); +proc elna_fixup_instructions(instructions: ^ElnaList) var - instruction: ^ElnaRtlInstruction; - stack_size: Word; + instruction: ^ElnaRtlInstruction + stack_size: Word begin instruction := instructions^.first; @@ -2170,9 +2169,9 @@ begin instruction^.operands[1].value := stack_size; instruction := instructions^.last; instruction^.operands[1].value := stack_size -end; +end -proc elna_fixup_procedure(rtl_declaration: ^ElnaRtlProcedure); +proc elna_fixup_procedure(rtl_declaration: ^ElnaRtlProcedure) begin .elna_fixup_procedure_loop; @@ -2182,18 +2181,18 @@ begin if rtl_declaration <> nil then goto elna_fixup_procedure_loop end -end; +end -proc elna_fixup_module(pair: ^ElnaInstructionModule); +proc elna_fixup_module(pair: ^ElnaInstructionModule) begin elna_fixup_procedure(pair^.code) -end; +end -proc elna_riscv_module(pair: ^ElnaInstructionModule); +proc elna_riscv_module(pair: ^ElnaInstructionModule) var - compiler_strings_copy: ^Char; - compiler_strings_end: ^Char; - current_byte: Char; + compiler_strings_copy: ^Char + compiler_strings_end: ^Char + current_byte: Char begin printf(".globl main\n\n\0"); printf(".section .data\n\0"); @@ -2221,13 +2220,13 @@ begin end; _write_c('"'); _write_c('\n') -end; +end -proc elna_parser_integer_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeIntegerLiteral; +proc elna_parser_integer_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeIntegerLiteral var - token: ^ElnaLexerToken; - result: ^ElnaTreeIntegerLiteral; - buffer: Word; + token: ^ElnaLexerToken + result: ^ElnaTreeIntegerLiteral + buffer: Pointer begin result := malloc(#size(ElnaTreeIntegerLiteral)); token := elna_lexer_read(cursor); @@ -2241,11 +2240,11 @@ begin result^.type_decoration := nil; return result -end; +end -proc elna_parser_boolean_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeBooleanLiteral; +proc elna_parser_boolean_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeBooleanLiteral var - result: ^ElnaTreeBooleanLiteral; + result: ^ElnaTreeBooleanLiteral begin result := malloc(#size(ElnaTreeBooleanLiteral)); @@ -2256,11 +2255,11 @@ begin elna_lexer_read(cursor); return result -end; +end -proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNilLiteral; +proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNilLiteral var - result: ^ElnaTreeNilLiteral; + result: ^ElnaTreeNilLiteral begin elna_lexer_read(cursor); @@ -2269,33 +2268,33 @@ begin result^.type_decoration := nil; return result -end; +end -proc elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, operand: ^ElnaTacOperand); +proc elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, operand: ^ElnaTacOperand) begin operand^.kind := ElnaTacKind.constant; operand^.value := integer_literal_node^.value; operand^.length := 4 -end; +end -proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand: ^ElnaTacOperand); +proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand: ^ElnaTacOperand) begin operand^.kind := ElnaTacKind.constant; operand^.value := boolean_literal_node^.value; operand^.length := 1 -end; +end -proc elna_tac_nil_literal(nil_node: Word, operand: ^ElnaTacOperand); +proc elna_tac_nil_literal(nil_node: Word, operand: ^ElnaTacOperand) begin operand^.kind := ElnaTacKind.constant; operand^.value := 0; operand^.length := 4 -end; +end -proc elna_parser_character_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCharacterLiteral; +proc elna_parser_character_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCharacterLiteral var - result: ^ElnaTreeCharacterLiteral; - token: ^ElnaLexerToken; + result: ^ElnaTreeCharacterLiteral + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeCharacterLiteral)); token := elna_lexer_read(cursor); @@ -2306,12 +2305,12 @@ begin result^.type_decoration := nil; return result -end; +end -proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand: ^ElnaTacOperand); +proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand: ^ElnaTacOperand) var - next_character: Word; - current_position: ^Char; + next_character: Word + current_position: ^Char begin operand^.kind := ElnaTacKind.constant; current_position := character_literal_node^.value + 1; @@ -2360,12 +2359,12 @@ begin operand^.value := next_character end; operand^.length := 1 -end; +end -proc elna_parser_variable_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableExpression; +proc elna_parser_variable_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableExpression var - result: ^ElnaTreeVariableExpression; - token: ^ElnaLexerToken; + result: ^ElnaTreeVariableExpression + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeVariableExpression)); token := elna_lexer_read(cursor); @@ -2376,19 +2375,19 @@ begin result^.type_decoration := nil; return result -end; +end -proc elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, operand: ^ElnaTacOperand); +proc elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, operand: ^ElnaTacOperand) begin operand^.kind := ElnaTacKind.variable; operand^.value := variable_expression^.name; operand^.length := variable_expression^.length -end; +end -proc elna_parser_string_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStringLiteral; +proc elna_parser_string_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStringLiteral var - result: ^ElnaTreeStringLiteral; - token: ^ElnaLexerToken; + result: ^ElnaTreeStringLiteral + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeStringLiteral)); token := elna_lexer_read(cursor); @@ -2399,13 +2398,13 @@ begin result^.type_decoration := nil; return result -end; +end proc elna_tac_string_literal(instructions: ^ElnaList, string_literal_node: ^ElnaTreeStringLiteral, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) var - offset: Word; - instruction: ^ElnaTacInstruction; + offset: Word + instruction: ^ElnaTacInstruction begin offset := _add_string(string_literal_node^.value); @@ -2422,12 +2421,12 @@ begin elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, offset, 4); elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) -end; +end -proc elna_parser_trait_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeTraitExpression; +proc elna_parser_trait_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeTraitExpression var - result: ^ElnaTreeTraitExpression; - token: ^ElnaLexerToken; + result: ^ElnaTreeTraitExpression + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeTraitExpression)); result^.kind := ElnaTreeKind.trait_expression; @@ -2443,12 +2442,12 @@ begin elna_lexer_read(cursor); return result -end; +end -proc elna_parser_cast_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCastExpression; +proc elna_parser_cast_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCastExpression var - result: ^ElnaTreeCastExpression; - token: ^ElnaLexerToken; + result: ^ElnaTreeCastExpression + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeCastExpression)); result^.kind := ElnaTreeKind._cast; @@ -2465,13 +2464,13 @@ begin elna_lexer_read(cursor); return result -end; +end -proc elna_parser_simple_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression; +proc elna_parser_simple_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression var - current_character: Word; - parser_node: ^ElnaTreeExpression; - token: ^ElnaLexerToken; + current_character: Word + parser_node: ^ElnaTreeExpression + token: ^ElnaLexerToken begin parser_node := nil; token := elna_lexer_peek(cursor); @@ -2494,12 +2493,12 @@ begin parser_node := elna_parser_variable_expression(cursor) end; return parser_node -end; +end proc elna_parser_dereference_expression(cursor: ^ElnaLexerCursor, - simple_expression: ^ElnaTreeExpression) -> ^ElnaTreeDereferenceExpression; + simple_expression: ^ElnaTreeExpression) -> ^ElnaTreeDereferenceExpression var - result: ^ElnaTreeDereferenceExpression; + result: ^ElnaTreeDereferenceExpression begin result := malloc(#size(ElnaTreeDereferenceExpression)); @@ -2509,12 +2508,12 @@ begin elna_lexer_read(cursor); return result -end; +end -proc elna_parser_designator(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression; +proc elna_parser_designator(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression var - simple_expression: ^ElnaTreeExpression; - token: ^ElnaLexerToken; + simple_expression: ^ElnaTreeExpression + token: ^ElnaLexerToken begin simple_expression := elna_parser_simple_expression(cursor); @@ -2535,13 +2534,13 @@ begin goto elna_parser_designator_loop end; return simple_expression -end; +end -proc elna_tac_trait_expression(trait_node: ^ElnaTreeTraitExpression, operand: ^ElnaTacOperand); +proc elna_tac_trait_expression(trait_node: ^ElnaTreeTraitExpression, operand: ^ElnaTacOperand) var - symbol: ^ElnaSymbolTypeInfo; - info_type: ^ElnaType; - parser_node: ^ElnaTreeNamedTypeExpression; + symbol: ^ElnaSymbolTypeInfo + info_type: ^ElnaType + parser_node: ^ElnaTreeNamedTypeExpression begin parser_node := trait_node^.argument; symbol := elna_symbol_table_lookup(symbol_table_global, parser_node^.name, parser_node^.length); @@ -2550,16 +2549,16 @@ begin operand^.kind := ElnaTacKind.constant; operand^.value := info_type^.size; operand^.length := 4 -end; +end proc elna_tac_cast_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeCastExpression, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) begin elna_tac_binary_expression(instructions, parser_node^.expression, symbol_table, operand) -end; +end proc elna_tac_simple_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeNode, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) begin if parser_node^.kind = ElnaTreeKind.character_literal then elna_tac_character_literal(parser_node, operand) @@ -2578,14 +2577,14 @@ begin else elna_tac_variable_expression(parser_node, operand) end -end; +end -proc elna_parser_unary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression; +proc elna_parser_unary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression var - result: ^ElnaTreeUnaryExpression; - operand: Word; - operator: Word; - token: ^ElnaLexerToken; + result: ^ElnaTreeUnaryExpression + operand: Word + operator: Word + token: ^ElnaLexerToken begin token := elna_lexer_peek(cursor); operator := 0; @@ -2613,14 +2612,14 @@ begin end; return result -end; +end -proc elna_tac_copy_address(instructions: ^ElnaList, operand_result: ^ElnaTacOperandResult, from: ^ElnaTacOperand, to: ^ElnaTacOperand); +proc elna_tac_copy_address(instructions: ^ElnaList, operand_result: ^ElnaTacOperandResult, from: ^ElnaTacOperand, to: ^ElnaTacOperand) var - instruction: ^ElnaTacInstruction; + instruction: ^ElnaTacInstruction begin if operand_result^.kind = ElnaTacOperandType.dereferenced_pointer then - memmove(to, from, #size(ElnaTacOperand)) + to^ := from^ elsif operand_result^.kind = ElnaTacOperandType.sub_object then instruction := elna_tac_instruction_create(ElnaTacOperator.get_address); elna_tac_instruction_set_operand(instruction, 1, from^.kind, from^.value, from^.length); @@ -2638,18 +2637,18 @@ begin elna_tac_instruction_set_operand(instruction, 2, to^.kind, to^.value, to^.length); elna_list_append(instructions, instruction) end -end; +end proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) var - token_kind: Word; - operator: Word; - unary_operand: ^ElnaTreeExpression; - operand_result: ElnaTacOperandResult; - instruction: ^ElnaTacInstruction; - base: ElnaTacOperand; - temporary_info: ^ElnaSymbolTemporaryInfo; + token_kind: Word + operator: Word + unary_operand: ^ElnaTreeExpression + operand_result: ElnaTacOperandResult + instruction: ^ElnaTacInstruction + base: ElnaTacOperand + temporary_info: ^ElnaSymbolTemporaryInfo begin if parser_node^.kind = ElnaTreeKind.unary_expression then operator := parser_node^.operator; @@ -2697,14 +2696,14 @@ begin operand^.value := base.value; operand^.length := base.length end -end; +end -proc elna_parser_binary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression; +proc elna_parser_binary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression var - lhs_node: ^ElnaTreeExpression; - rhs_node: ^ElnaTreeExpression; - result: ^ElnaTreeBinaryExpression; - token: ^ElnaLexerToken; + lhs_node: ^ElnaTreeExpression + rhs_node: ^ElnaTreeExpression + result: ^ElnaTreeBinaryExpression + token: ^ElnaLexerToken begin lhs_node := elna_parser_unary_expression(cursor); rhs_node := nil; @@ -2765,13 +2764,13 @@ begin result := lhs_node end; return result -end; +end proc elna_tac_add_pointer(parser_node: ^ElnaTreeExpression, lhs: ^ElnaTacOperand, - rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction; + rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction var - instruction: ^ElnaTacInstruction; - pointer_type: ^ElnaTypePointer; + instruction: ^ElnaTacInstruction + pointer_type: ^ElnaTypePointer begin pointer_type := parser_node^.type_decoration; instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr); @@ -2783,14 +2782,14 @@ begin elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length); return instruction -end; +end proc elna_tac_subtract_create(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, lhs: ^ElnaTacOperand, - rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) var - instruction: ^ElnaTacInstruction; - lhs_is_pointer: Word; - rhs_is_not_pointer: Word; + instruction: ^ElnaTacInstruction + lhs_is_pointer: Word + rhs_is_not_pointer: Word begin lhs_is_pointer := parser_node^.lhs^.type_decoration^.kind = ElnaTypeKind.pointer; rhs_is_not_pointer := parser_node^.rhs^.type_decoration^.kind <> ElnaTypeKind.pointer; @@ -2806,14 +2805,14 @@ begin else elna_tac_binary_create(instructions, ElnaTacOperator.subtract, lhs, rhs, symbol_table, operand) end -end; +end proc elna_tac_binary_create(instructions: ^ElnaList, operator: ElnaTacOperator, lhs: ^ElnaTacOperand, - rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) var - instruction: ^ElnaTacInstruction; - lhs_symbol: ^ElnaSymbolTemporaryInfo; - variable_type: ^ElnaType; + instruction: ^ElnaTacInstruction + lhs_symbol: ^ElnaSymbolTemporaryInfo + variable_type: ^ElnaType begin if lhs^.kind = ElnaTacKind.variable then lhs_symbol := elna_symbol_table_lookup(symbol_table, lhs^.value, lhs^.length); @@ -2828,14 +2827,14 @@ begin 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); elna_list_append(instructions, instruction) -end; +end proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) var - instruction: ^ElnaTacInstruction; - lhs: ElnaTacOperand; - rhs: ElnaTacOperand; + instruction: ^ElnaTacInstruction + lhs: ElnaTacOperand + rhs: ElnaTacOperand begin if parser_node^.kind <> ElnaTreeKind.binary_expression then elna_tac_unary_expression(instructions, parser_node, symbol_table, operand) @@ -2881,14 +2880,14 @@ begin elna_tac_binary_create(instructions, ElnaTacOperator.not_equal, @lhs, @rhs, symbol_table, operand) end end -end; +end -proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: ^ElnaTreeExpression) -> ^ElnaTreeCall; +proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: ^ElnaTreeExpression) -> ^ElnaTreeCall var - result: ^ElnaTreeCall; - argument_number: Word; - argument_entry: ^ElnaTreeExpressionList; - token: ^ElnaLexerToken; + result: ^ElnaTreeCall + argument_number: Word + argument_entry: ^ElnaTreeExpressionList + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeCall)); result^.kind := ElnaTreeKind.call; @@ -2929,15 +2928,15 @@ begin result^.count := argument_number - 1; return result -end; +end proc elna_tac_call(instructions: ^ElnaList, parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, - operand: ^ElnaTacOperand); + operand: ^ElnaTacOperand) var - parsed_expression: ^ElnaTreeVariableExpression; - arguments_operand: ^ElnaTacOperand; - call_instruction: ^ElnaTacInstruction; - argument_entry: ^ElnaTreeExpressionList; + parsed_expression: ^ElnaTreeVariableExpression + arguments_operand: ^ElnaTacOperand + call_instruction: ^ElnaTacInstruction + argument_entry: ^ElnaTreeExpressionList begin parsed_expression := parsed_call^.callee; arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand)); @@ -2960,12 +2959,12 @@ begin goto elna_tac_call_loop end; elna_list_append(instructions, call_instruction) -end; +end -proc elna_parser_goto_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeGotoStatement; +proc elna_parser_goto_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeGotoStatement var - result: ^ElnaTreeGotoStatement; - token: ^ElnaLexerToken; + result: ^ElnaTreeGotoStatement + token: ^ElnaLexerToken begin elna_lexer_read(cursor); token := elna_lexer_read(cursor); @@ -2977,13 +2976,13 @@ begin result^.length := token^.length; return result -end; +end -proc elna_tac_goto_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeGotoStatement); +proc elna_tac_goto_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeGotoStatement) var - label_length: Word; - label_with_dot: ^Char; - instruction: ^ElnaTacInstruction; + label_length: Word + label_with_dot: ^Char + instruction: ^ElnaTacInstruction begin label_length := parser_node^.length + 1; label_with_dot := malloc(label_length); @@ -2994,12 +2993,12 @@ begin instruction := elna_tac_instruction_create(ElnaTacOperator.jump); elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.label, label_with_dot, label_length); elna_list_append(instructions, instruction) -end; +end -proc elna_parser_label_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeLabelDeclaration; +proc elna_parser_label_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeLabelDeclaration var - result: ^ElnaTreeLabelDeclaration; - token: ^ElnaLexerToken; + result: ^ElnaTreeLabelDeclaration + token: ^ElnaLexerToken begin elna_lexer_read(cursor); token := elna_lexer_read(cursor); @@ -3012,24 +3011,24 @@ begin result^.length := token^.length; return result -end; +end -proc elna_tac_label_declaration(instructions: ^ElnaList, parser_node: ^ElnaTreeLabelDeclaration); +proc elna_tac_label_declaration(instructions: ^ElnaList, parser_node: ^ElnaTreeLabelDeclaration) begin elna_tac_label(instructions, parser_node^.label, parser_node^.length) -end; +end -proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand: ^ElnaTacOperand); +proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand: ^ElnaTacOperand) var - enumeration_type: ^ElnaTypeEnumeration; - members: Word; - members_length: Word; - token_type: Word; - symbol_info: ^ElnaSymbolTypeInfo; - member_name: Word; - member_length: Word; - counter: Word; - enumeration_type_name: ^ElnaTreeVariableExpression; + enumeration_type: ^ElnaTypeEnumeration + members: Word + members_length: Word + token_type: Word + symbol_info: ^ElnaSymbolTypeInfo + member_name: Word + member_length: Word + counter: Word + enumeration_type_name: ^ElnaTreeVariableExpression begin enumeration_type_name := field_access_expression^.aggregate; symbol_info := elna_symbol_table_lookup(symbol_table_global, @@ -3057,13 +3056,13 @@ begin operand^.value := counter; operand^.length := 4 end -end; +end proc elna_parser_field_access_expression(cursor: ^ElnaLexerCursor, - aggregate: ^ElnaTreeExpression) -> ^ElnaTreeFieldAccessExpression; + aggregate: ^ElnaTreeExpression) -> ^ElnaTreeFieldAccessExpression var - result: ^ElnaTreeFieldAccessExpression; - token: ^ElnaLexerToken; + result: ^ElnaTreeFieldAccessExpression + token: ^ElnaLexerToken begin (* Skip dot. Read the enumeration value. *) elna_lexer_read(cursor); @@ -3078,12 +3077,12 @@ begin result^.length := token^.length; return result -end; +end proc elna_parser_array_access_expression(cursor: ^ElnaLexerCursor, - array: ^ElnaTreeExpression) -> ^ElnaTreeArrayAccessExpression; + array: ^ElnaTreeExpression) -> ^ElnaTreeArrayAccessExpression var - result: ^ElnaTreeArrayAccessExpression; + result: ^ElnaTreeArrayAccessExpression begin elna_lexer_read(cursor); @@ -3097,19 +3096,19 @@ begin elna_lexer_read(cursor); return result -end; +end proc elna_tac_dereference_expression(instructions: ^ElnaList, dereference_expression: ^ElnaTreeDereferenceExpression, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) var - load_instruction: ^ElnaTacInstruction; - operand_result: ElnaTacOperandResult; - intermediate: ElnaTacOperand; + load_instruction: ^ElnaTacInstruction + operand_result: ElnaTacOperandResult + intermediate: ElnaTacOperand begin elna_tac_designator(instructions, dereference_expression^.pointer, symbol_table, @operand_result, operand); if operand_result.kind = ElnaTacOperandType.dereferenced_pointer then - memcpy(@intermediate, operand, #size(ElnaTacOperand)); + intermediate := operand^; elna_tac_make_variable(operand, symbol_table, word_type); load_instruction := elna_tac_instruction_create(ElnaTacOperator.load); @@ -3117,7 +3116,7 @@ begin elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, load_instruction) elsif operand_result.kind = ElnaTacOperandType.sub_object then - memcpy(@intermediate, operand, #size(ElnaTacOperand)); + intermediate := operand^; elna_tac_make_variable(operand, symbol_table, word_type); load_instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset); @@ -3126,13 +3125,13 @@ begin elna_tac_instruction_set_operand(load_instruction, 3, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, load_instruction) end -end; +end proc elna_tac_designator(instructions: ^ElnaList, parser_node: ^ElnaTreeExpression, symbol_table: ElnaSymbolTable, - operand_result: ^ElnaTacOperandResult, operand: ^ElnaTacOperand); + operand_result: ^ElnaTacOperandResult, operand: ^ElnaTacOperand) var - field_access_expression: ^ElnaTreeFieldAccessExpression; - designator_base: ^ElnaTreeExpression; + field_access_expression: ^ElnaTreeFieldAccessExpression + designator_base: ^ElnaTreeExpression begin operand_result^.kind := ElnaTacOperandType.plain_object; operand_result^.offset := 0; @@ -3158,19 +3157,19 @@ begin else elna_tac_simple_expression(instructions, parser_node, symbol_table, operand) end -end; +end proc elna_tac_field_access_expression(instructions: ^ElnaList, field_access_expression: ^ElnaTreeFieldAccessExpression, - symbol_table: ^ElnaSymbolTable, operand_result: ^ElnaTacOperandResult, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand_result: ^ElnaTacOperandResult, operand: ^ElnaTacOperand) var - field_type: ^ElnaType; - instruction: ^ElnaTacInstruction; - designator_base: ^ElnaTreeExpression; - aggregate_type: ^ElnaTypeRecord; - field_count: Word; - current_field: ^ElnaTypeField; - field_offset: Word; - base: ElnaTacOperand; + field_type: ^ElnaType + instruction: ^ElnaTacInstruction + designator_base: ^ElnaTreeExpression + aggregate_type: ^ElnaTypeRecord + field_count: Word + current_field: ^ElnaTypeField + field_offset: Word + base: ElnaTacOperand begin designator_base := field_access_expression^.aggregate; aggregate_type := designator_base^.type_decoration; @@ -3200,25 +3199,26 @@ begin elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) elsif operand_result^.kind = ElnaTacOperandType.sub_object then - memcpy(operand, @base, #size(ElnaTacOperand)); + operand^ := base; operand_result^.offset := operand_result^.offset + field_offset else (* ElnaTacOperandType.plain_object *) - memcpy(operand, @base, #size(ElnaTacOperand)); + operand^ := base; + operand_result^.kind := ElnaTacOperandType.sub_object; operand_result^.offset := field_offset end -end; +end proc elna_tac_array_access_expression(instructions: ^ElnaList, array_access_expression: ^ElnaTreeArrayAccessExpression, - symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); + symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) var - instruction: ^ElnaTacInstruction; - operand_result: ElnaTacOperandResult; - inter_operand: ElnaTacOperand; - index_operand: ElnaTacOperand; - aggregate_type: ^ElnaTypeArray; - designator_base: ^ElnaTreeExpression; - element_type: ^ElnaType; + instruction: ^ElnaTacInstruction + operand_result: ElnaTacOperandResult + inter_operand: ElnaTacOperand + index_operand: ElnaTacOperand + aggregate_type: ^ElnaTypeArray + designator_base: ^ElnaTreeExpression + element_type: ^ElnaType begin designator_base := array_access_expression^.array; aggregate_type := designator_base^.type_decoration; @@ -3244,11 +3244,11 @@ begin elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, element_type^.size, 4); elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) -end; +end -proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: ^ElnaTreeNode) -> ^ElnaTreeAssignStatement; +proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: ^ElnaTreeNode) -> ^ElnaTreeAssignStatement var - result: ^ElnaTreeAssignStatement; + result: ^ElnaTreeAssignStatement begin result := malloc(#size(ElnaTreeAssignStatement)); @@ -3261,15 +3261,15 @@ begin result^.assignment := elna_parser_binary_expression(cursor); return result -end; +end -proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable) var - operand_result: ElnaTacOperandResult; - instruction: ^ElnaTacInstruction; - assignment_operand: ElnaTacOperand; - assignee: ElnaTacOperand; - symbol_info: ^ElnaSymbolInfo; + operand_result: ElnaTacOperandResult + instruction: ^ElnaTacInstruction + assignment_operand: ElnaTacOperand + assignee: ElnaTacOperand + symbol_info: ^ElnaSymbolInfo begin elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @operand_result, @assignee); @@ -3294,13 +3294,13 @@ begin elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length) end; elna_list_append(instructions, instruction) -end; +end -proc elna_parser_return_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeReturnStatement; +proc elna_parser_return_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeReturnStatement var - returned: ^ElnaTreeExpression; - label_length: Word; - result: ^ElnaTreeReturnStatement; + returned: ^ElnaTreeExpression + label_length: Word + result: ^ElnaTreeReturnStatement begin (* Skip "return" keyword and whitespace after it. *) elna_lexer_read(cursor); @@ -3313,19 +3313,19 @@ begin result^.returned := returned; return result -end; +end -proc elna_tac_return_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_return_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable) var - instruction: ^ElnaTacInstruction; - operand: ElnaTacOperand; + instruction: ^ElnaTacInstruction + operand: ElnaTacOperand begin elna_tac_binary_expression(instructions, parser_node^.returned, symbol_table, @operand); instruction := elna_tac_instruction_create(ElnaTacOperator._return); elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length); elna_list_append(instructions, instruction) -end; +end (** * Writes a label, .Ln, where n is a unique number. @@ -3333,9 +3333,9 @@ end; * Parameters: * counter - Label counter. *) -proc _write_label(counter: Word, length: Word); +proc _write_label(counter: Word, length: Word) var - first_byte: Word; + first_byte: Word begin if length = 0 then printf(".L%i\0", counter) @@ -3343,11 +3343,11 @@ begin printf(".%.*s\0", length, counter); end; fflush(nil) -end; +end -proc elna_parser_conditional_statements(cursor: ^ElnaLexerCursor) -> ^ElnaTreeConditionalStatements; +proc elna_parser_conditional_statements(cursor: ^ElnaLexerCursor) -> ^ElnaTreeConditionalStatements var - result: ^ElnaTreeConditionalStatements; + result: ^ElnaTreeConditionalStatements begin result := malloc(#size(ElnaTreeConditionalStatements)); @@ -3362,14 +3362,14 @@ begin result^.next := nil; return result -end; +end proc elna_tac_conditional_statements(instructions: ^ElnaList, parser_node: ^ElnaTreeConditionalStatements, - after_end_label: Word, symbol_table: ^ElnaSymbolTable); + after_end_label: Word, symbol_table: ^ElnaSymbolTable) var - condition_label: Word; - instruction: ^ElnaTacInstruction; - operand: ElnaTacOperand; + condition_label: Word + instruction: ^ElnaTacInstruction + operand: ElnaTacOperand begin (* Compile condition. *) elna_tac_binary_expression(instructions, parser_node^.condition, symbol_table, @operand); @@ -3390,14 +3390,14 @@ begin elna_list_append(instructions, instruction); elna_tac_label(instructions, condition_label, 0) -end; +end -proc elna_parser_if_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeIfStatement; +proc elna_parser_if_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeIfStatement var - result: ^ElnaTreeIfStatement; - previous_conditional: ^ElnaTreeConditionalStatements; - next_conditional: ^ElnaTreeConditionalStatements; - token: ^ElnaLexerToken; + result: ^ElnaTreeIfStatement + previous_conditional: ^ElnaTreeConditionalStatements + next_conditional: ^ElnaTreeConditionalStatements + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeIfStatement)); @@ -3425,13 +3425,13 @@ begin elna_lexer_read(cursor); return result -end; +end -proc elna_parser_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement; +proc elna_parser_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement var - result: ^ElnaTreeStatement; - designator: ^ElnaTreeNode; - token: ^ElnaLexerToken; + result: ^ElnaTreeStatement + designator: ^ElnaTreeNode + token: ^ElnaLexerToken begin result := nil; token := elna_lexer_peek(cursor); @@ -3454,14 +3454,14 @@ begin end end; return result -end; +end -proc elna_parser_statements(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement; +proc elna_parser_statements(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement var - previous_statement: ^ElnaTreeStatement; - next_statement: ^ElnaTreeStatement; - first_statement: ^ElnaTreeStatement; - token: ^ElnaLexerToken; + previous_statement: ^ElnaTreeStatement + next_statement: ^ElnaTreeStatement + first_statement: ^ElnaTreeStatement + token: ^ElnaLexerToken begin elna_lexer_skip_empty_lines(cursor); @@ -3489,9 +3489,9 @@ begin elna_lexer_skip_empty_lines(cursor); return first_statement -end; +end -proc elna_tac_statements(instructions: ^ElnaList, current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_statements(instructions: ^ElnaList, current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable) begin .elna_tac_statements_loop; if current_statement <> nil then @@ -3500,13 +3500,13 @@ begin goto elna_tac_statements_loop end -end; +end -proc elna_tac_if_statement(instructions: ElnaList, parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_if_statement(instructions: ElnaList, parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable) var - current_node: ^ElnaTreeConditionalStatements; - after_end_label: Word; - condition_label: Word; + current_node: ^ElnaTreeConditionalStatements + after_end_label: Word + condition_label: Word begin after_end_label := label_counter; label_counter := label_counter + 1; @@ -3527,11 +3527,11 @@ begin elna_tac_statements(instructions, parser_node^._else, symbol_table) end; elna_tac_label(instructions, after_end_label, 0) -end; +end -proc elna_tac_statement(instructions: ElnaList, parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable); +proc elna_tac_statement(instructions: ElnaList, parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) var - operand: ElnaTacOperand; + operand: ElnaTacOperand begin if parser_node^.kind = ElnaTreeKind.goto_statement then elna_tac_goto_statement(instructions, parser_node) @@ -3546,7 +3546,7 @@ begin elsif parser_node^.kind = ElnaTreeKind.assign_statement then elna_tac_assign_statement(instructions, parser_node, symbol_table) end -end; +end (** * Writes a regster name to the standard output. @@ -3555,18 +3555,18 @@ end; * register_character - Register character. * register_number - Register number. *) -proc _write_register(register_character: Word, register_number: Word); +proc _write_register(register_character: Word, register_number: Word) begin _write_c(register_character); _write_c(register_number + '0') -end; +end -proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeRecordTypeExpression; +proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeRecordTypeExpression var - entry: ^ElnaTreeField; - result: ^ElnaTreeRecordTypeExpression; - previous_entry: ^ElnaTreeField; - token: ^ElnaLexerToken; + entry: ^ElnaTreeField + result: ^ElnaTreeRecordTypeExpression + previous_entry: ^ElnaTreeField + token: ^ElnaLexerToken begin elna_lexer_read(cursor); result := malloc(#size(ElnaTreeRecordTypeExpression)); @@ -3608,14 +3608,14 @@ begin result^.kind := ElnaTreeKind.record_type_expression; return result -end; +end -proc elna_parser_enumeration_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeEnumerationTypeExpression; +proc elna_parser_enumeration_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeEnumerationTypeExpression var - result: ^ElnaTreeEnumerationTypeExpression; - entry: ^ElnaTreeEnumeration; - previous_entry: ^ElnaTreeEnumeration; - token: ^ElnaLexerToken; + result: ^ElnaTreeEnumerationTypeExpression + entry: ^ElnaTreeEnumeration + previous_entry: ^ElnaTreeEnumeration + token: ^ElnaLexerToken begin elna_lexer_read(cursor); @@ -3646,7 +3646,7 @@ begin goto elna_parser_enumeration_type_expression_loop end; return result -end; +end (** * Reads and creates enumeration type representation. @@ -3660,13 +3660,13 @@ end; * * Returns enumeration type description. *) -proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression) -> ^ElnaTypeEnumeration; +proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression) -> ^ElnaTypeEnumeration var - result: ^ElnaTypeEnumeration; - memory_start: Word; - member_count: Word; - member_array_start: Word; - member_array_current: Word; + result: ^ElnaTypeEnumeration + memory_start: Word + member_count: Word + member_array_start: Word + member_array_current: Word begin result := malloc(#size(ElnaTypeEnumeration)); @@ -3700,11 +3700,11 @@ begin result^.length := member_count; return result -end; +end -proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression) -> ^ElnaTypePointer; +proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression) -> ^ElnaTypePointer var - result: ^ElnaTypePointer; + result: ^ElnaTypePointer begin result := malloc(#size(ElnaTypePointer)); @@ -3714,13 +3714,13 @@ begin result^.base := elna_name_type_expression(parser_node^.base); return result -end; +end -proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression) -> ^ElnaTypeArray; +proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression) -> ^ElnaTypeArray var - base: ^ElnaType; - result: ^ElnaTypeArray; - length: ^ElnaTreeIntegerLiteral; + base: ^ElnaType + result: ^ElnaTypeArray + length: ^ElnaTreeIntegerLiteral begin result := malloc(#size(ElnaTypeArray)); base := elna_name_type_expression(parser_node^.base); @@ -3734,15 +3734,15 @@ begin result^.length := length^.value; return result -end; +end -proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression) -> ^ElnaTypeRecord; +proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression) -> ^ElnaTypeRecord var - result: ^ElnaTypeRecord; - tree_field: ^ElnaTreeField; - member_array_start: ^ElnaTypeField; - member_array_current: ^ElnaTypeField; - field_type: ^ElnaType; + result: ^ElnaTypeRecord + tree_field: ^ElnaTreeField + member_array_start: ^ElnaTypeField + member_array_current: ^ElnaTypeField + field_type: ^ElnaType begin result := malloc(#size(ElnaTypeRecord)); result^.kind := ElnaTypeKind._record; @@ -3774,12 +3774,12 @@ begin end; return result -end; +end -proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNamedTypeExpression; +proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNamedTypeExpression var - result: ^ElnaTreeNamedTypeExpression; - token: ^ElnaLexerToken; + result: ^ElnaTreeNamedTypeExpression + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeNamedTypeExpression)); token := elna_lexer_read(cursor); @@ -3789,11 +3789,11 @@ begin result^.length := token^.length; return result -end; +end -proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreePointerTypeExpression; +proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreePointerTypeExpression var - result: ^ElnaTreePointerTypeExpression; + result: ^ElnaTreePointerTypeExpression begin elna_lexer_read(cursor); @@ -3802,11 +3802,11 @@ begin result^.base := elna_parser_type_expression(cursor); return result -end; +end -proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeArrayTypeExpression; +proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeArrayTypeExpression var - result: ^ElnaTreeArrayTypeExpression; + result: ^ElnaTreeArrayTypeExpression begin elna_lexer_read(cursor); @@ -3820,12 +3820,12 @@ begin result^.base := elna_parser_type_expression(cursor); return result -end; +end -proc elna_parser_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNode; +proc elna_parser_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNode var - result: ^ElnaTreeNode; - token: ^ElnaLexerToken; + result: ^ElnaTreeNode + token: ^ElnaLexerToken begin result := nil; token := elna_lexer_peek(cursor); @@ -3842,13 +3842,13 @@ begin result := elna_parser_array_type_expression(cursor) end; return result -end; +end -proc elna_name_type_expression(parser_node: ^ElnaTreeNode) -> ^ElnaType; +proc elna_name_type_expression(parser_node: ^ElnaTreeNode) -> ^ElnaType var - named_type_expression: ^ElnaTreeNamedTypeExpression; - type_symbol: ^ElnaSymbolTypeInfo; - result: ^ElnaType; + named_type_expression: ^ElnaTreeNamedTypeExpression + type_symbol: ^ElnaSymbolTypeInfo + result: ^ElnaType begin if parser_node^.kind = ElnaTreeKind.named_type_expression then named_type_expression := parser_node; @@ -3867,27 +3867,27 @@ begin end; return result -end; +end -proc type_info_create(type_representation: ^ElnaType) -> ^ElnaSymbolTypeInfo; +proc type_info_create(type_representation: ^ElnaType) -> ^ElnaSymbolTypeInfo var - result: ^ElnaSymbolTypeInfo; + result: ^ElnaSymbolTypeInfo begin result := malloc(#size(ElnaSymbolTypeInfo)); result^.kind := ElnaSymbolInfoKind.type_info; result^._type := type_representation; return result -end; +end (** * Parameters: * attr - Local variable attributes. * temporary_type - Local variable type. *) -proc temporary_info_create(attr: Word, temporary_type: ^ElnaType) -> ^ElnaSymbolTemporaryInfo; +proc temporary_info_create(attr: Word, temporary_type: ^ElnaType) -> ^ElnaSymbolTemporaryInfo var - result: ^ElnaSymbolTemporaryInfo; + result: ^ElnaSymbolTemporaryInfo begin result := malloc(#size(ElnaSymbolTemporaryInfo)); result^.kind := ElnaSymbolInfoKind.temporary_info; @@ -3897,39 +3897,39 @@ begin result^.attr := attr; return result -end; +end (** * Parameters: * symbol_table - Local symbol table. *) -proc procedure_info_create(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolProcedureInfo; +proc procedure_info_create(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolProcedureInfo var - result: ^ElnaSymbolProcedureInfo; + result: ^ElnaSymbolProcedureInfo begin result := malloc(#size(ElnaSymbolProcedureInfo)); result^.kind := ElnaSymbolInfoKind.procedure_info; result^.symbol_table := symbol_table; return result -end; +end (** * Parameters: * variable_index - Variable index. *) -proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable); +proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable) var - info: Word; - variable_type: Word; + info: Word + variable_type: Word begin variable_type := elna_name_type_expression(parser_node^.type_expression); info := temporary_info_create(0, variable_type); elna_symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info) -end; +end -proc elna_name_procedure_temporaries(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable); +proc elna_name_procedure_temporaries(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable) begin .elna_name_procedure_temporaries_loop; if parser_node <> nil then @@ -3938,15 +3938,15 @@ begin parser_node := parser_node^.next; goto elna_name_procedure_temporaries_loop end -end; +end -proc elna_parser_procedure_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeProcedureDeclaration; +proc elna_parser_procedure_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeProcedureDeclaration var - next_declaration: ^ElnaTreeDeclaration; - current_declaration: ^ElnaTreeDeclaration; - result: ^ElnaTreeProcedureDeclaration; - parameter_head: ^ElnaTreeDeclaration; - token: ^ElnaLexerToken; + next_declaration: ^ElnaTreeDeclaration + current_declaration: ^ElnaTreeDeclaration + result: ^ElnaTreeProcedureDeclaration + parameter_head: ^ElnaTreeDeclaration + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeProcedureDeclaration)); @@ -3989,11 +3989,11 @@ begin result^.parameters := parameter_head; (* Skip semicolon or arrow. *) - token := elna_lexer_read(cursor); + token := elna_lexer_peek(cursor); if token^.kind = ElnaLexerKind.arrow then - result^.return_type := elna_parser_type_expression(cursor); - elna_lexer_read(cursor) + elna_lexer_read(cursor); + result^.return_type := elna_parser_type_expression(cursor) else result^.return_type := nil end; @@ -4015,14 +4015,14 @@ begin elna_lexer_read(cursor); return result -end; +end -proc elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word) -> ^Word; +proc elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word) -> ^Word var - ast_parameter: ^ElnaTreeDeclaration; - parameter_index: Word; - current_parameter: Word; - parameter_list: Word; + ast_parameter: ^ElnaTreeDeclaration + parameter_index: Word + current_parameter: Word + parameter_list: Word begin ast_parameter := ast_list; parameter_count^ := 0; @@ -4054,11 +4054,11 @@ begin end; return parameter_list -end; +end -proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable; +proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable var - result: ^ElnaRtlStaticVariable; + result: ^ElnaRtlStaticVariable begin result := malloc(#size(ElnaRtlStaticVariable)); @@ -4068,15 +4068,15 @@ begin result^.body := tac_declaration^.body; return result -end; +end -proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word) -> ^ElnaRtlInstruction; +proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word) -> ^ElnaRtlInstruction var - result: ^ElnaRtlInstruction; - instruction: ^ElnaRtlInstruction; - parameter_index: Word; - parameter_name: Word; - name_length: Word; + result: ^ElnaRtlInstruction + instruction: ^ElnaRtlInstruction + parameter_index: Word + parameter_name: Word + name_length: Word begin result := nil; parameter_index := 0; @@ -4098,26 +4098,26 @@ begin end; return result -end; +end (* Returns whether the provided type is array or record. *) -proc elna_type_is_aggregate(_type: ^ElnaType); +proc elna_type_is_aggregate(_type: ^ElnaType) var - lhs: Word; - rhs: Word; + lhs: Word + rhs: Word begin lhs := _type^.kind = ElnaTypeKind._record; rhs := _type^.kind = ElnaTypeKind.array; return lhs or rhs -end; +end proc elna_rtl_generate_pseudo(operand: ^ElnaRtlOperand, variable_map: ^ElnaSymbolTable, - rtl_type: ^ElnaRtlType) -> ^ElnaRtlObjectInfo; + rtl_type: ^ElnaRtlType) -> ^ElnaRtlObjectInfo var - pseudo_symbol: ^ElnaRtlObjectInfo; - pseudo_type: ^ElnaRtlTypeWord; - buffer: Word; + pseudo_symbol: ^ElnaRtlObjectInfo + pseudo_type: ^ElnaRtlTypeWord + buffer: Word begin operand^.kind := ElnaRtlKind.pseudo; pseudo_counter := pseudo_counter + 1; @@ -4135,11 +4135,11 @@ begin elna_symbol_table_enter(variable_map, buffer, operand^.length, pseudo_symbol); return pseudo_symbol -end; +end -proc elna_rtl_constant_type(size: Word) -> ^ElnaRtlType; +proc elna_rtl_constant_type(size: Word) -> ^ElnaRtlType var - rtl_type: ^ElnaRtlType; + rtl_type: ^ElnaRtlType begin rtl_type := malloc(#size(ElnaRtlTypeWord)); if size = 1 then @@ -4148,12 +4148,12 @@ begin rtl_type^.kind := ElnaRtlTypeKind.long_word end; return rtl_type -end; +end -proc elna_rtl_symbol_type(variable_type: ^ElnaType) -> ^ElnaRtlType; +proc elna_rtl_symbol_type(variable_type: ^ElnaType) -> ^ElnaRtlType var - byte_array: ^ElnaRtlTypeByteArray; - rtl_type: ^ElnaRtlType; + byte_array: ^ElnaRtlTypeByteArray + rtl_type: ^ElnaRtlType begin if elna_type_is_aggregate(variable_type) then byte_array := malloc(#size(ElnaRtlTypeByteArray)); @@ -4166,16 +4166,16 @@ begin rtl_type := elna_rtl_constant_type(variable_type^.size) end; return rtl_type -end; +end -proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure) -> ^ElnaRtlProcedure; +proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure) -> ^ElnaRtlProcedure var - count: Word; - current_entry: ^ElnaSymbolEntry; - pseudo_symbol: ^ElnaRtlObjectInfo; - variable_info: ^ElnaSymbolTemporaryInfo; - info: ^ElnaSymbolInfo; - result: ^ElnaRtlProcedure; + count: Word + current_entry: ^ElnaSymbolEntry + pseudo_symbol: ^ElnaRtlObjectInfo + variable_info: ^ElnaSymbolTemporaryInfo + info: ^ElnaSymbolInfo + result: ^ElnaRtlProcedure begin result := malloc(#size(ElnaRtlProcedure)); elna_list_initialize(@result^.body); @@ -4216,14 +4216,14 @@ begin elna_rtl_instructions(@result^.body, tac_declaration^.body.first, result^.variable_map); return result -end; +end -proc elna_tac_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) -> ^ElnaTacProcedure; +proc elna_tac_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) -> ^ElnaTacProcedure var - symbol_info: ^ElnaSymbolProcedureInfo; - result: ^ElnaTacProcedure; - parameter_count: Word; - body: ElnaList; + symbol_info: ^ElnaSymbolProcedureInfo + result: ^ElnaTacProcedure + parameter_count: Word + body: ElnaList begin result := malloc(#size(ElnaTacProcedure)); result^.next := nil; @@ -4243,14 +4243,14 @@ begin elna_tac_statements(@result^.body, parser_node^.body, symbol_info^.symbol_table); return result -end; +end -proc elna_parser_procedures(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration; +proc elna_parser_procedures(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration var - parser_node: ^ElnaTreeDeclaration; - result: ^ElnaTreeDeclaration; - current_declaration: ^ElnaTreeDeclaration; - token: ^ElnaLexerToken; + parser_node: ^ElnaTreeDeclaration + result: ^ElnaTreeDeclaration + current_declaration: ^ElnaTreeDeclaration + token: ^ElnaLexerToken begin result := nil; @@ -4267,19 +4267,16 @@ begin end; current_declaration := parser_node; - (* Skip semicolon. *) - elna_lexer_read(cursor); - goto elna_parser_procedures_loop end; return result -end; +end -proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable; +proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable var - current_copy: ^ElnaRtlStaticVariable; - next_copy: ^ElnaRtlStaticVariable; - first_copy: ^ElnaRtlStaticVariable; + current_copy: ^ElnaRtlStaticVariable + next_copy: ^ElnaRtlStaticVariable + first_copy: ^ElnaRtlStaticVariable begin if tac_procedure <> nil then first_copy := elna_rtl_global_declaration(tac_procedure); @@ -4301,13 +4298,13 @@ begin end; return first_copy -end; +end -proc elna_rtl_procedures(tac_procedure: ^ElnaTacProcedure) -> ^ElnaRtlProcedure; +proc elna_rtl_procedures(tac_procedure: ^ElnaTacProcedure) -> ^ElnaRtlProcedure var - current_copy: ^ElnaRtlProcedure; - next_copy: ^ElnaRtlProcedure; - first_copy: ^ElnaRtlProcedure; + current_copy: ^ElnaRtlProcedure + next_copy: ^ElnaRtlProcedure + first_copy: ^ElnaRtlProcedure begin if tac_procedure <> nil then first_copy := elna_rtl_procedure_declaration(tac_procedure); @@ -4329,13 +4326,13 @@ begin end; return first_copy -end; +end -proc elna_tac_procedures(parser_node: ^ElnaTreeDeclaration) -> ^ElnaTacProcedure; +proc elna_tac_procedures(parser_node: ^ElnaTreeDeclaration) -> ^ElnaTacProcedure var - result: ^ElnaTacProcedure; - current_procedure: ^ElnaTacProcedure; - first_procedure: ^ElnaTacProcedure; + result: ^ElnaTacProcedure + current_procedure: ^ElnaTacProcedure + first_procedure: ^ElnaTacProcedure begin first_procedure := nil; @@ -4356,14 +4353,14 @@ begin .elna_tac_procedures_end; return first_procedure -end; +end (** * Skips comments. *) -proc elna_lexer_skip_empty_lines(cursor: ^ElnaLexerCursor); +proc elna_lexer_skip_empty_lines(cursor: ^ElnaLexerCursor) var - token: ^ElnaLexerToken; + token: ^ElnaLexerToken begin .skip_empty_lines_rerun; @@ -4373,12 +4370,12 @@ begin elna_lexer_read(cursor); goto skip_empty_lines_rerun end -end; +end -proc elna_parser_type_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeTypeDeclaration; +proc elna_parser_type_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeTypeDeclaration var - result: ^ElnaTreeTypeDeclaration; - token: ^ElnaLexerToken; + result: ^ElnaTreeTypeDeclaration + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeTypeDeclaration)); token := elna_lexer_read(cursor); @@ -4391,32 +4388,30 @@ begin elna_lexer_read(cursor); result^.type_expression := elna_parser_type_expression(cursor); - elna_lexer_read(cursor); - return result -end; +end -proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration); +proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration) var - symbol_type: ^ElnaType; - type_info: ^ElnaSymbolTypeInfo; + symbol_type: ^ElnaType + type_info: ^ElnaSymbolTypeInfo begin symbol_type := elna_name_type_expression(parser_node^.type_expression); type_info := type_info_create(symbol_type); elna_symbol_table_enter(symbol_table_global, parser_node^.name, parser_node^.length, type_info) -end; +end -proc elna_type_type_declaration(parser_node: Word); +proc elna_type_type_declaration(parser_node: Word) begin -end; +end -proc elna_parser_type_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration; +proc elna_parser_type_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration var - parser_node: ^ElnaTreeDeclaration; - result: ^ElnaTreeDeclaration; - current_declaration: ^ElnaTreeDeclaration; - token: ^ElnaLexerToken; + parser_node: ^ElnaTreeDeclaration + result: ^ElnaTreeDeclaration + current_declaration: ^ElnaTreeDeclaration + token: ^ElnaLexerToken begin result := nil; elna_lexer_skip_empty_lines(cursor); @@ -4445,13 +4440,13 @@ begin .elna_parser_type_part_end; return result -end; +end -proc elna_parser_variable_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableDeclaration; +proc elna_parser_variable_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableDeclaration var - variable_type: Word; - result: ^ElnaTreeVariableDeclaration; - token: ^ElnaLexerToken; + variable_type: Word + result: ^ElnaTreeVariableDeclaration + token: ^ElnaLexerToken begin token := elna_lexer_read(cursor); @@ -4468,12 +4463,12 @@ begin result^.type_expression := variable_type; return result -end; +end -proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration) -> ^ElnaTacStaticVariable; +proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration) -> ^ElnaTacStaticVariable var - result: ^ElnaTacStaticVariable; - variable_info: ^ElnaSymbolTemporaryInfo; + 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); @@ -4484,14 +4479,14 @@ begin result^.body := variable_info^.variable_type^.size; return result -end; +end -proc elna_parser_var_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration; +proc elna_parser_var_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration var - result: ^ElnaTreeDeclaration; - variable_node: ^ElnaTreeDeclaration; - current_declaration: ^ElnaTreeDeclaration; - token: ^ElnaLexerToken; + result: ^ElnaTreeDeclaration + variable_node: ^ElnaTreeDeclaration + current_declaration: ^ElnaTreeDeclaration + token: ^ElnaLexerToken begin result := nil; token := elna_lexer_peek(cursor); @@ -4509,9 +4504,6 @@ begin if token^.kind = ElnaLexerKind.identifier then variable_node := elna_parser_variable_declaration(cursor); - (* Skip semicolon. *) - elna_lexer_read(cursor); - if result = nil then result := variable_node else @@ -4523,13 +4515,13 @@ begin .elna_parser_var_part_end; return result -end; +end -proc elna_tac_var_part(parser_node: ^ElnaTreeDeclaration) -> ^ElnaTacStaticVariable; +proc elna_tac_var_part(parser_node: ^ElnaTreeDeclaration) -> ^ElnaTacStaticVariable var - node: ^ElnaTacStaticVariable; - current_variable: ^ElnaTacStaticVariable; - first_variable: ^ElnaTacStaticVariable; + node: ^ElnaTacStaticVariable + current_variable: ^ElnaTacStaticVariable + first_variable: ^ElnaTacStaticVariable begin first_variable := nil; if parser_node = nil then @@ -4552,12 +4544,12 @@ begin .elna_tac_var_part_end; return first_variable -end; +end -proc elna_parser_program_body(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement; +proc elna_parser_program_body(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement var - result: ^ElnaTreeStatement; - token: ^ElnaLexerToken; + result: ^ElnaTreeStatement + token: ^ElnaLexerToken begin result := nil; token := elna_lexer_peek(cursor); @@ -4567,14 +4559,14 @@ begin result := elna_parser_statements(cursor); end; return result -end; +end -proc elna_parser_module_declaration(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreeModuleDeclaration; +proc elna_parser_module_declaration(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreeModuleDeclaration var - parser_node: Word; - result: ^ElnaTreeModuleDeclaration; - parser_error: ^ElnaError; - token: ^ElnaLexerToken; + parser_node: Word + result: ^ElnaTreeModuleDeclaration + parser_error: ^ElnaError + token: ^ElnaLexerToken begin result := malloc(#size(ElnaTreeModuleDeclaration)); result^.kind := ElnaTreeKind.module_declaration; @@ -4598,12 +4590,12 @@ begin result^.body := elna_parser_program_body(cursor) end; return result -end; +end -proc elna_tac_program_body(parser_node: ^ElnaTreeStatement) -> ^ElnaTacProcedure; +proc elna_tac_program_body(parser_node: ^ElnaTreeStatement) -> ^ElnaTacProcedure var - result: ^ElnaTacProcedure; - symbol_info: ^ElnaSymbolProcedureInfo; + result: ^ElnaTacProcedure + symbol_info: ^ElnaSymbolProcedureInfo begin result := malloc(#size(ElnaTacProcedure)); result^.next := nil; @@ -4623,12 +4615,12 @@ begin elna_tac_statements(@result^.body, parser_node, result^.symbol_table); return result -end; +end -proc elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) -> ^ElnaInstructionModule; +proc elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) -> ^ElnaInstructionModule var - result: ^ElnaInstructionModule; - code: ^ElnaTacProcedure; + result: ^ElnaInstructionModule + code: ^ElnaTacProcedure begin result := malloc(#size(ElnaInstructionModule)); result^.data := elna_tac_var_part(parser_node^.globals); @@ -4652,41 +4644,41 @@ begin end; .elna_tac_module_declaration_end; return result -end; +end -proc elna_name_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression); +proc elna_name_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression) begin elna_name_designator(parser_node^.pointer) -end; +end -proc elna_name_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression); +proc elna_name_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression) begin elna_name_designator(parser_node^.aggregate) -end; +end -proc elna_name_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression); +proc elna_name_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression) begin elna_name_designator(parser_node^.array); elna_name_binary_expression(parser_node^.index) -end; +end -proc elna_name_cast_expression(parser_node: ^ElnaTreeCastExpression); +proc elna_name_cast_expression(parser_node: ^ElnaTreeCastExpression) begin elna_name_binary_expression(parser_node^.expression); parser_node^.type_decoration := elna_name_type_expression(parser_node^.type_expression) -end; +end -proc elna_name_simple_expression(parser_node: ^ElnaTreeNode); +proc elna_name_simple_expression(parser_node: ^ElnaTreeNode) begin (* Not interested in literals and variable expressions. *) if parser_node^.kind = ElnaTreeKind._cast then elna_name_cast_expression(parser_node) end -end; +end -proc elna_name_call(parser_node: ^ElnaTreeCall); +proc elna_name_call(parser_node: ^ElnaTreeCall) var - argument_tree: ^ElnaTreeExpressionList; + argument_tree: ^ElnaTreeExpressionList begin argument_tree := parser_node^.arguments; @@ -4697,9 +4689,9 @@ begin goto elna_name_call_argument end -end; +end -proc elna_name_designator(parser_node: ^ElnaTreeNode); +proc elna_name_designator(parser_node: ^ElnaTreeNode) begin if parser_node^.kind = ElnaTreeKind.dereference_expression then elna_name_dereference_expression(parser_node) @@ -4712,18 +4704,18 @@ begin else elna_name_simple_expression(parser_node) end -end; +end -proc elna_name_unary_expression(parser_node: ^ElnaTreeUnaryExpression); +proc elna_name_unary_expression(parser_node: ^ElnaTreeUnaryExpression) begin if parser_node^.kind = ElnaTreeKind.unary_expression then elna_name_designator(parser_node^.operand) else elna_name_designator(parser_node) end -end; +end -proc elna_name_binary_expression(parser_node: ^ElnaTreeBinaryExpression); +proc elna_name_binary_expression(parser_node: ^ElnaTreeBinaryExpression) begin if parser_node^.kind = ElnaTreeKind.binary_expression then elna_name_unary_expression(parser_node^.lhs); @@ -4731,9 +4723,9 @@ begin else elna_name_unary_expression(parser_node) end -end; +end -proc elna_name_conditional_statements(parser_node: ^ElnaTreeConditionalStatements); +proc elna_name_conditional_statements(parser_node: ^ElnaTreeConditionalStatements) begin .elna_name_conditional_statements_loop; elna_name_binary_expression(parser_node^.condition); @@ -4743,11 +4735,11 @@ begin if parser_node <> nil then goto elna_name_conditional_statements_loop end -end; +end -proc elna_name_if_statement(parser_node: ^ElnaTreeIfStatement); +proc elna_name_if_statement(parser_node: ^ElnaTreeIfStatement) var - block: ^ElnaTreeConditionalStatements; + block: ^ElnaTreeConditionalStatements begin block := parser_node^.conditionals; @@ -4762,20 +4754,20 @@ begin if block <> nil then elna_name_statements(block) end -end; +end -proc elna_name_return_statement(parser_node: ^ElnaTreeReturnStatement); +proc elna_name_return_statement(parser_node: ^ElnaTreeReturnStatement) begin elna_name_binary_expression(parser_node^.returned) -end; +end -proc elna_name_assign_statement(parser_node: ^ElnaTreeAssignStatement); +proc elna_name_assign_statement(parser_node: ^ElnaTreeAssignStatement) begin elna_name_designator(parser_node^.assignee); elna_name_binary_expression(parser_node^.assignment) -end; +end -proc elna_name_statement(parser_node: ^ElnaTreeStatement); +proc elna_name_statement(parser_node: ^ElnaTreeStatement) begin (* Skipping goto and label declarations. *) if parser_node^.kind = ElnaTreeKind.if_statement then @@ -4787,9 +4779,9 @@ begin elsif parser_node^.kind = ElnaTreeKind.assign_statement then elna_name_assign_statement(parser_node) end -end; +end -proc elna_name_statements(parser_node: ^ElnaTreeStatement); +proc elna_name_statements(parser_node: ^ElnaTreeStatement) begin .elna_name_statements_loop; if parser_node <> nil then @@ -4798,12 +4790,12 @@ begin parser_node := parser_node^.next; goto elna_name_statements_loop end -end; +end -proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration); +proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) var - new_symbol_table: ^ElnaSymbolTable; - symbol_info: Word; + new_symbol_table: ^ElnaSymbolTable + symbol_info: Word begin new_symbol_table := elna_symbol_table_create(symbol_table_global); symbol_info := procedure_info_create(new_symbol_table); @@ -4813,20 +4805,20 @@ begin elna_name_statements(parser_node^.body); elna_symbol_table_enter(symbol_table_global, parser_node^.name, parser_node^.length, symbol_info) -end; +end -proc elna_name_program_body(parser_node: ^ElnaTreeStatement); +proc elna_name_program_body(parser_node: ^ElnaTreeStatement) var - new_symbol_table: ^ElnaSymbolTable; - symbol_info: Word; + new_symbol_table: ^ElnaSymbolTable + symbol_info: Word begin new_symbol_table := elna_symbol_table_create(symbol_table_global); symbol_info := procedure_info_create(new_symbol_table); elna_symbol_table_enter(symbol_table_global, "main", 4, symbol_info) -end; +end -proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable); +proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable) begin .elna_type_conditional_statements_loop; elna_type_binary_expression(parser_node^.condition, symbol_table); @@ -4836,11 +4828,11 @@ begin if parser_node <> nil then goto elna_type_conditional_statements_loop end -end; +end -proc elna_type_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable); +proc elna_type_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable) var - block: ^ElnaTreeConditionalStatements; + block: ^ElnaTreeConditionalStatements begin block := parser_node^.conditionals; @@ -4855,16 +4847,16 @@ begin if block <> nil then elna_type_statements(block, symbol_table) end -end; +end -proc elna_type_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable); +proc elna_type_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable) begin elna_type_binary_expression(parser_node^.returned, symbol_table) -end; +end -proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable); +proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable) var - argument_tree: ^ElnaTreeExpressionList; + argument_tree: ^ElnaTreeExpressionList begin argument_tree := parser_node^.arguments; @@ -4875,15 +4867,15 @@ begin goto elna_type_call_argument end -end; +end -proc elna_type_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable); +proc elna_type_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable) begin elna_type_designator(parser_node^.assignee, symbol_table); elna_type_binary_expression(parser_node^.assignment, symbol_table) -end; +end -proc elna_type_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable); +proc elna_type_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) begin (* Skipping goto and label declarations. *) if parser_node^.kind = ElnaTreeKind.if_statement then @@ -4895,9 +4887,9 @@ begin elsif parser_node^.kind = ElnaTreeKind.assign_statement then elna_type_assign_statement(parser_node, symbol_table) end -end; +end -proc elna_type_statements(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable); +proc elna_type_statements(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable) begin .elna_type_statements_loop; if parser_node <> nil then @@ -4906,40 +4898,40 @@ begin parser_node := parser_node^.next; goto elna_type_statements_loop end -end; +end -proc elna_type_character_literal(parser_node: ^ElnaTreeCharacterLiteral); +proc elna_type_character_literal(parser_node: ^ElnaTreeCharacterLiteral) begin parser_node^.type_decoration := char_type -end; +end -proc elna_type_integer_literal(parser_node: ^ElnaTreeIntegerLiteral); +proc elna_type_integer_literal(parser_node: ^ElnaTreeIntegerLiteral) begin parser_node^.type_decoration := word_type -end; +end -proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral); +proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral) begin parser_node^.type_decoration := word_type -end; +end -proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral); +proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral) begin parser_node^.type_decoration := bool_type -end; +end -proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral); +proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral) var - symbol_info: ^ElnaSymbolTypeInfo; + symbol_info: ^ElnaSymbolTypeInfo begin symbol_info := elna_symbol_table_lookup(symbol_table_global, "Pointer", 7); parser_node^.type_decoration := symbol_info^._type -end; +end -proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: ^ElnaSymbolTable); +proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: ^ElnaSymbolTable) var - variable_info: ^ElnaSymbolInfo; - temporary_info: ^ElnaSymbolTemporaryInfo; + variable_info: ^ElnaSymbolInfo + temporary_info: ^ElnaSymbolTemporaryInfo begin variable_info := elna_symbol_table_lookup(symbol_table, parser_node^.name, parser_node^.length); @@ -4947,14 +4939,14 @@ begin temporary_info := variable_info; parser_node^.type_decoration := temporary_info^.variable_type end -end; +end -proc elna_type_cast_expression(parser_node: ^ElnaTreeCastExpression, symbol_table: ^ElnaSymbolTable); +proc elna_type_cast_expression(parser_node: ^ElnaTreeCastExpression, symbol_table: ^ElnaSymbolTable) begin elna_type_binary_expression(parser_node^.expression, symbol_table) -end; +end -proc elna_type_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable); +proc elna_type_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) begin if parser_node^.kind = ElnaTreeKind.integer_literal then elna_type_integer_literal(parser_node) @@ -4971,13 +4963,13 @@ begin elsif parser_node^.kind = ElnaTreeKind.variable_expression then elna_type_variable_expression(parser_node, symbol_table) end -end; +end -proc elna_type_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable); +proc elna_type_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable) var - base_type: ^ElnaType; - pointer_type: ^ElnaTypePointer; - dereferenced_expression: ^ElnaTreeExpression; + base_type: ^ElnaType + pointer_type: ^ElnaTypePointer + dereferenced_expression: ^ElnaTreeExpression begin elna_type_designator(parser_node^.pointer, symbol_table); @@ -4990,17 +4982,17 @@ begin base_type := pointer_type^.base; end; parser_node^.type_decoration := base_type -end; +end -proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable); +proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable) var - variable_expression: ^ElnaTreeVariableExpression; - base_type: Word; - type_kind: ^ElnaSymbolTypeInfo; - symbol_info: ^ElnaSymbolInfo; - aggregate_type: ^ElnaTypeRecord; - field_count: Word; - current_field: ^ElnaTypeField; + variable_expression: ^ElnaTreeVariableExpression + base_type: Word + type_kind: ^ElnaSymbolTypeInfo + symbol_info: ^ElnaSymbolInfo + aggregate_type: ^ElnaTypeRecord + field_count: Word + current_field: ^ElnaTypeField begin base_type := nil; variable_expression := parser_node^.aggregate; @@ -5035,12 +5027,12 @@ begin end; parser_node^.type_decoration := base_type -end; +end -proc elna_type_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable); +proc elna_type_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable) var - aggregate_type: ^ElnaTypeArray; - base_expression: ^ElnaTreeExpression; + aggregate_type: ^ElnaTypeArray + base_expression: ^ElnaTreeExpression begin base_expression := parser_node^.array; @@ -5049,9 +5041,9 @@ begin aggregate_type := base_expression^.type_decoration; parser_node^.type_decoration := aggregate_type^.base -end; +end -proc elna_type_designator(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable); +proc elna_type_designator(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) begin if parser_node^.kind = ElnaTreeKind.dereference_expression then elna_type_dereference_expression(parser_node, symbol_table) @@ -5064,9 +5056,9 @@ begin else elna_type_simple_expression(parser_node, symbol_table) end -end; +end -proc elna_type_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable); +proc elna_type_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable) begin if parser_node^.kind = ElnaTreeKind.unary_expression then elna_type_designator(parser_node^.operand, symbol_table); @@ -5075,11 +5067,11 @@ begin else elna_type_designator(parser_node, symbol_table) end -end; +end -proc elna_type_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable); +proc elna_type_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable) var - binary_operand: ^ElnaTreeExpression; + binary_operand: ^ElnaTreeExpression begin if parser_node^.kind = ElnaTreeKind.binary_expression then elna_type_unary_expression(parser_node^.rhs, symbol_table); @@ -5091,20 +5083,20 @@ begin else elna_type_unary_expression(parser_node, symbol_table) end -end; +end -proc elna_type_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration); +proc elna_type_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) var - procedure_info: ^ElnaSymbolProcedureInfo; + procedure_info: ^ElnaSymbolProcedureInfo begin 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; +end -proc elna_name_module_declaration(parser_node: ^ElnaTreeModuleDeclaration); +proc elna_name_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) var - current_part: ^ElnaTreeDeclaration; + current_part: ^ElnaTreeDeclaration begin current_part := parser_node^.types; .elna_name_module_declaration_type; @@ -5133,11 +5125,11 @@ begin if parser_node^.body <> nil then elna_name_program_body(parser_node^.body) end -end; +end -proc elna_type_module_declaration(parser_node: ^ElnaTreeModuleDeclaration); +proc elna_type_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) var - current_part: ^ElnaTreeDeclaration; + current_part: ^ElnaTreeDeclaration begin current_part := parser_node^.types; .elna_type_module_declaration_type; @@ -5156,16 +5148,16 @@ begin goto elna_type_module_declaration_procedure end -end; +end -proc compile(); +proc compile() var - parser_node: Word; - tac: Word; - rtl: Word; - error_list: ElnaList; - compiled: Word; - lexer_state: ElnaLexerCursor; + parser_node: Word + tac: Word + rtl: Word + error_list: ElnaList + compiled: Word + lexer_state: ElnaLexerCursor begin elna_lexer_initialize(@lexer_state, source_code); elna_list_initialize(@error_list); @@ -5184,7 +5176,7 @@ begin end; return compiled -end; +end (** * Looks for a symbol in the given symbol table. @@ -5196,11 +5188,11 @@ end; * * Returns the symbol pointer or nil. *) -proc elna_symbol_table_lookup(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word); +proc elna_symbol_table_lookup(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word) var - result: Word; - symbol_table_length: Word; - current_entry: ^ElnaSymbolEntry; + result: Word + symbol_table_length: Word + current_entry: ^ElnaSymbolEntry begin result := nil; symbol_table_length := symbol_table^.count; @@ -5230,7 +5222,7 @@ begin .symbol_table_lookup_end; return result -end; +end (** * Create a new local symbol table in the symbol memory region after the last @@ -5241,9 +5233,9 @@ end; * * Returns newly allocated, empty symbol table. *) -proc elna_symbol_table_create(parent: ^ElnaSymbolTable); +proc elna_symbol_table_create(parent: ^ElnaSymbolTable) var - new_symbol_table: ^ElnaSymbolTable; + new_symbol_table: ^ElnaSymbolTable begin new_symbol_table := malloc(#size(ElnaSymbolTable)); new_symbol_table^.symbols := malloc(16384); @@ -5251,7 +5243,7 @@ begin new_symbol_table^.parent := parent; return new_symbol_table -end; +end (** * Inserts a symbol into the table. @@ -5262,9 +5254,9 @@ end; * name_length - Symbol name length. * symbol - Symbol pointer. *) -proc elna_symbol_table_enter(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word, symbol: Word); +proc elna_symbol_table_enter(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word, symbol: Word) var - symbol_pointer: ^ElnaSymbolEntry; + symbol_pointer: ^ElnaSymbolEntry begin (* Calculate the offset for the new symbol. *) symbol_pointer := symbol_table^.symbols + symbol_table^.count; @@ -5275,14 +5267,14 @@ begin (* Increment the symbol table length. *) symbol_table^.count := symbol_table^.count + 1 -end; +end (* Build global symbol table with predefined symbols. *) -proc elna_symbol_table_build(); +proc elna_symbol_table_build() var - current_info: ^ElnaSymbolTypeInfo; - current_type: ^ElnaType; - global_pointer: ^Word; + current_info: ^ElnaSymbolTypeInfo + current_type: ^ElnaType + global_pointer: ^Word begin symbol_table_global := elna_symbol_table_create(nil); @@ -5314,9 +5306,9 @@ begin char_type^.alignment := 1; current_info := type_info_create(char_type); elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info) -end; +end -proc elna_lexer_classifications1(); +proc elna_lexer_classifications1() begin classification[1] := ElnaLexerClass.eof; classification[10] := ElnaLexerClass.space; @@ -5324,9 +5316,9 @@ begin classification[14] := ElnaLexerClass.space; classification[33] := ElnaLexerClass.space; classification[34] := ElnaLexerClass.single -end; +end -proc elna_lexer_classifications2(); +proc elna_lexer_classifications2() begin classification[35] := ElnaLexerClass.double_quote; classification[36] := ElnaLexerClass.number_sign; @@ -5358,9 +5350,9 @@ begin classification[62] := ElnaLexerClass.equals; classification[63] := ElnaLexerClass.greater; classification[64] := ElnaLexerClass.other -end; +end -proc elna_lexer_classifications3(); +proc elna_lexer_classifications3() begin classification[65] := ElnaLexerClass.single; classification[66] := ElnaLexerClass.alpha; @@ -5396,9 +5388,9 @@ begin classification[96] := ElnaLexerClass.alpha; classification[97] := ElnaLexerClass.other; classification[98] := ElnaLexerClass.hex -end; +end -proc elna_lexer_classifications4(); +proc elna_lexer_classifications4() begin classification[99] := ElnaLexerClass.hex; classification[100] := ElnaLexerClass.hex; @@ -5429,14 +5421,14 @@ begin classification[125] := ElnaLexerClass.single; classification[126] := ElnaLexerClass.other; classification[127] := ElnaLexerClass.single -end; +end (** * Initializes the array with character classes. *) -proc elna_lexer_classifications(); +proc elna_lexer_classifications() var - code: Word; + code: Word begin code := 1; @@ -5462,12 +5454,12 @@ begin if code < 257 then goto elna_lexer_classifications_other end -end; +end -proc elna_lexer_get_transition(current_state: Word, character_class: Word); +proc elna_lexer_get_transition(current_state: Word, character_class: Word) var - column_position: Word; - target: Word; + column_position: Word + target: Word begin (* Each state is 8 bytes long (2 words: action and next state). There are 23 character classes, so a transition row 8 * 23 = 184 bytes long. *) @@ -5477,7 +5469,7 @@ begin target := @transition_table[current_state]; return target + column_position -end; +end (** * Parameters: @@ -5486,15 +5478,15 @@ end; * action - Action to assign. * next_state - Next state to assign. *) -proc elna_lexer_set_transition(current_state: Word, character_class: Word, action: Word, next_state: ElnaLexerState); +proc elna_lexer_set_transition(current_state: Word, character_class: Word, action: Word, next_state: ElnaLexerState) var - transition: ^ElnaLexerTransition; + transition: ^ElnaLexerTransition begin transition := elna_lexer_get_transition(current_state, character_class); transition^.action := action; transition^.next_state := next_state -end; +end (* Sets same action and state transition for all character classes in one transition row. *) @@ -5504,7 +5496,7 @@ end; * default_action - Default action (Callback). * next_state - Next state (Transition state enumeration). *) -proc elna_lexer_default_transition(current_state: Word, default_action: Word, next_state: ElnaLexerState); +proc elna_lexer_default_transition(current_state: Word, default_action: Word, next_state: ElnaLexerState) begin elna_lexer_set_transition(current_state, ElnaLexerClass.invalid, default_action, next_state); elna_lexer_set_transition(current_state, ElnaLexerClass.digit, default_action, next_state); @@ -5529,7 +5521,7 @@ begin elna_lexer_set_transition(current_state, ElnaLexerClass.less, default_action, next_state); elna_lexer_set_transition(current_state, ElnaLexerClass.other, default_action, next_state); elna_lexer_set_transition(current_state, ElnaLexerClass.number_sign, default_action, next_state) -end; +end (** * The transition table describes transitions from one state to another, given @@ -5539,7 +5531,7 @@ end; * the amount of classes. So given the current state and a classified character * the table can be used to look up the next state. *) -proc elna_lexer_transitions(); +proc elna_lexer_transitions() begin (* Start state. *) elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish); @@ -5664,12 +5656,12 @@ begin elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.trait); elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.zero, ElnaLexerAction.accumulate, ElnaLexerState.trait); elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.trait) -end; +end (** * One time lexer initialization. *) -proc elna_lexer_initialize(cursor: ^ElnaLexerCursor, code_pointer: Word); +proc elna_lexer_initialize(cursor: ^ElnaLexerCursor, code_pointer: Word) begin elna_lexer_classifications(); elna_lexer_transitions(); @@ -5681,12 +5673,12 @@ begin cursor^.position.start_location.column := 1; cursor^.position.end_location.line := 1; cursor^.position.end_location.column := 1 -end; +end (* Returns true or false depending whether two strings are equal. *) -proc string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word) -> Bool; +proc string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word) -> Bool var - result: Bool; + result: Bool begin if lhs_length = rhs_length then result := memcmp(lhs_pointer, rhs_pointer, lhs_length) = 0 @@ -5694,22 +5686,22 @@ begin result := false end; return result -end; +end -proc elna_lexer_token_create(kind: ElnaLexerKind, position: ^ElnaPosition) -> ^ElnaLexerToken; +proc elna_lexer_token_create(kind: ElnaLexerKind, position: ^ElnaPosition) -> ^ElnaLexerToken var - result: ^ElnaLexerToken; + result: ^ElnaLexerToken begin result := malloc(#size(ElnaLexerToken)); result^.kind := kind; - memcpy(@result^.position, position, #size(ElnaPosition)); + result^.position := position; return result -end; +end -proc elna_lexer_classify_keyword(position_start: ^Char, position_end: Word, position: ^ElnaPosition) -> ^ElnaLexerToken; +proc elna_lexer_classify_keyword(position_start: ^Char, position_end: Word, position: ^ElnaPosition) -> ^ElnaLexerToken var - result: ^ElnaLexerToken; + result: ^ElnaLexerToken begin result := elna_lexer_token_create(ElnaLexerKind.identifier, position); result^.start := position_start; @@ -5763,12 +5755,12 @@ begin result^.kind := ElnaLexerKind._cast end; return result -end; +end -proc elna_lexer_classify_finalize(start_position: ^Char, position: ^ElnaPosition) -> ^ElnaLexerToken; +proc elna_lexer_classify_finalize(start_position: ^Char, position: ^ElnaPosition) -> ^ElnaLexerToken var - character: Char; - result: ^ElnaLexerToken; + character: Char + result: ^ElnaLexerToken begin character := start_position^; @@ -5786,12 +5778,12 @@ begin result := elna_lexer_token_create(ElnaLexerKind.greater_than, position) end; return result -end; +end -proc elna_lexer_classify_single(start_position: ^Char, position: ^ElnaPosition) -> ^ElnaLexerToken; +proc elna_lexer_classify_single(start_position: ^Char, position: ^ElnaPosition) -> ^ElnaLexerToken var - character: Char; - result: ^ElnaLexerToken; + character: Char + result: ^ElnaLexerToken begin result := malloc(#size(ElnaLexerToken)); character := start_position^; @@ -5830,13 +5822,13 @@ begin result := elna_lexer_token_create(ElnaLexerKind.pipe, position) end; return result -end; +end -proc elna_lexer_classify_composite(start_position: ^Char, one_before_last: ^Char, position: ^ElnaPosition) -> ^ElnaLexerToken; +proc elna_lexer_classify_composite(start_position: ^Char, one_before_last: ^Char, position: ^ElnaPosition) -> ^ElnaLexerToken var - first_character: Char; - last_character: Char; - result: ^ElnaLexerToken; + first_character: Char + last_character: Char + result: ^ElnaLexerToken begin first_character := start_position^; last_character := one_before_last^; @@ -5857,12 +5849,12 @@ begin result := elna_lexer_token_create(ElnaLexerKind.arrow, position) end; return result -end; +end -proc elna_lexer_classify_delimited(start_position: ^Char, end_position: Word, position: ^ElnaPosition) -> ^ElnaLexerToken; +proc elna_lexer_classify_delimited(start_position: ^Char, end_position: Word, position: ^ElnaPosition) -> ^ElnaLexerToken var - delimiter: Char; - result: ^ElnaLexerToken; + delimiter: Char + result: ^ElnaLexerToken begin delimiter := start_position^; @@ -5877,22 +5869,22 @@ begin result^.length := end_position - start_position; return result -end; +end -proc elna_lexer_classify_integer(start_position: Word, end_position: Word, position: ^ElnaPosition) -> ^ElnaLexerToken; +proc elna_lexer_classify_integer(start_position: Word, end_position: Word, position: ^ElnaPosition) -> ^ElnaLexerToken var - result: ^ElnaLexerToken; + result: ^ElnaLexerToken begin result := elna_lexer_token_create(ElnaLexerKind.integer, position); result^.start := start_position; result^.length := end_position - start_position; return result -end; +end -proc elna_lexer_execute_action(cursor: ^ElnaLexerCursor, action_to_perform: Word) -> ^ElnaLexerToken; +proc elna_lexer_execute_action(cursor: ^ElnaLexerCursor, action_to_perform: Word) -> ^ElnaLexerToken var - token: ^ElnaLexerToken; + token: ^ElnaLexerToken begin token := nil; @@ -5926,21 +5918,21 @@ begin token := elna_lexer_classify_delimited(cursor^.start, cursor^.finish, @cursor^.position) end; return token -end; +end -proc elna_lexer_execute_transition(cursor: ^ElnaLexerCursor, kind: ^ElnaLexerKind) -> ^ElnaLexerToken; +proc elna_lexer_execute_transition(cursor: ^ElnaLexerCursor, kind: ^ElnaLexerKind) -> ^ElnaLexerToken var - next_transition: ^ElnaLexerTransition; - current_character: Char; + next_transition: ^ElnaLexerTransition + current_character: Char begin current_character := cursor^.finish^; next_transition := elna_lexer_get_transition(cursor^.state, classification[current_character + 1]); cursor^.state := next_transition^.next_state; return elna_lexer_execute_action(cursor, next_transition^.action, kind) -end; +end -proc elna_lexer_classify_space(start_position: ^Char, location: ^ElnaLocation); +proc elna_lexer_classify_space(start_position: ^Char, location: ^ElnaLocation) begin if start_position^ = '\n' then location^.line := location^.line + 1; @@ -5948,21 +5940,21 @@ begin else location^.column := location^.column + 1 end -end; +end -proc elna_lexer_advance(cursor: ^ElnaLexerCursor); +proc elna_lexer_advance(cursor: ^ElnaLexerCursor) begin cursor^.finish := cursor^.finish + 1; cursor^.position.end_location.column := cursor^.position.end_location.column + 1 -end; +end (** * Reads the next token and writes its type into the address in the kind parameter. * Resets the lexer state for reading the next token. *) -proc elna_lexer_peek(cursor: ^ElnaLexerCursor) -> ^ElnaLexerToken; +proc elna_lexer_peek(cursor: ^ElnaLexerCursor) -> ^ElnaLexerToken var - token: ^ElnaLexerToken; + token: ^ElnaLexerToken begin if cursor^.token = nil then cursor^.state := ElnaLexerState.start; @@ -5976,33 +5968,33 @@ begin cursor^.token := token end; return cursor^.token -end; +end (** * Reads the token and advance the lexer. *) -proc elna_lexer_read(cursor: ^ElnaLexerCursor) -> ^ElnaLexerToken; +proc elna_lexer_read(cursor: ^ElnaLexerCursor) -> ^ElnaLexerToken var - token: ^ElnaLexerToken; + token: ^ElnaLexerToken begin token := elna_lexer_peek(cursor); cursor^.token := nil; cursor^.start := cursor^.finish; - memcpy(@cursor^.position.start_location, @cursor^.position.end_location, #size(ElnaLocation)); + cursor^.position.start_location := cursor^.position.end_location; return token -end; +end -proc initialize_global_state(); +proc initialize_global_state() begin compiler_strings_position := @compiler_strings; source_code := malloc(495616) -end; +end -proc read_source(); +proc read_source() var - last_read: Word; - offset: Word; + last_read: Word + offset: Word begin (* Read the source from the standard input. *) offset := source_code; @@ -6014,7 +6006,7 @@ begin offset := offset + last_read; goto start_read end -end; +end begin initialize_global_state(); @@ -6026,4 +6018,4 @@ begin else exit(4) end -end; +end.