From 90a48de0a58f6f2512370c7ce0c32a4e16f496d0 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 23 May 2026 00:42:02 +0200 Subject: [PATCH] Implement 1 byte variable operations --- Rakefile | 8 +- boot/stage21/cl.elna | 599 ++++++++++++++++++++++++++----------------- 2 files changed, 362 insertions(+), 245 deletions(-) diff --git a/Rakefile b/Rakefile index 499a70b..4cb08d0 100644 --- a/Rakefile +++ b/Rakefile @@ -46,11 +46,9 @@ task :convert do current_stage << <<~FUN proc f(); var - x: ^ElnaLocation; + x: ElnaRtlObjectInfo; begin - x := malloc(#size(ElnaLocation)); - x^.line := 5; - x^.column := cast(3: Word) + x.allocated := true end; begin @@ -60,6 +58,8 @@ task :convert do current_stage << <<~FUN var FUN + elsif line.end_with?("allocated: Word\n") + current_stage << "\t\tallocated: Bool\n" else current_stage << line end diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna index 72d7e01..9e88b6a 100644 --- a/boot/stage21/cl.elna +++ b/boot/stage21/cl.elna @@ -523,6 +523,12 @@ type nop ); ElnaTacKind = (list, label, constant, variable); + + (* + - If value is a variable or label, length is its name length. + - If value is a constant, length is its size. + - If value is a list, length is the list length. + *) ElnaTacOperand = record kind: ElnaTacKind; value: Word; @@ -604,10 +610,23 @@ type body: ElnaList; variable_map: ^ElnaSymbolTable end; + ElnaRtlTypeKind = (byte, long_word, byte_array); + ElnaRtlType = record + kind: ElnaRtlTypeKind + end; + ElnaRtlTypeWord = record + kind: ElnaRtlTypeKind + end; + ElnaRtlTypeByteArray = record + kind: ElnaRtlTypeKind; + size: Word; + alignment: Word + end; ElnaRtlInstruction = record next: Word; operator: ElnaRtlOperator; - operands: [3]ElnaRtlOperand + operands: [3]ElnaRtlOperand; + types: [2]^ElnaRtlType end; ElnaRtlRegister = ( zero, @@ -643,18 +662,6 @@ type t5, t6 ); - ElnaRtlTypeKind = (long_word, byte_array); - ElnaRtlType = record - kind: ElnaRtlTypeKind - end; - ElnaRtlTypeWord = record - kind: ElnaRtlTypeKind - end; - ElnaRtlTypeByteArray = record - kind: ElnaRtlTypeKind; - size: Word; - alignment: Word - end; ElnaRtlInfoKind = (object_info, static_info); ElnaRtlInfo = record kind: ElnaRtlInfoKind @@ -683,6 +690,8 @@ var *) transition_table: [19][23]ElnaLexerTransition; word_type: ^ElnaType; + char_type: ^ElnaType; + bool_type: ^ElnaType; source_code: Word; compiler_strings_position: Word; @@ -691,35 +700,6 @@ var temporary_variable_counter: Word; pseudo_counter: Word; -(** - * Calculates and returns the string token length between quotes, including the - * escaping slash characters. - * - * Parameters: - * string - String token pointer. - * - * Returns the length in a0. - *) -proc _string_length(string: Word) -> Word; -var - counter: Word; - current_byte: Word; -begin - (* Reset the counter. *) - counter := 0; - - .string_length_loop; - string := string + 1; - - current_byte := _load_byte(string); - if current_byte <> '"' then - counter := counter + 1; - goto string_length_loop - end; - - return counter -end; - (** * Adds a string to the global, read-only string storage. * @@ -728,7 +708,7 @@ end; * * Returns the offset from the beginning of the storage to the new string in a0. *) -proc _add_string(string: Word); +proc _add_string(string: ^Char) -> Word; var contents: Word; result: Word; @@ -739,12 +719,14 @@ begin .add_string_loop; current_byte := _load_byte(contents); - if current_byte <> '"' then + (* if current_byte <> '"' then *) + if current_byte <> 34 then _store_byte(current_byte, compiler_strings_position); compiler_strings_position := compiler_strings_position + 1; contents := contents + 1; - if current_byte <> '\\' then + (* if current_byte <> '\\' then *) + if current_byte <> 92 then compiler_strings_length := compiler_strings_length + 1 end; goto add_string_loop @@ -788,39 +770,6 @@ begin write(1, @character, 1) end; -(** - * Write null terminated string. - * - * Parameters: - * string - String. - *) -proc _write_z(string: Word); -begin - printf("%s\0", string); - fflush(nil) -end; - -(** - * Detects if the passed character is a 7-bit alpha character or an underscore. - * - * Paramters: - * character - Tested character. - * - * Sets a0 to 1 if the character is an alpha character or underscore, sets it to 0 otherwise. - *) -proc _is_alpha(character: Word); -var - is_underscore: Word; -begin - is_underscore := character = '_'; - - return isalpha(character) or is_underscore -end; - -proc _is_alnum(character: Word); - return _is_alpha(character) or isdigit(character) -end; - proc elna_list_initialize(list: ^ElnaList); begin list^.first := nil; @@ -913,6 +862,8 @@ begin result^.operator := operator; result^.next := nil; + result^.types[1] := nil; + result^.types[2] := nil; return result end; @@ -937,7 +888,7 @@ begin if operand^.kind = ElnaTacKind.constant then instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand^.value, operand^.length, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand^.value, 0, 0); elna_list_append(instructions, instruction) elsif operand^.kind = ElnaTacKind.variable then instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); @@ -952,15 +903,18 @@ proc elna_rtl_operand_value(instructions: ^ElnaList, tac_operand: ^ElnaTacOperan var instruction: ^ElnaRtlInstruction; pseudo_symbol: ^ElnaRtlObjectInfo; + rtl_type: ^ElnaRtlType; begin pseudo_symbol := nil; if tac_operand^.kind = ElnaTacKind.constant then - elna_rtl_generate_pseudo(rtl_operand, variable_map); + rtl_type := elna_rtl_constant_type(tac_operand^.length); + pseudo_symbol := elna_rtl_generate_pseudo(rtl_operand, variable_map, rtl_type); instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); elna_rtl_instruction_set_operand(instruction, 1, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, tac_operand^.value, tac_operand^.length, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, tac_operand^.value, 0, 0); + instruction^.types[1] := rtl_type; elna_list_append(instructions, instruction) elsif tac_operand^.kind = ElnaTacKind.variable then pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_operand^.value, tac_operand^.length); @@ -1004,12 +958,16 @@ var result: ^ElnaRtlInstruction; rtl_operand: ElnaRtlOperand; intermediate: ElnaRtlOperand; + rtl_type: ^ElnaRtlType; begin - elna_rtl_generate_pseudo(@intermediate, variable_map); + rtl_type := malloc(#size(ElnaRtlTypeWord)); + rtl_type^.kind := ElnaRtlTypeKind.long_word; + elna_rtl_generate_pseudo(@intermediate, variable_map, rtl_type); result := elna_rtl_instruction_create(ElnaRtlOperator.li); elna_rtl_instruction_set_operand(result, 1, intermediate.kind, intermediate.value, intermediate.length, 0); elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.immediate, tac_instruction^.operands[3].value, 0, 0); + result^.types[1] := rtl_type; elna_list_append(instructions, result); result := elna_rtl_instruction_create(ElnaRtlOperator.mul); @@ -1193,13 +1151,19 @@ var 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, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); + rtl_type := pseudo_symbol^.rtl_type + else + rtl_type := elna_rtl_constant_type(tac_instruction^.operands[1].length) + end; elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); - pseudo_symbol := elna_symbol_table_lookup(variable_map, - tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); - if pseudo_symbol <> nil then - if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then + if tac_instruction^.operands[1].kind = ElnaTacKind.variable then + if rtl_type^.kind = ElnaRtlTypeKind.byte_array then instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, @@ -1211,16 +1175,17 @@ begin elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); elna_list_append(instructions, instruction); - elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type) - else - pseudo_symbol = nil + elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type); + + rtl_type := nil end end; - if pseudo_symbol = nil then + if rtl_type <> nil then instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); elna_rtl_instruction_set_operand(instruction, 1, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); + instruction^.types[1] := rtl_type; elna_list_append(instructions, instruction) end; end; @@ -1231,13 +1196,20 @@ var 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, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); + rtl_type := pseudo_symbol^.rtl_type + else + rtl_type := elna_rtl_constant_type(tac_instruction^.operands[1].length) + end; elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand); - pseudo_symbol := elna_symbol_table_lookup(variable_map, - tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); - if pseudo_symbol <> nil then - if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then + if tac_instruction^.operands[1].kind = ElnaTacKind.variable then + if rtl_type^.kind = ElnaRtlTypeKind.byte_array then instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo_mem, @@ -1255,13 +1227,15 @@ begin elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0); elna_list_append(instructions, instruction); - elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type) - else - pseudo_symbol := nil + elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type); + + rtl_type := nil end end; - if pseudo_symbol = nil then - elna_rtl_generate_pseudo(@target_operand, variable_map); + if rtl_type <> nil then + address_type := elna_rtl_constant_type(4); + elna_rtl_generate_pseudo(@target_operand, variable_map, address_type); + instruction := elna_rtl_operand_address(variable_map, @tac_instruction^.operands[2], @target_operand); elna_list_append(instructions, instruction); @@ -1269,6 +1243,7 @@ begin elna_rtl_instruction_set_operand(instruction, 1, source_operand.kind, source_operand.value, source_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length, tac_instruction^.operands[3].value); + instruction^.types[1] := rtl_type; elna_list_append(instructions, instruction) end end; @@ -1301,6 +1276,8 @@ begin elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); + instruction^.types[1] := pseudo_symbol^.rtl_type; + elna_list_append(instructions, instruction) end end; @@ -1347,7 +1324,8 @@ begin tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, tac_instruction^.operands[2].value); - elna_list_append(instructions, instruction) + elna_list_append(instructions, instruction); + instruction^.types[1] := pseudo_symbol^.rtl_type end end; @@ -1371,15 +1349,16 @@ var source_operand: ElnaRtlOperand; pseudo_symbol: ^ElnaRtlObjectInfo; begin - elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand); pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); + elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand); if source_operand.kind = ElnaRtlKind.pseudo then instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0); + instruction^.types[1] := pseudo_symbol^.rtl_type; elna_list_append(instructions, instruction); else instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); @@ -1471,6 +1450,8 @@ begin tac_instruction^.operands[1].value, tac_instruction^.operands[1].length, 0); elna_rtl_instruction_set_operand(instruction, 2, tac_instruction^.operands[2].kind, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); + elna_rtl_instruction_set_operand(instruction, 3, tac_instruction^.operands[3].kind, + tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0); elna_list_append(instructions, instruction) end end; @@ -1484,7 +1465,8 @@ begin elna_list_append(instructions, result) end; -proc elna_riscv_instruction_name(instruction_kind: ElnaRtlOperator) -> Word; +proc elna_riscv_instruction_name(instruction_kind: ElnaRtlOperator, + source_type: ^ElnaRtlType, destination_type: ^ElnaRtlType) -> Word; var argument_count: Word; begin @@ -1502,10 +1484,18 @@ begin _write_s("\taddi", 5) elsif instruction_kind = ElnaRtlOperator.lw then argument_count := 2; - _write_s("\tlw", 3) + if source_type^.kind = ElnaRtlTypeKind.byte then + _write_s("\tlb", 3) + else + _write_s("\tlw", 3) + end elsif instruction_kind = ElnaRtlOperator.sw then argument_count := 2; - _write_s("\tsw", 3) + if source_type^.kind = ElnaRtlTypeKind.byte then + _write_s("\tsb", 3) + else + _write_s("\tsw", 3) + end elsif instruction_kind = ElnaRtlOperator.jal then argument_count := 1; _write_s("\tcall", 5) @@ -1576,14 +1566,17 @@ var begin operand_type := instruction^.operands[n].kind; - _write_c(' '); + (* _write_c(' '); *) + _write_c(32); if operand_type = ElnaRtlKind.register then elna_riscv_register(instruction^.operands[n].value) elsif operand_type = ElnaRtlKind.memory then _write_i(instruction^.operands[n].offset); - _write_c('('); + (* _write_c('('); *) + _write_c(40); elna_riscv_register(instruction^.operands[n].value); - _write_c(')') + (* _write_c(')') *) + _write_c(41) elsif operand_type = ElnaRtlKind.data then if instruction^.operands[n].length = 0 then _write_label(instruction^.operands[n].value, 0) @@ -1602,22 +1595,28 @@ proc elna_alloc_variable(operand_value: Word, operand_length: Word, var 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 goto elna_alloc_variable_end end; - if pseudo_symbol^.allocated = false then - pseudo_symbol^.allocated := true; - pseudo_symbol^.counter := temporary_variable_counter; - + (* pseudo_symbol^.allocated = false *) + if pseudo_symbol^.allocated = 0 then if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then pseudo_type := pseudo_symbol^.rtl_type; - temporary_variable_counter := temporary_variable_counter + pseudo_type^.size + pseudo_symbol^.counter := _align_at(temporary_variable_counter, pseudo_type^.alignment); + type_size := pseudo_type^.size + elsif pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte then + pseudo_symbol^.counter := temporary_variable_counter; + type_size := 1 else - temporary_variable_counter := temporary_variable_counter + 4 - end + pseudo_symbol^.counter := _align_at(temporary_variable_counter, 4); + type_size := 4 + end; + temporary_variable_counter := pseudo_symbol^.counter + type_size; + pseudo_symbol^.allocated := 1 (* true *) end; .elna_alloc_variable_end; return pseudo_symbol @@ -1642,6 +1641,7 @@ begin elna_rtl_instruction_set_operand(store_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.sp, 0, pseudo_symbol^.counter); + store_instruction^.types[1] := pseudo_symbol^.rtl_type; elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_list_insert(instructions, instruction, store_instruction); @@ -1686,10 +1686,14 @@ begin elna_rtl_instruction_set_operand(store_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.t1, 0, instruction^.operands[2].offset); + store_instruction^.types[1] := instruction^.types[1]; pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length, variable_map); instruction^.operator := ElnaRtlOperator.lw; + (* Because it is an address. *) + instruction^.types[1] := malloc(#size(ElnaRtlTypeWord)); + instruction^.types[1]^.kind := ElnaRtlTypeKind.long_word; elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, @@ -1717,6 +1721,9 @@ begin instruction^.operands[2].offset); instruction^.operator := ElnaRtlOperator.lw; + (* Because it is an address. *) + instruction^.types[1] := malloc(#size(ElnaRtlTypeWord)); + instruction^.types[1]^.kind := ElnaRtlTypeKind.long_word; elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, @@ -1760,12 +1767,13 @@ begin elna_rtl_instruction_set_operand(load_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.t1, 0, 0) else - pseudo_symbol := elna_alloc_variable(target_operand.value, target_operand.length, - variable_map); + pseudo_symbol := elna_alloc_variable(target_operand.value, target_operand.length, variable_map); instruction^.operator = ElnaRtlOperator.sw; elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, - ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) + ElnaRtlRegister.sp, 0, pseudo_symbol^.counter); + + instruction^.types[1] := pseudo_symbol^.rtl_type end elsif destination_pseudo then pseudo_symbol := elna_symbol_table_lookup(variable_map, target_operand.value, target_operand.length); @@ -1789,9 +1797,10 @@ begin source_operand.value, source_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) - end + end; + instruction^.types[1] := pseudo_symbol^.rtl_type elsif source_pseudo then - pseudo_symbol := elna_symbol_table_lookup(variable_map, source_operand.value, source_operand.length); + pseudo_symbol := elna_alloc_variable(source_operand.value, source_operand.length, variable_map); if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then load_instruction := malloc(#size(ElnaRtlInstruction)); @@ -1803,14 +1812,14 @@ begin load_instruction^.operator = ElnaRtlOperator.lw; elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, - target_operand.value, target_operand.length, 0) + target_operand.value, target_operand.length, 0); + load_instruction^.types[1] := pseudo_symbol^.rtl_type else - pseudo_symbol := elna_alloc_variable(source_operand.value, source_operand.length, - variable_map); instruction^.operator = ElnaRtlOperator.lw; elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) - end + end; + instruction^.types[1] := pseudo_symbol^.rtl_type end; return instruction end; @@ -1846,9 +1855,10 @@ begin elna_list_insert(instructions, instruction, main_instruction); load_instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); - elna_rtl_instruction_set_operand(load_instruction, 1, ElnaRtlKind.register, target, 0, 0); elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, target, 0, 0); + load_instruction^.types[1] := pseudo_symbol^.rtl_type; + elna_list_insert(instructions, instruction, load_instruction) else instruction^.operator := ElnaRtlOperator.lw; @@ -1856,6 +1866,8 @@ begin elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, target, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.sp, 0, pseudo_symbol^.counter); + instruction^.types[1] := pseudo_symbol^.rtl_type; + elna_list_insert(instructions, instruction, main_instruction); end; instruction := main_instruction @@ -1924,6 +1936,7 @@ begin elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.sp, 0, pseudo_symbol^.counter); + instruction^.types[1] := pseudo_symbol^.rtl_type; elna_list_insert(instructions, instruction, new_instruction) end @@ -1951,7 +1964,8 @@ begin if instruction^.operator = ElnaRtlOperator.label then _write_label(instruction^.operands[1].value, instruction^.operands[1].length); - _write_c(':') + (* _write_c(':') *) + _write_c(58) elsif instruction^.operator = ElnaRtlOperator.allocate_stack then operand_value := instruction^.operands[1].value; @@ -1966,14 +1980,21 @@ begin printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value - 4, operand_value - 8, operand_value); fflush(nil) elsif instruction^.operator = ElnaRtlOperator.nop then - operand_value := instruction^.operands[1].value; + operand_value := instruction^.operands[1].kind; - printf("\n# copy (%i %.*s) (%i %.*s)\n\0", instruction^.operands[1].kind, - instruction^.operands[1].length, operand_value, - instruction^.operands[2].kind, instruction^.operands[2].length, instruction^.operands[2].value); + if operand_value = ElnaTacKind.constant then + printf("\n# copy %i (%i %i) (%i %.*s)\n\0", instruction^.operands[3].kind, + instruction^.operands[1].kind, instruction^.operands[1].value, + instruction^.operands[2].kind, instruction^.operands[2].length, instruction^.operands[2].value) + else + printf("\n# copy %i (%i %.*s) (%i %.*s)\n\0", instruction^.operands[3].kind, + instruction^.operands[1].kind, instruction^.operands[1].length, instruction^.operands[1].value, + instruction^.operands[2].kind, instruction^.operands[2].length, instruction^.operands[2].value) + end; fflush(nil) else - argument_count := elna_riscv_instruction_name(instruction^.operator) + argument_count := elna_riscv_instruction_name(instruction^.operator, + instruction^.types[1], instruction^.types[2]) end; current_argument := 1; @@ -1983,11 +2004,12 @@ begin current_argument := current_argument + 1 end; if current_argument <= argument_count then - _write_c(','); + (* _write_c(','); *) + _write_c(44); goto elna_riscv_instruction_loop end; - _write_c('\n') + _write_c(10) end; proc elna_rtl_instructions(instructions: ^ElnaList, instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); @@ -2061,7 +2083,8 @@ begin printf("%.*s:\n\0", procedure^.length, procedure^.name); elna_riscv_instructions(procedure^.body); - _write_z("\tret\n\0"); + printf("\tret\n\0"); + fflush(nil); procedure := procedure^.next; if procedure <> nil then @@ -2129,21 +2152,26 @@ begin elna_alloc_procedure(pair^.code) end; +proc _align_at(address: Word, alignment: Word) -> Word; +begin + if address % alignment then + address := address + alignment + end; + address := address / alignment; + address := address * alignment; + + return address +end; + proc elna_fixup_instructions(instructions: ^ElnaList); var instruction: ^ElnaRtlInstruction; stack_size: Word; begin instruction := instructions^.first; - stack_size := instruction^.operands[1].value; (* Align the stack. *) - stack_size := stack_size + 8; - if stack_size % 16 then - stack_size := stack_size + 16 - end; - stack_size := stack_size / 16; - stack_size := stack_size * 16; + stack_size := _align_at(instruction^.operands[1].value + 8, 16); instruction^.operands[1].value := stack_size; instruction := instructions^.last; @@ -2173,19 +2201,21 @@ var compiler_strings_end: Word; current_byte: Word; begin - _write_z(".globl main\n\n\0"); - _write_z(".section .data\n\0"); + printf(".globl main\n\n\0"); + printf(".section .data\n\0"); elna_riscv_variable(pair^.data); - _write_z(".section .text\n\n\0"); - _write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0"); - _write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0"); + printf(".section .text\n\n\0"); + printf(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0"); + printf(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0"); elna_riscv_procedure(pair^.code); - _write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0"); - _write_c('"'); + printf(".section .rodata\n.type strings, @object\nstrings: .ascii \0"); + fflush(nil); + (* _write_c('"'); *) + _write_c(34); compiler_strings_copy := @compiler_strings; compiler_strings_end := compiler_strings_position; @@ -2198,8 +2228,9 @@ begin goto elna_riscv_module_loop end; - _write_c('"'); - _write_c('\n'); + (* _write_c('"'); *) + _write_c(34); + _write_c(10); end; proc elna_parser_integer_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeIntegerLiteral; @@ -2254,21 +2285,21 @@ proc elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, ope begin operand^.kind := ElnaTacKind.constant; operand^.value := integer_literal_node^.value; - operand^.length := 0 + operand^.length := 4 end; proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand: ^ElnaTacOperand); begin operand^.kind := ElnaTacKind.constant; operand^.value := boolean_literal_node^.value; - operand^.length := 0 + operand^.length := 1 end; proc elna_tac_nil_literal(nil_node: Word, operand: ^ElnaTacOperand); begin operand^.kind := ElnaTacKind.constant; operand^.value := 0; - operand^.length := 0 + operand^.length := 4 end; proc elna_parser_character_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCharacterLiteral; @@ -2288,10 +2319,54 @@ begin end; proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand: ^ElnaTacOperand); +var + next_character: Word; begin operand^.kind := ElnaTacKind.constant; - operand^.value := character_literal_node^.value; - operand^.length := character_literal_node^.length + next_character := _load_byte(character_literal_node^.value + 1); + + (* Escape. *) + if next_character = 92 then + next_character := _load_byte(character_literal_node^.value + 2); + + if next_character = 92 then + (* \\ Backslash. *) + operand^.value := next_character + elsif next_character = 110 then + (* \n Newline. *) + operand^.value := 10 + elsif next_character = 97 then + (* \a Bell. *) + operand^.value := 7 + elsif next_character = 98 then + (* \b Backspace. *) + operand^.value := 8 + elsif next_character = 116 then + (* \t Tab. *) + operand^.value := 9 + elsif next_character = 102 then + (* \f Formfeed. *) + operand^.value := 12 + elsif next_character = 114 then + (* \r Carriage return. *) + operand^.value := 13 + elsif next_character = 118 then + (* \v Vertical tab. *) + operand^.value := 11 + elsif next_character = 34 then + (* \" Double quote. *) + operand^.value := next_character + elsif next_character = 39 then + (* \" Single quote. *) + operand^.value := next_character + elsif next_character = 48 then + (* \0 Null character. *) + operand^.value := 0 + end + else + operand^.value := next_character + end; + operand^.length := 1 end; proc elna_parser_variable_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableExpression; @@ -2351,7 +2426,7 @@ begin (* Add offset to the string block pointer. *) instruction := elna_tac_instruction_create(ElnaTacOperator.add); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); - elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, offset, 0); + 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; @@ -2481,7 +2556,7 @@ begin operand^.kind := ElnaTacKind.constant; operand^.value := info_type^.size; - operand^.length := 0 + operand^.length := 4 end; proc elna_tac_cast_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeCastExpression, @@ -2523,11 +2598,14 @@ begin operator := 0; if token^.kind = ElnaLexerKind.at then - operator := '@' + (* operator := '@' *) + operator := 64 elsif token^.kind = ElnaLexerKind.minus then - operator := '-' + (* operator := '-' *) + operator := 45 elsif token^.kind = ElnaLexerKind.not then - operator := '~' + (* operator := '~' *) + operator := 126 end; if operator <> 0 then elna_lexer_read(cursor) @@ -2560,7 +2638,7 @@ begin elna_list_append(instructions, instruction); instruction := elna_tac_instruction_create(ElnaTacOperator.add); - elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.constant, operand_result^.offset, 0); + elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.constant, operand_result^.offset, 4); elna_tac_instruction_set_operand(instruction, 2, to^.kind, to^.value, to^.length); elna_tac_instruction_set_operand(instruction, 3, to^.kind, to^.value, to^.length); elna_list_append(instructions, instruction) @@ -2592,17 +2670,20 @@ begin end; elna_tac_designator(instructions, unary_operand, symbol_table, @operand_result, @base); - if operator = '@' then + (* if operator = '@' then *) + if operator = 64 then elna_tac_make_variable(operand, symbol_table, word_type); elna_tac_copy_address(instructions, @operand_result, @base, operand) - elsif operator = '-' then + (* elsif operator = '-' then *) + elsif operator = 45 then elna_tac_make_variable(operand, symbol_table, parser_node^.type_decoration); instruction := elna_tac_instruction_create(ElnaTacOperator.negate); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) - elsif operator = '~' then + (* elsif operator = '~' then *) + elsif operator = 126 then elna_tac_make_variable(operand, symbol_table, parser_node^.type_decoration); instruction := elna_tac_instruction_create(ElnaTacOperator.complement); @@ -2621,7 +2702,7 @@ begin instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); - elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, operand_result.offset, 0); + elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, operand_result.offset, 4); elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) else @@ -2711,7 +2792,7 @@ begin elna_tac_make_variable(operand, symbol_table, word_type); elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length); elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length); - elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 0); + elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 4); elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length); return instruction @@ -2920,7 +3001,8 @@ begin label_length := parser_node^.length + 1; label_with_dot := malloc(label_length); - _store_byte('.', label_with_dot); + (* _store_byte('.', label_with_dot); *) + _store_byte(46, label_with_dot); memcpy(label_with_dot + 1, parser_node^.label, parser_node^.length); instruction := elna_tac_instruction_create(ElnaTacOperator.jump); @@ -2987,7 +3069,7 @@ begin (* Found. *) operand^.kind := ElnaTacKind.constant; operand^.value := counter; - operand^.length := 0 + operand^.length := 4 end end; @@ -3054,7 +3136,7 @@ begin load_instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset); elna_tac_instruction_set_operand(load_instruction, 1, intermediate.kind, intermediate.value, intermediate.length); - elna_tac_instruction_set_operand(load_instruction, 2, ElnaTacKind.constant, operand_result.offset, 0); + elna_tac_instruction_set_operand(load_instruction, 2, ElnaTacKind.constant, operand_result.offset, 4); elna_tac_instruction_set_operand(load_instruction, 3, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, load_instruction) end @@ -3128,7 +3210,7 @@ begin instruction := elna_tac_instruction_create(ElnaTacOperator.add); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); - elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, field_offset, 0); + elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, field_offset, 4); 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 @@ -3161,7 +3243,7 @@ begin instruction := elna_tac_instruction_create(ElnaTacOperator.subtract); elna_tac_instruction_set_operand(instruction, 1, inter_operand.kind, inter_operand.value, inter_operand.length); - elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, 1, 0); + elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, 1, 4); elna_tac_instruction_set_operand(instruction, 3, index_operand.kind, index_operand.value, index_operand.length); elna_list_append(instructions, instruction); @@ -3173,7 +3255,7 @@ begin instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, index_operand.kind, index_operand.value, index_operand.length); - elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, element_type^.size, 0); + 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; @@ -3218,8 +3300,7 @@ begin elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length); elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length); - elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, operand_result.offset, 0); - elna_list_append(instructions, instruction) + elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, operand_result.offset, 4) else instruction := elna_tac_instruction_create(ElnaTacOperator.copy); elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, @@ -3491,7 +3572,8 @@ end; proc _write_register(register_character: Word, register_number: Word); begin _write_c(register_character); - _write_c(register_number + '0') + (* _write_c(register_number + '0') *) + _write_c(register_number + 48) end; proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeRecordTypeExpression; @@ -3657,8 +3739,6 @@ var begin result := malloc(#size(ElnaTypeArray)); base := elna_name_type_expression(parser_node^.base); - - (* TODO: Expected to be an integer literal for now. *) length := parser_node^.length; result^.kind := ElnaTypeKind.array; @@ -4047,7 +4127,8 @@ begin return lhs or rhs end; -proc elna_rtl_generate_pseudo(operand: ^ElnaRtlOperand, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlObjectInfo; +proc elna_rtl_generate_pseudo(operand: ^ElnaRtlOperand, variable_map: ^ElnaSymbolTable, + rtl_type: ^ElnaRtlType) -> ^ElnaRtlObjectInfo; var pseudo_symbol: ^ElnaRtlObjectInfo; pseudo_type: ^ElnaRtlTypeWord; @@ -4060,24 +4141,33 @@ begin buffer := malloc(7); sprintf(buffer, "$b%i\0", pseudo_counter); - pseudo_symbol^.allocated := false; - - pseudo_type := malloc(#size(ElnaRtlTypeWord)); - pseudo_type^.kind := ElnaRtlTypeKind.long_word; + pseudo_symbol^.allocated := 0; (* false *) operand^.value := buffer; operand^.length := strlen(buffer); - pseudo_symbol^.rtl_type := pseudo_type; + pseudo_symbol^.rtl_type := rtl_type; elna_symbol_table_enter(variable_map, buffer, operand^.length, pseudo_symbol); return pseudo_symbol end; -proc elna_rtl_symbol_type(variable_type: ^ElnaType); +proc elna_rtl_constant_type(size: Word) -> ^ElnaRtlType; +var + rtl_type: ^ElnaRtlType; +begin + rtl_type := malloc(#size(ElnaRtlTypeWord)); + if size = 1 then + rtl_type^.kind := ElnaRtlTypeKind.byte + else + rtl_type^.kind := ElnaRtlTypeKind.long_word + end; + return rtl_type +end; + +proc elna_rtl_symbol_type(variable_type: ^ElnaType) -> ^ElnaRtlType; var byte_array: ^ElnaRtlTypeByteArray; - long_word: ^ElnaRtlTypeWord; rtl_type: ^ElnaRtlType; begin if elna_type_is_aggregate(variable_type) then @@ -4088,10 +4178,7 @@ begin rtl_type := byte_array else - long_word := malloc(#size(ElnaRtlTypeWord)); - long_word^.kind := ElnaRtlTypeKind.long_word; - - rtl_type := long_word + rtl_type := elna_rtl_constant_type(variable_type^.size) end; return rtl_type end; @@ -4128,7 +4215,7 @@ begin variable_info := current_entry^.symbol_info; pseudo_symbol := malloc(#size(ElnaRtlObjectInfo)); - pseudo_symbol^.allocated := false; + pseudo_symbol^.allocated := 0; (* false *) pseudo_symbol^.kind := ElnaRtlInfoKind.object_info; pseudo_symbol^.rtl_type := elna_rtl_symbol_type(variable_info^.variable_type); @@ -4838,7 +4925,7 @@ end; proc elna_type_character_literal(parser_node: ^ElnaTreeCharacterLiteral); begin - parser_node^.type_decoration := word_type + parser_node^.type_decoration := char_type end; proc elna_type_integer_literal(parser_node: ^ElnaTreeIntegerLiteral); @@ -4852,11 +4939,8 @@ begin end; proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral); -var - symbol_info: ^ElnaSymbolTypeInfo; begin - symbol_info := elna_symbol_table_lookup(symbol_table_global, "Bool", 4); - parser_node^.type_decoration := symbol_info^._type + parser_node^.type_decoration := bool_type end; proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral); @@ -5147,7 +5231,7 @@ begin goto symbol_table_lookup_end end; (* If names don't match, try the next entry. *) - if string_compare(current_entry^.name, current_entry^.length, symbol_name, name_length) = false then + if string_compare(current_entry^.name, current_entry^.length, symbol_name, name_length) = 0 then goto symbol_table_lookup_repeat end; (* Otherwise, the symbol is found. *) @@ -5232,18 +5316,18 @@ begin current_info := type_info_create(current_type); elna_symbol_table_enter(symbol_table_global, "Pointer", 7, current_info); - current_type := malloc(#size(ElnaType)); - current_type^.kind := ElnaTypeKind.primitive; - current_type^.size := 1; - current_type^.alignment := 1; - current_info := type_info_create(current_type); + bool_type := malloc(#size(ElnaType)); + bool_type^.kind := ElnaTypeKind.primitive; + bool_type^.size := 1; + bool_type^.alignment := 1; + current_info := type_info_create(bool_type); elna_symbol_table_enter(symbol_table_global, "Bool", 4, current_info); - current_type := malloc(#size(ElnaType)); - current_type^.kind := ElnaTypeKind.primitive; - current_type^.size := 1; - current_type^.alignment := 1; - current_info := type_info_create(current_type); + char_type := malloc(#size(ElnaType)); + char_type^.kind := ElnaTypeKind.primitive; + char_type^.size := 1; + char_type^.alignment := 1; + current_info := type_info_create(char_type); elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info) end; @@ -5615,14 +5699,14 @@ begin 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); +proc string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word) -> Word; var result: Word; begin if lhs_length = rhs_length then result := memcmp(lhs_pointer, rhs_pointer, lhs_length) = 0 else - result := false + result := 0 (* false *) end; return result end; @@ -5646,7 +5730,8 @@ begin result^.start := position_start; result^.length := position_end - position_start; - if _load_byte(position_start) = '#' then + (* if _load_byte(position_start) = '#' then *) + if _load_byte(position_start) = 35 then result^.kind := ElnaLexerKind.trait elsif string_compare(position_start, result^.length, "const", 5) then result^.kind := ElnaLexerKind._const @@ -5703,17 +5788,23 @@ var begin character := _load_byte(start_position); - if character = ':' then + (* if character = ':' then *) + if character = 58 then result := elna_lexer_token_create(ElnaLexerKind.colon, position) - elsif character = '.' then + (* elsif character = '.' then *) + elsif character = 46 then result := elna_lexer_token_create(ElnaLexerKind.dot, position) - elsif character = '(' then + (* elsif character = '(' then *) + elsif character = 40 then result := elna_lexer_token_create(ElnaLexerKind.left_paren, position) - elsif character = '-' then + (* elsif character = '-' then *) + elsif character = 45 then result := elna_lexer_token_create(ElnaLexerKind.minus, position) - elsif character = '<' then + (* elsif character = '<' then *) + elsif character = 60 then result := elna_lexer_token_create(ElnaLexerKind.less_than, position) - elsif character = '>' then + (* elsif character = '>' then *) + elsif character = 62 then result := elna_lexer_token_create(ElnaLexerKind.greater_than, position) end; return result @@ -5727,37 +5818,53 @@ begin result := malloc(#size(ElnaLexerToken)); character := _load_byte(start_position); - if character = ';' then + (* if character = ';' then *) + if character = 59 then result := elna_lexer_token_create(ElnaLexerKind.semicolon, position) - elsif character = ',' then + (* elsif character = ',' then *) + elsif character = 44 then result := elna_lexer_token_create(ElnaLexerKind.comma, position) - elsif character = ')' then + (* elsif character = ')' then *) + elsif character = 41 then result := elna_lexer_token_create(ElnaLexerKind.right_paren, position) - elsif character = '@' then + (* elsif character = '@' then *) + elsif character = 64 then result := elna_lexer_token_create(ElnaLexerKind.at, position) - elsif character = '~' then + (* elsif character = '~' then *) + elsif character = 126 then result := elna_lexer_token_create(ElnaLexerKind.not, position) - elsif character = '&' then + (* elsif character = '&' then *) + elsif character = 38 then result := elna_lexer_token_create(ElnaLexerKind.and, position) - elsif character = '+' then + (* elsif character = '+' then *) + elsif character = 43 then result := elna_lexer_token_create(ElnaLexerKind.plus, position) - elsif character = '*' then + (* elsif character = '*' then *) + elsif character = 42 then result := elna_lexer_token_create(ElnaLexerKind.multiplication, position) - elsif character = '=' then + (* elsif character = '=' then *) + elsif character = 61 then result := elna_lexer_token_create(ElnaLexerKind.equals, position) - elsif character = '%' then + (* elsif character = '%' then *) + elsif character = 37 then result := elna_lexer_token_create(ElnaLexerKind.remainder, position) - elsif character = '/' then + (* elsif character = '/' then *) + elsif character = 47 then result := elna_lexer_token_create(ElnaLexerKind.division, position) - elsif character = '.' then + (* elsif character = '.' then *) + elsif character = 46 then result := elna_lexer_token_create(ElnaLexerKind.dot, position) - elsif character = '^' then + (* elsif character = '^' then *) + elsif character = 94 then result := elna_lexer_token_create(ElnaLexerKind.hat, position) - elsif character = '[' then + (* elsif character = '[' then *) + elsif character = 91 then result := elna_lexer_token_create(ElnaLexerKind.left_square, position) - elsif character = ']' then + (* elsif character = ']' then *) + elsif character = 93 then result := elna_lexer_token_create(ElnaLexerKind.right_square, position) - elsif character = '|' then + (* elsif character = '|' then *) + elsif character = 124 then result := elna_lexer_token_create(ElnaLexerKind.pipe, position) end; return result @@ -5772,19 +5879,26 @@ begin first_character := _load_byte(start_position); last_character := _load_byte(one_before_last); - if first_character = ':' then + (* if first_character = ':' then *) + if first_character = 58 then result := elna_lexer_token_create(ElnaLexerKind.assignment, position) - elsif first_character = '<' then - if last_character = '=' then + (* elsif first_character = '<' then *) + elsif first_character = 60 then + (* if last_character = '=' then *) + if last_character = 61 then result := elna_lexer_token_create(ElnaLexerKind.less_equal, position) - elsif last_character = '>' then + (* elsif last_character = '>' then *) + elsif last_character = 62 then result := elna_lexer_token_create(ElnaLexerKind.not_equal, position) end - elsif first_character = '>' then - if last_character = '=' then + (* elsif first_character = '>' then *) + elsif first_character = 62 then + (* if last_character = '=' then *) + if last_character = 61 then result := elna_lexer_token_create(ElnaLexerKind.greater_equal, position) end - elsif first_character = '-' then + (* elsif first_character = '-' then *) + elsif first_character = 45 then result := elna_lexer_token_create(ElnaLexerKind.arrow, position) end; return result @@ -5797,11 +5911,14 @@ var begin delimiter := _load_byte(start_position); - if delimiter = '(' then + (* if delimiter = '(' then *) + if delimiter = 40 then result := elna_lexer_token_create(ElnaLexerKind.comment, position) - elsif delimiter = '\'' then + (* elsif delimiter = '\'' then *) + elsif delimiter = 39 then result := elna_lexer_token_create(ElnaLexerKind.character, position) - elsif delimiter = '"' then + (* elsif delimiter = '"' then *) + elsif delimiter = 34 then result := elna_lexer_token_create(ElnaLexerKind.string, position) end; result^.start := start_position; @@ -5877,7 +5994,7 @@ var begin character := _load_byte(start_position); - if character = '\n' then + if character = 10 then location^.line := location^.line + 1; location^.column := 1 else