summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-05-31 01:41:39 +0200
committerEugen Wissner <belka@caraus.de>2026-05-31 08:45:09 +0200
commit9634ad51a2c3afb98362ab9635ba762c4c3f1bbf (patch)
tree065b10a6132c99e6389326fc7859964dac656cec
parent74010389716f0389b873f610365bb43ab26e9948 (diff)
downloadelna-9634ad51a2c3afb98362ab9635ba762c4c3f1bbf.tar.gz
Parse escape sequences in strings
-rw-r--r--boot/stage21/cl.elna41
-rw-r--r--boot/stage22/cl.elna354
-rw-r--r--doc/appendix.tex2
-rw-r--r--doc/language.tex6
4 files changed, 245 insertions, 158 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;
-
- if current_byte <> '\\' then
- compiler_strings_length := compiler_strings_length + 1
- end;
+ current_byte := string^;
+
+ 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,73 +2372,79 @@ begin
operand^.length := 4
end
-proc elna_parser_character_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCharacterLiteral
-var
- result: ^ElnaTreeCharacterLiteral
- token: ^ElnaLexerToken
-begin
- result := malloc(#size(ElnaTreeCharacterLiteral));
- token := elna_lexer_read(cursor);
-
- result^.kind := ElnaTreeKind.character_literal;
- result^.value := token^.start;
- result^.length := token^.length;
- result^.type_decoration := nil;
-
- return result
-end
-
-proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand: ^ElnaTacOperand)
+(* Escape a single character if needed. *)
+proc elna_parser_escape(current_position: ^Char, result: ^Char) -> Word
var
- next_character: Word
- current_position: ^Char
+ parsed_length: Word
+ next_character: Char
begin
- operand^.kind := ElnaTacKind.constant;
- current_position := character_literal_node^.value + 1;
next_character := current_position^;
- (* Escape. *)
if next_character = '\\' then
+ parsed_length := 2;
current_position := current_position + 1;
next_character := current_position^;
if next_character = '\\' then
(* \\ Backslash. *)
- operand^.value := 92
+ result^ := 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
+ result^ := 10
elsif next_character = 't' then
(* \t Tab. *)
- operand^.value := 9
+ result^ := 9
elsif next_character = 'f' then
(* \f Formfeed. *)
- operand^.value := 12
+ result^ := 12
elsif next_character = 'r' then
(* \r Carriage return. *)
- operand^.value := 13
+ result^ := 13
elsif next_character = 'v' then
(* \v Vertical tab. *)
- operand^.value := 11
+ result^ := 11
elsif next_character = '"' then
(* \" Double quote. *)
- operand^.value := 34
+ result^ := 34
elsif next_character = '\'' then
- (* \" Single quote. *)
- operand^.value := 39
+ (* \' Single quote. *)
+ result^ := 39
elsif next_character = '0' then
(* \0 Null character. *)
- operand^.value := 0
+ result^ := 0
end
else
- operand^.value := next_character
+ parsed_length := 1;
+ result^ := next_character
end;
+
+ return parsed_length
+end
+
+proc elna_parser_character_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCharacterLiteral
+var
+ result: ^ElnaTreeCharacterLiteral
+ token: ^ElnaLexerToken
+begin
+ result := malloc(#size(ElnaTreeCharacterLiteral));
+ token := elna_lexer_read(cursor);
+ result^.kind := ElnaTreeKind.character_literal;
+
+ elna_parser_escape(token^.start + 1, @result^.value);
+
+ result^.length := 0;
+ result^.type_decoration := nil;
+
+ return result
+end
+
+proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand: ^ElnaTacOperand)
+var
+ next_character: Word
+ current_position: ^Char
+begin
+ operand^.kind := ElnaTacKind.constant;
+ 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 @@
<hex-character> = `\\x' <hex-digit> \{<hex-digit>\}.
<escaped-character> = `\\' \\
- (`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
+ (`n' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
<printable-character> = \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}
<escaped-character> = `\\' \\
- (`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
+ (`n' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
<hex-character> = `\\x' <hex-digit> \{<hex-digit>\}.
@@ -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 \\