From 9634ad51a2c3afb98362ab9635ba762c4c3f1bbf Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 31 May 2026 01:41:39 +0200 Subject: [PATCH] Parse escape sequences in strings --- boot/stage21/cl.elna | 41 ++++- boot/stage22/cl.elna | 370 +++++++++++++++++++++++++------------------ doc/appendix.tex | 2 +- doc/language.tex | 6 +- 4 files changed, 253 insertions(+), 166 deletions(-) diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna index bd54ecd..1d5e7cc 100644 --- a/boot/stage21/cl.elna +++ b/boot/stage21/cl.elna @@ -9,6 +9,7 @@ program; (* - Allow assigning variables refering to aggregates. *) (* - Cast expressions. *) +(* - Strings are typed as records with a pointer and length. *) type ElnaListNode = record @@ -58,7 +59,7 @@ type kind: ElnaTypeKind; size: Word; alignment: Word; - members: Word; + members: ^ElnaTypeField; length: Word end; ElnaTypePointer = record @@ -692,6 +693,7 @@ var word_type: ^ElnaType; char_type: ^ElnaType; bool_type: ^ElnaType; + string_type: ^ElnaTypeRecord; source_code: Word; compiler_strings_position: Word; @@ -4934,7 +4936,7 @@ end; proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral); begin - parser_node^.type_decoration := word_type + parser_node^.type_decoration := string_type end; proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral); @@ -5291,12 +5293,39 @@ begin symbol_table^.count := symbol_table^.count + 1 end; +proc elna_symbol_string_build(); +var + current_field: ^ElnaTypeField; + char_pointer: ^ElnaTypePointer; +begin + string_type := malloc(#size(ElnaTypeRecord)); + string_type^.kind := ElnaTypeKind._record; + string_type^.size := 8; + string_type^.alignment := 4; + string_type^.members := malloc(2 * #size(ElnaTypeField)); + + char_pointer := malloc(#size(ElnaTypePointer)); + char_pointer^.kind := ElnaTypeKind.pointer; + char_pointer^.size := 4; + char_pointer^.alignment := 4; + char_pointer^.base := char_type; + + current_field := string_type^.members; + current_field^.name := "ptr"; + current_field^.length := 3; + current_field^.field_type := char_pointer; + + current_field := current_field + 1; + current_field^.name := "length"; + current_field^.length := 6; + current_field^.field_type := word_type +end; + (* Build global symbol table with predefined symbols. *) proc elna_symbol_table_build(); var current_info: ^ElnaSymbolTypeInfo; current_type: ^ElnaType; - global_pointer: ^Word; begin symbol_table_global := elna_symbol_table_create(nil); @@ -5327,7 +5356,11 @@ begin 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) + elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info); + + elna_symbol_string_build(); + current_info := type_info_create(string_type); + elna_symbol_table_enter(symbol_table_global, "String", 6, current_info) end; proc elna_lexer_classifications1(); diff --git a/boot/stage22/cl.elna b/boot/stage22/cl.elna index bcf4c23..fbaf2ce 100644 --- a/boot/stage22/cl.elna +++ b/boot/stage22/cl.elna @@ -8,6 +8,8 @@ program; (* Stage 22 compiler. *) (* - Support 2 word procedure arguments. *) +(* - Characters are parsed to a character ASCII code. *) +(* - Strings are parsed and their length doesn't count for escaping backslash. *) type ElnaListNode = record @@ -138,7 +140,7 @@ type ElnaTreeStringLiteral = record kind: ElnaTreeKind; type_decoration: ^ElnaType; - value: Word; + value: ^Char; length: Word end ElnaTreeVariableExpression = record @@ -679,14 +681,9 @@ type var symbol_table_global: ^ElnaSymbolTable variable_map_global: ^ElnaSymbolTable - compiler_strings: [1024]Word + compiler_strings: [4096]Char 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 @@ -705,33 +702,70 @@ var * * Parameters: * string - String token. + * string_length - String length. * - * Returns the offset from the beginning of the storage to the new string in a0. + * Returns the offset from the beginning of the storage to the new string. *) -proc _add_string(string: ^Char) -> Word +proc elna_tac_add_string(string: ^Char, string_length: Word) -> Word var - contents: Word result: Word current_byte: Char - length_to_copy: Word + current_target: ^Char begin - contents := string + 1; result := compiler_strings_length; - length_to_copy := 0; + (* Global character pointer is appearently dereferenced wrongly. *) + current_target := compiler_strings_position; .add_string_loop; - current_byte := contents^; - if current_byte <> '"' then - length_to_copy := length_to_copy + 1; - contents := contents + 1; + current_byte := string^; - if current_byte <> '\\' then - compiler_strings_length := compiler_strings_length + 1 - end; + if current_byte = 92 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := '\\' + elsif current_byte = 10 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := 'n' + elsif current_byte = 9 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := 't' + elsif current_byte = 12 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := 'f' + elsif current_byte = 13 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := 'r' + elsif current_byte = 11 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := 'v' + elsif current_byte = 34 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := '"' + elsif current_byte = 39 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := '\'' + elsif current_byte = 0 then + current_target^ := '\\'; + current_target := current_target + 1; + current_target^ := '0' + else + current_target^ := current_byte + end; + current_target := current_target + 1; + string := string + 1; + string_length := string_length - 1; + compiler_strings_length := compiler_strings_length + 1; + if string_length > 0 then goto add_string_loop end; - memcpy(compiler_strings_position, string + 1, length_to_copy); - compiler_strings_position := compiler_strings_position + length_to_copy; + compiler_strings_position := current_target; return result end @@ -756,7 +790,7 @@ end *) proc _write_i(number: Word) begin - printf("%i\0", number); + printf("%i\0".ptr, number); fflush(nil) end @@ -826,7 +860,7 @@ begin pseudo_counter := pseudo_counter + 1; buffer := malloc(7); - sprintf(buffer, "$a%i\0", pseudo_counter); + sprintf(buffer, "$a%i\0".ptr, pseudo_counter); operand^.kind := ElnaTacKind.variable; operand^.value := buffer; @@ -1385,7 +1419,7 @@ begin elna_list_append(instructions, instruction); instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy".ptr, 6, 0); elna_list_append(instructions, instruction) end @@ -1518,91 +1552,91 @@ var begin if instruction_kind = ElnaRtlOperator.li then argument_count := 2; - _write_s("\tli", 3) + _write_s("\tli".ptr, 3) elsif instruction_kind = ElnaRtlOperator.la then argument_count := 2; - _write_s("\tla", 3) + _write_s("\tla".ptr, 3) elsif instruction_kind = ElnaRtlOperator.add then argument_count := 3; - _write_s("\tadd", 4) + _write_s("\tadd".ptr, 4) elsif instruction_kind = ElnaRtlOperator.addi then argument_count := 3; - _write_s("\taddi", 5) + _write_s("\taddi".ptr, 5) elsif instruction_kind = ElnaRtlOperator.lw then argument_count := 2; if source_type^.kind = ElnaRtlTypeKind.byte then - _write_s("\tlb", 3) + _write_s("\tlb".ptr, 3) else - _write_s("\tlw", 3) + _write_s("\tlw".ptr, 3) end elsif instruction_kind = ElnaRtlOperator.sw then argument_count := 2; if source_type^.kind = ElnaRtlTypeKind.byte then - _write_s("\tsb", 3) + _write_s("\tsb".ptr, 3) else - _write_s("\tsw", 3) + _write_s("\tsw".ptr, 3) end elsif instruction_kind = ElnaRtlOperator.jal then argument_count := 1; - _write_s("\tcall", 5) + _write_s("\tcall".ptr, 5) elsif instruction_kind = ElnaRtlOperator.mv then argument_count := 2; - _write_s("\tmv", 3) + _write_s("\tmv".ptr, 3) elsif instruction_kind = ElnaRtlOperator.sub then argument_count := 3; - _write_s("\tsub", 4) + _write_s("\tsub".ptr, 4) elsif instruction_kind = ElnaRtlOperator.mul then argument_count := 3; - _write_s("\tmul", 4) + _write_s("\tmul".ptr, 4) elsif instruction_kind = ElnaRtlOperator.div then argument_count := 3; - _write_s("\tdiv", 4) + _write_s("\tdiv".ptr, 4) elsif instruction_kind = ElnaRtlOperator.rem then argument_count := 3; - _write_s("\trem", 4) + _write_s("\trem".ptr, 4) elsif instruction_kind = ElnaRtlOperator._xor then argument_count := 3; - _write_s("\txor", 4) + _write_s("\txor".ptr, 4) elsif instruction_kind = ElnaRtlOperator.xori then argument_count := 3; - _write_s("\txori", 5) + _write_s("\txori".ptr, 5) elsif instruction_kind = ElnaRtlOperator._or then argument_count := 3; - _write_s("\tor", 3) + _write_s("\tor".ptr, 3) elsif instruction_kind = ElnaRtlOperator.and then argument_count := 3; - _write_s("\tand", 4) + _write_s("\tand".ptr, 4) elsif instruction_kind = ElnaRtlOperator.seqz then argument_count := 2; - _write_s("\tseqz", 5) + _write_s("\tseqz".ptr, 5) elsif instruction_kind = ElnaRtlOperator.snez then argument_count := 2; - _write_s("\tsnez", 5) + _write_s("\tsnez".ptr, 5) elsif instruction_kind = ElnaRtlOperator.slt then argument_count := 3; - _write_s("\tslt", 4) + _write_s("\tslt".ptr, 4) elsif instruction_kind = ElnaRtlOperator.neg then argument_count := 2; - _write_s("\tneg", 4) + _write_s("\tneg".ptr, 4) elsif instruction_kind = ElnaRtlOperator.not then argument_count := 2; - _write_s("\tnot", 4) + _write_s("\tnot".ptr, 4) elsif instruction_kind = ElnaRtlOperator.j then argument_count := 1; - _write_s("\tj", 2) + _write_s("\tj".ptr, 2) elsif instruction_kind = ElnaRtlOperator.beqz then argument_count := 2; - _write_s("\tbeqz", 5) + _write_s("\tbeqz".ptr, 5) elsif instruction_kind = ElnaRtlOperator.bnez then argument_count := 2; - _write_s("\tbnez", 5) + _write_s("\tbnez".ptr, 5) end; return argument_count end proc elna_riscv_register(register: Word) begin - printf("x%i\0", register - 1); + printf("x%i\0".ptr, register - 1); fflush(nil) end @@ -2010,24 +2044,24 @@ begin operand_value := instruction^.operands[1].value; (* Write the prologue. *) - printf("\taddi sp, sp, -%i\n\tsw ra, %i(sp)\n\tsw s0, %i(sp)\n\taddi s0, sp, %i\n\0", + printf("\taddi sp, sp, -%i\n\tsw ra, %i(sp)\n\tsw s0, %i(sp)\n\taddi s0, sp, %i\n\0".ptr, operand_value, operand_value - 4, operand_value - 8, operand_value); fflush(nil) elsif instruction^.operator = ElnaRtlOperator.ret then operand_value := instruction^.operands[1].value; (* Write the epilogue. *) - 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); + printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0".ptr, operand_value - 4, operand_value - 8, operand_value); fflush(nil) elsif instruction^.operator = ElnaRtlOperator.nop then operand_value := instruction^.operands[1].kind; if operand_value = ElnaTacKind.constant then - printf("\n# copy %i (%i %i) (%i %.*s)\n\0", instruction^.operands[3].kind, + printf("\n# copy %i (%i %i) (%i %.*s)\n\0".ptr, 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 %.*s) (%i %.*s)\n\0", + printf("\n# copy (%i %.*s) (%i %.*s)\n\0".ptr, 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; @@ -2117,13 +2151,13 @@ begin .elna_riscv_procedure_loop; (* Write .type _procedure_name, @function. *) - printf(".type %.*s, @function\n\0", procedure^.length, procedure^.name); + printf(".type %.*s, @function\n\0".ptr, procedure^.length, procedure^.name); (* Write procedure label, _procedure_name: *) - printf("%.*s:\n\0", procedure^.length, procedure^.name); + printf("%.*s:\n\0".ptr, procedure^.length, procedure^.name); elna_riscv_instructions(procedure^.body.first); - printf("\tret\n\0"); + printf("\tret\n\0".ptr); fflush(nil); procedure := procedure^.next; @@ -2136,9 +2170,9 @@ proc elna_riscv_variable(variable: ^ElnaRtlStaticVariable) begin .elna_riscv_variable_loop; if variable <> 0 then - printf(".type %.*s, @object\n\0", variable^.length, variable^.name); + printf(".type %.*s, @object\n\0".ptr, variable^.length, variable^.name); - printf("%.*s: .zero %i\n\0", variable^.length, variable^.name, variable^.body); + printf("%.*s: .zero %i\n\0".ptr, variable^.length, variable^.name, variable^.body); variable := variable^.next; goto elna_riscv_variable_loop @@ -2241,16 +2275,16 @@ var compiler_strings_end: ^Char current_byte: Char begin - printf(".globl main\n\n\0"); - printf(".section .data\n\0"); + printf(".globl main\n\n\0".ptr); + printf(".section .data\n\0".ptr); elna_riscv_variable(pair^.data); - printf(".section .text\n\n\0"); + printf(".section .text\n\n\0".ptr); elna_riscv_procedure(pair^.code); - printf(".section .rodata\n.type strings, @object\nstrings: .ascii \0"); + printf(".section .rodata\n.type strings, @object\nstrings: .ascii \0".ptr); fflush(nil); _write_c('"'); @@ -2296,7 +2330,7 @@ begin result := malloc(#size(ElnaTreeBooleanLiteral)); result^.kind := ElnaTreeKind.boolean_literal; - result^.value := string_compare(cursor^.start, 4, "true", 4); + result^.value := string_compare(cursor^.start, 4, "true".ptr, 4); result^.type_decoration := nil; elna_lexer_read(cursor); @@ -2338,6 +2372,55 @@ begin operand^.length := 4 end +(* Escape a single character if needed. *) +proc elna_parser_escape(current_position: ^Char, result: ^Char) -> Word +var + parsed_length: Word + next_character: Char +begin + next_character := current_position^; + + if next_character = '\\' then + parsed_length := 2; + current_position := current_position + 1; + next_character := current_position^; + + if next_character = '\\' then + (* \\ Backslash. *) + result^ := 92 + elsif next_character = 'n' then + (* \n Newline. *) + result^ := 10 + elsif next_character = 't' then + (* \t Tab. *) + result^ := 9 + elsif next_character = 'f' then + (* \f Formfeed. *) + result^ := 12 + elsif next_character = 'r' then + (* \r Carriage return. *) + result^ := 13 + elsif next_character = 'v' then + (* \v Vertical tab. *) + result^ := 11 + elsif next_character = '"' then + (* \" Double quote. *) + result^ := 34 + elsif next_character = '\'' then + (* \' Single quote. *) + result^ := 39 + elsif next_character = '0' then + (* \0 Null character. *) + result^ := 0 + end + else + parsed_length := 1; + result^ := next_character + end; + + return parsed_length +end + proc elna_parser_character_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCharacterLiteral var result: ^ElnaTreeCharacterLiteral @@ -2345,10 +2428,11 @@ var begin result := malloc(#size(ElnaTreeCharacterLiteral)); token := elna_lexer_read(cursor); - result^.kind := ElnaTreeKind.character_literal; - result^.value := token^.start; - result^.length := token^.length; + + elna_parser_escape(token^.start + 1, @result^.value); + + result^.length := 0; result^.type_decoration := nil; return result @@ -2360,51 +2444,7 @@ var current_position: ^Char begin operand^.kind := ElnaTacKind.constant; - current_position := character_literal_node^.value + 1; - next_character := current_position^; - - (* Escape. *) - if next_character = '\\' then - current_position := current_position + 1; - next_character := current_position^; - - if next_character = '\\' then - (* \\ Backslash. *) - operand^.value := 92 - elsif next_character = 'n' then - (* \n Newline. *) - operand^.value := 10 - elsif next_character = 'a' then - (* \a Bell. *) - operand^.value := 7 - elsif next_character = 'b' then - (* \b Backspace. *) - operand^.value := 8 - elsif next_character = 't' then - (* \t Tab. *) - operand^.value := 9 - elsif next_character = 'f' then - (* \f Formfeed. *) - operand^.value := 12 - elsif next_character = 'r' then - (* \r Carriage return. *) - operand^.value := 13 - elsif next_character = 'v' then - (* \v Vertical tab. *) - operand^.value := 11 - elsif next_character = '"' then - (* \" Double quote. *) - operand^.value := 34 - elsif next_character = '\'' then - (* \" Single quote. *) - operand^.value := 39 - elsif next_character = '0' then - (* \0 Null character. *) - operand^.value := 0 - end - else - operand^.value := next_character - end; + operand^.value := character_literal_node^.value; operand^.length := 1 end @@ -2435,13 +2475,31 @@ proc elna_parser_string_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStringLite var result: ^ElnaTreeStringLiteral token: ^ElnaLexerToken + current_position: ^Char + parsed_length: Word + parsed_total: Word + target_position: ^Char begin result := malloc(#size(ElnaTreeStringLiteral)); token := elna_lexer_read(cursor); + target_position := malloc(token^.length - 2); + current_position := token^.start + 1; + parsed_total := 2; result^.kind := ElnaTreeKind.string_literal; - result^.value := token^.start; - result^.length := token^.length; + result^.value := target_position; + result^.length := 0; + + .elna_parser_escape_loop; + parsed_length := elna_parser_escape(current_position, target_position); + current_position := current_position + parsed_length; + parsed_total := parsed_total + parsed_length; + target_position := target_position + 1; + + if parsed_total < token^.length then + goto elna_parser_escape_loop + end; + result^.length := target_position - result^.value; result^.type_decoration := nil; return result @@ -2453,12 +2511,12 @@ var offset: Word instruction: ^ElnaTacInstruction begin - offset := _add_string(string_literal_node^.value); + offset := elna_tac_add_string(string_literal_node^.value, string_literal_node^.length); elna_tac_make_variable(operand, symbol_table, word_type); instruction := elna_tac_instruction_create(ElnaTacOperator.get_address); - elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.variable, "strings", 7); + elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.variable, "strings".ptr, 7); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction); @@ -3385,9 +3443,9 @@ var first_byte: Word begin if length = 0 then - printf(".L%i\0", counter) + printf(".L%i\0".ptr, counter) else - printf(".%.*s\0", length, counter); + printf(".%.*s\0".ptr, length, counter); end; fflush(nil) end @@ -4207,7 +4265,7 @@ begin pseudo_symbol^.kind := ElnaRtlInfoKind.object_info; buffer := malloc(7); - sprintf(buffer, "$b%i\0", pseudo_counter); + sprintf(buffer, "$b%i\0".ptr, pseudo_counter); pseudo_symbol^.allocated := false; operand^.value := buffer; @@ -4683,10 +4741,10 @@ begin elna_list_initialize(@result^.body); - result^.name := "main"; + result^.name := "main".ptr; result^.length := 4; - symbol_info := elna_symbol_table_lookup(symbol_table_global, "main", 4); + symbol_info := elna_symbol_table_lookup(symbol_table_global, result^.name, result^.length); result^.symbol_table := symbol_info^.symbol_table; @@ -4896,7 +4954,7 @@ 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) + elna_symbol_table_enter(symbol_table_global, "main".ptr, 4, symbol_info) end proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable) @@ -4993,7 +5051,7 @@ end proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral) begin - parser_node^.type_decoration := word_type + parser_node^.type_decoration := string_type end proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral) @@ -5005,7 +5063,7 @@ proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral) var symbol_info: ^ElnaSymbolTypeInfo begin - symbol_info := elna_symbol_table_lookup(symbol_table_global, "Pointer", 7); + symbol_info := elna_symbol_table_lookup(symbol_table_global, "Pointer".ptr, 7); parser_node^.type_decoration := symbol_info^._type end @@ -5368,14 +5426,14 @@ begin char_pointer^.base := char_type; current_field := string_type^.members; - current_field^.name := "ptr"; + current_field^.name := "ptr".ptr; current_field^.length := 3; current_field^.field_type := char_pointer; current_field := current_field + 1; - current_field^.name := "length"; + current_field^.name := "length".ptr; current_field^.length := 6; - current_field^.field_type := word_type; + current_field^.field_type := word_type end (* Build global symbol table with predefined symbols. *) @@ -5391,32 +5449,32 @@ begin word_type^.size := 4; word_type^.alignment := 4; current_info := type_info_create(word_type); - elna_symbol_table_enter(symbol_table_global, "Word", 4, current_info); + elna_symbol_table_enter(symbol_table_global, "Word".ptr, 4, current_info); current_type := malloc(#size(ElnaType)); current_type^.kind := ElnaTypeKind.primitive; current_type^.size := 4; current_type^.alignment := 4; current_info := type_info_create(current_type); - elna_symbol_table_enter(symbol_table_global, "Pointer", 7, current_info); + elna_symbol_table_enter(symbol_table_global, "Pointer".ptr, 7, current_info); 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); + elna_symbol_table_enter(symbol_table_global, "Bool".ptr, 4, current_info); 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); + elna_symbol_table_enter(symbol_table_global, "Char".ptr, 4, current_info); elna_symbol_string_build(); current_info := type_info_create(string_type); - elna_symbol_table_enter(symbol_table_global, "String", 6, current_info) + elna_symbol_table_enter(symbol_table_global, "String".ptr, 6, current_info) end proc elna_lexer_classifications1() @@ -5820,49 +5878,49 @@ begin if position_start^ = '#' then result^.kind := ElnaLexerKind.trait - elsif string_compare(position_start, result^.length, "const", 5) then + elsif string_compare(position_start, result^.length, "const".ptr, 5) then result^.kind := ElnaLexerKind._const - elsif string_compare(position_start, result^.length, "var", 3) then + elsif string_compare(position_start, result^.length, "var".ptr, 3) then result^.kind := ElnaLexerKind._var - elsif string_compare(position_start, result^.length, "proc", 4) then + elsif string_compare(position_start, result^.length, "proc".ptr, 4) then result^.kind := ElnaLexerKind._proc - elsif string_compare(position_start, result^.length, "type", 4) then + elsif string_compare(position_start, result^.length, "type".ptr, 4) then result^.kind := ElnaLexerKind._type - elsif string_compare(position_start, result^.length, "begin", 5) then + elsif string_compare(position_start, result^.length, "begin".ptr, 5) then result^.kind := ElnaLexerKind._begin - elsif string_compare(position_start, result^.length, "end", 3) then + elsif string_compare(position_start, result^.length, "end".ptr, 3) then result^.kind := ElnaLexerKind._end - elsif string_compare(position_start, result^.length, "return", 6) then + elsif string_compare(position_start, result^.length, "return".ptr, 6) then result^.kind := ElnaLexerKind._return - elsif string_compare(position_start, result^.length, "goto", 4) then + elsif string_compare(position_start, result^.length, "goto".ptr, 4) then result^.kind := ElnaLexerKind._goto - elsif string_compare(position_start, result^.length, "if", 2) then + elsif string_compare(position_start, result^.length, "if".ptr, 2) then result^.kind := ElnaLexerKind._if - elsif string_compare(position_start, result^.length, "while", 5) then + elsif string_compare(position_start, result^.length, "while".ptr, 5) then result^.kind := ElnaLexerKind._while - elsif string_compare(position_start, result^.length, "then", 4) then + elsif string_compare(position_start, result^.length, "then".ptr, 4) then result^.kind := ElnaLexerKind._then - elsif string_compare(position_start, result^.length, "else", 4) then + elsif string_compare(position_start, result^.length, "else".ptr, 4) then result^.kind := ElnaLexerKind._else - elsif string_compare(position_start, result^.length, "elsif", 5) then + elsif string_compare(position_start, result^.length, "elsif".ptr, 5) then result^.kind := ElnaLexerKind._elsif - elsif string_compare(position_start, result^.length, "record", 6) then + elsif string_compare(position_start, result^.length, "record".ptr, 6) then result^.kind := ElnaLexerKind._record - elsif string_compare(position_start, result^.length, "or", 2) then + elsif string_compare(position_start, result^.length, "or".ptr, 2) then result^.kind := ElnaLexerKind._or - elsif string_compare(position_start, result^.length, "xor", 3) then + elsif string_compare(position_start, result^.length, "xor".ptr, 3) then result^.kind := ElnaLexerKind._xor - elsif string_compare(position_start, result^.length, "program", 7) then + elsif string_compare(position_start, result^.length, "program".ptr, 7) then result^.kind := ElnaLexerKind._program - elsif string_compare(position_start, result^.length, "module", 6) then + elsif string_compare(position_start, result^.length, "module".ptr, 6) then result^.kind := ElnaLexerKind._module - elsif string_compare(position_start, result^.length, "nil", 3) then + elsif string_compare(position_start, result^.length, "nil".ptr, 3) then result^.kind := ElnaLexerKind.null - elsif string_compare(position_start, result^.length, "true", 4) then + elsif string_compare(position_start, result^.length, "true".ptr, 4) then result^.kind := ElnaLexerKind.boolean - elsif string_compare(position_start, result^.length, "false", 5) then + elsif string_compare(position_start, result^.length, "false".ptr, 5) then result^.kind := ElnaLexerKind.boolean - elsif string_compare(position_start, result^.length, "cast", 4) then + elsif string_compare(position_start, result^.length, "cast".ptr, 4) then result^.kind := ElnaLexerKind._cast end; return result diff --git a/doc/appendix.tex b/doc/appendix.tex index f68eaa2..09bdbde 100644 --- a/doc/appendix.tex +++ b/doc/appendix.tex @@ -17,7 +17,7 @@ = `\\x' \{\}. = `\\' \\ - (`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0'). + (`n' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0'). = \enspace? a printable ASCII character\space?. diff --git a/doc/language.tex b/doc/language.tex index cce2fcb..36ee877 100644 --- a/doc/language.tex +++ b/doc/language.tex @@ -84,7 +84,7 @@ called the \textit{the length} of the string. \begin{grammar} = `\\' \\ - (`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0'). + (`n' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0'). = `\\x' \{\}. @@ -106,10 +106,6 @@ beginning with a backslash (\textbackslash). \toprule \verb|\n| & Newline \\ \midrule - \verb|\a| & Bell \\ - \midrule - \verb|\b| & Backspace \\ - \midrule \verb|\t| & Horizontal tab \\ \midrule \verb|\f| & Form feed \\