summaryrefslogtreecommitdiff
path: root/boot/stage17/cl.elna
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-01-01 21:52:14 +0100
committerEugen Wissner <belka@caraus.de>2026-01-01 21:52:14 +0100
commit58e708f44c23144622a9a5546b07d5c01d18db56 (patch)
tree90373eadd62e8b9f8a127ab22427069e87296106 /boot/stage17/cl.elna
parent3db3a0f20e37ba4a9973f9fe9fb9a61df25391f8 (diff)
downloadelna-58e708f44c23144622a9a5546b07d5c01d18db56.tar.gz
Implement type size trait
Diffstat (limited to 'boot/stage17/cl.elna')
-rw-r--r--boot/stage17/cl.elna365
1 files changed, 223 insertions, 142 deletions
diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna
index ac4ceaa..6ca9ff0 100644
--- a/boot/stage17/cl.elna
+++ b/boot/stage17/cl.elna
@@ -9,6 +9,7 @@ program;
(* - true and false boolean literals. *)
(* - the number of local variables is not limited. *)
+(* - #size(T). *)
type
(**
@@ -30,6 +31,34 @@ type
parameters: Word;
count: Word
end;
+ ElnaTreeKind = (
+ integer_literal,
+ string_literal,
+ character_literal,
+ boolean_literal,
+ variable_expression,
+ field_access_expression,
+ dereference_expression,
+ unary_expression,
+ binary_expression,
+ call,
+ goto_statement,
+ label_declaration,
+ return_statement,
+ assign_statement,
+ if_statement,
+ procedure_declaration,
+ variable_declaration,
+ enumeration_type_expression,
+ named_type_expression,
+ type_declaration,
+ module_declaration,
+ record_type_expression,
+ pointer_type_expression,
+ array_type_expression,
+ null,
+ trait_expression
+ );
ElnaTreeNode = record
kind: Word
end;
@@ -157,6 +186,12 @@ type
base: Word;
length: Word
end;
+ ElnaTreeTraitExpression = record
+ kind: Word;
+ name: Word;
+ length: Word;
+ argument: Word
+ end;
(**
* Conditional statements is a list of pairs: condition and statements.
* Used for example to represent if and elsif blocks with beloning statements.
@@ -292,7 +327,8 @@ type
double_quote,
greater,
less,
- other
+ other,
+ number_sign
);
ElnaLexerState = (
start,
@@ -311,6 +347,8 @@ type
character_escape,
string,
string_escape,
+ number_sign,
+ trait,
finish
);
ElnaLexerKind = (
@@ -378,33 +416,7 @@ type
_goto,
eof
);
- ElnaTreeKind = (
- integer_literal,
- string_literal,
- character_literal,
- boolean_literal,
- variable_expression,
- field_access_expression,
- dereference_expression,
- unary_expression,
- binary_expression,
- call,
- goto_statement,
- label_declaration,
- return_statement,
- assign_statement,
- if_statement,
- procedure_declaration,
- variable_declaration,
- enumeration_type_expression,
- named_type_expression,
- type_declaration,
- module_declaration,
- record_type_expression,
- pointer_type_expression,
- array_type_expression,
- null
- );
+
ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
ElnaTypeKind = (primitive, enumeration, _record, pointer, array);
ElnaTacOperator = (
@@ -1048,6 +1060,63 @@ begin
return first_instruction
end;
+proc elna_rtl_store(tac_instruction: Word, next_instruction: ^^ElnaInstructionList);
+var
+ result: ^ElnaInstructionList;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
+ operands: ^ElnaInstructionList;
+begin
+ operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
+ next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
+ result := operands;
+ operands := result^.next;
+
+ elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
+
+ operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
+ if operand_type = ElnaTacOperand.pseudo then
+ elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
+ end;
+ if operands = 0 then
+ result^.next := next_instruction^
+ else
+ operands^.next := next_instruction^
+ end;
+ return result
+end;
+
+proc elna_rtl_load(tac_instruction: Word, next_instruction: ^^ElnaInstructionList);
+var
+ result: ^ElnaInstructionList;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
+ operands: ^ElnaInstructionList;
+begin
+ operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
+ next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.lw);
+ result := operands;
+ operands := result^.next;
+
+ elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.t0, 0);
+
+ operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
+ elna_rtl_instruction_set_operand(next_instruction^, 1, operand_type, operand_value, operand_length);
+
+ if operands = 0 then
+ result^.next := next_instruction^
+ else
+ operands^.next := next_instruction^
+ end;
+ return result
+end;
+
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: ^^ElnaInstructionList);
var
result: ^ElnaInstructionList;
@@ -1063,53 +1132,16 @@ begin
next_instruction^ := nil;
if instruction_kind = ElnaTacOperator.get_address then
- operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
- operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
- operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
-
- if operand_type = ElnaTacOperand.symbol then
- result := elna_rtl_instruction_create(ElnaRtlOperator.la);
-
- elna_rtl_copy_operand(tac_instruction, 1, result);
- elna_rtl_copy_operand(tac_instruction, 2, result)
- elsif operand_type = ElnaTacOperand.pseudo then
- result := elna_rtl_instruction_create(ElnaRtlOperator.la);
+ result := elna_rtl_instruction_create(ElnaRtlOperator.la);
- elna_rtl_copy_operand(tac_instruction, 1, result);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
- end
+ elna_rtl_copy_operand(tac_instruction, 1, result);
+ elna_rtl_copy_operand(tac_instruction, 2, result)
elsif instruction_kind = ElnaTacOperator.add then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add)
elsif instruction_kind = ElnaTacOperator.load then
- operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
-
- if operand_type = ElnaTacOperand.pseudo then
- operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
- operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
-
- result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
- elna_rtl_copy_operand(tac_instruction, 1, result);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
- end
+ result := elna_rtl_load(tac_instruction, next_instruction)
elsif instruction_kind = ElnaTacOperator.store then
- operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
- next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
- result := operands;
- operands := result^.next;
-
- elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
-
- operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
- operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
- operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
- if operand_type = ElnaTacOperand.pseudo then
- elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
- end;
- if operands = 0 then
- result^.next := next_instruction^
- else
- operands^.next := next_instruction^
- end
+ result := elna_rtl_store(tac_instruction, next_instruction)
elsif instruction_kind = ElnaTacOperator.proc_call then
result := elna_rtl_call(tac_instruction, next_instruction)
elsif instruction_kind = ElnaTacOperator.subtract then
@@ -1438,7 +1470,7 @@ begin
end
end;
-proc elna_alloc_load_store(instruction: ^ElnaInstructionList);
+proc elna_alloc_store(instruction: ^ElnaInstructionList);
var
old_instruction: ^ElnaInstructionList;
operand_type: Word;
@@ -1446,9 +1478,9 @@ var
operand_length: Word;
pseudo_symbol: Word;
begin
- operand_type := elna_rtl_instruction_get_operand_type(instruction, 1);
- operand_value := elna_rtl_instruction_get_operand_value(instruction, 1);
- operand_length := elna_rtl_instruction_get_operand_length(instruction, 1);
+ operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
+ operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
if operand_type = ElnaRtlOperand.pseudo then
old_instruction := malloc(elna_rtl_instruction_size());
@@ -1461,31 +1493,35 @@ begin
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
instruction^.next := old_instruction;
- elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t1, 0);
-
- goto elna_alloc_load_store_end
- end;
+ elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.t1, 0)
+ end
+end;
- operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
- operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
- operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
+proc elna_alloc_load(instruction: ^ElnaInstructionList);
+var
+ old_instruction: ^ElnaInstructionList;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
+ pseudo_symbol: Word;
+begin
+ operand_type := elna_rtl_instruction_get_operand_type(instruction, 1);
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 1);
+ operand_length := elna_rtl_instruction_get_operand_length(instruction, 1);
if operand_type = ElnaRtlOperand.pseudo then
old_instruction := malloc(elna_rtl_instruction_size());
memcpy(old_instruction, instruction, elna_rtl_instruction_size());
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
- elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
+ elna_rtl_instruction_set_kind(old_instruction, ElnaRtlOperator.sw);
- elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t1, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
+ elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t1, 0);
+ elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
instruction^.next := old_instruction;
- elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.t1, 0);
-
- goto elna_alloc_load_store_end
- end;
- .elna_alloc_load_store_end
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t1, 0)
+ end
end;
proc elna_alloc_instruction(instruction: ^ElnaInstructionList);
@@ -1532,9 +1568,9 @@ begin
elsif instruction_kind = ElnaRtlOperator.la then
elna_alloc_load_address(instruction)
elsif instruction_kind = ElnaRtlOperator.lw then
- elna_alloc_load_store(instruction)
+ elna_alloc_load(instruction)
elsif instruction_kind = ElnaRtlOperator.sw then
- elna_alloc_load_store(instruction)
+ elna_alloc_store(instruction)
elsif instruction_kind = ElnaRtlOperator._or then
elna_alloc_operation_target(instruction)
elsif instruction_kind = ElnaRtlOperator.and then
@@ -1991,6 +2027,32 @@ begin
return elna_instruction_list_concatenate(first_instruction, next_instruction)
end;
+proc elna_parser_trait_expression();
+var
+ result: ^ElnaTreeTraitExpression;
+ token_kind: Word;
+begin
+ printf("# Comment\n\0");
+ fflush(nil);
+
+ result := malloc(ElnaTreeTraitExpression_size());
+ result^.kind := ElnaTreeKind.trait_expression;
+
+ result^.name := _elna_lexer_global_get_start();
+ result^.length := _elna_lexer_global_get_end() - result^.name;
+
+ _elna_lexer_skip_token();
+ _elna_lexer_read_token(@token_kind);
+ _elna_lexer_skip_token();
+
+ result^.argument := elna_parser_type_expression();
+
+ _elna_lexer_read_token(@token_kind);
+ _elna_lexer_skip_token();
+
+ return result
+end;
+
proc elna_parser_simple_expression();
var
current_character: Word;
@@ -2010,6 +2072,8 @@ begin
parser_node := elna_parser_boolean_literal()
elsif token_kind = ElnaLexerKind.null then
parser_node := elna_parser_nil_literal()
+ elsif token_kind = ElnaLexerKind.trait then
+ parser_node := elna_parser_trait_expression()
elsif token_kind = ElnaLexerKind.identifier then
parser_node := elna_parser_variable_expression()
end;
@@ -2033,26 +2097,43 @@ end;
proc elna_parser_designator();
var
simple_expression: Word;
- token_kind1: Word;
+ token_kind: Word;
begin
simple_expression := elna_parser_simple_expression();
.elna_parser_designator_loop;
- _elna_lexer_read_token(@token_kind1);
+ _elna_lexer_read_token(@token_kind);
- if token_kind1 = ElnaLexerKind.hat then
+ if token_kind = ElnaLexerKind.hat then
simple_expression := elna_parser_dereference_expression(simple_expression);
goto elna_parser_designator_loop
- elsif token_kind1 = ElnaLexerKind.dot then
+ elsif token_kind = ElnaLexerKind.dot then
simple_expression := elna_parser_field_access_expression(simple_expression);
goto elna_parser_designator_loop
- elsif token_kind1 = ElnaLexerKind.left_paren then
+ elsif token_kind = ElnaLexerKind.left_paren then
simple_expression := elna_parser_call(simple_expression);
goto elna_parser_designator_loop
end;
return simple_expression
end;
+proc elna_tac_trait_expression(trait_node: ^ElnaTreeTraitExpression, operand_type: Word, operand_value: Word, operand_length: Word);
+var
+ symbol: ^ElnaSymbolTypeInfo;
+ info_type: ^ElnaType;
+ parser_node: ^ElnaTreeNamedTypeExpression;
+begin
+ parser_node := trait_node^.argument;
+ symbol := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
+ info_type := symbol^._type;
+
+ operand_type^ := ElnaTacOperand.immediate;
+ operand_value^ := info_type^.size;
+ operand_length^ := 0;
+
+ return nil
+end;
+
proc elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
instruction: Word;
@@ -2067,6 +2148,8 @@ begin
instruction := elna_tac_boolean_literal(parser_node, operand_type, operand_value, operand_length)
elsif parser_node^.kind = ElnaTreeKind.null then
instruction := elna_tac_nil_literal(parser_node, operand_type, operand_value, operand_length)
+ elsif parser_node^.kind = ElnaTreeKind.trait_expression then
+ instruction := elna_tac_trait_expression(parser_node, operand_type, operand_value, operand_length)
else
instruction := elna_tac_variable_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
end;
@@ -2112,7 +2195,7 @@ proc elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_tab
var
token_kind: Word;
operator: Word;
- operand: Word;
+ operand: ^ElnaTreeExpression;
is_address: Word;
first_instruction: Word;
instruction: Word;
@@ -2152,23 +2235,13 @@ begin
operand_value^ := "$unary";
operand_length^ := 6
elsif is_address then
- if operand_type^ = ElnaTacOperand.pseudo then
- instruction := _elna_tac_instruction_create(ElnaTacOperator.load);
- _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
- _elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
-
- operand_type^ := ElnaTacOperand.temporary;
- operand_value^ := 6;
- operand_length^ := 0
- else
- instruction := _elna_tac_instruction_create(ElnaTacOperator.load);
- _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
- _elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.load);
+ _elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$unary", 6);
- operand_type^ := ElnaTacOperand.pseudo;
- operand_value^ := "$unary";
- operand_length^ := 6
- end
+ operand_type^ := ElnaTacOperand.pseudo;
+ operand_value^ := "$unary";
+ operand_length^ := 6
else
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
@@ -2490,21 +2563,21 @@ end;
proc elna_parser_goto_statement();
var
- token_kind1: Word;
- result1: ^ElnaTreeGotoStatement;
+ token_kind: Word;
+ result: ^ElnaTreeGotoStatement;
begin
_elna_lexer_skip_token();
- _elna_lexer_read_token(@token_kind1);
+ _elna_lexer_read_token(@token_kind);
- result1 := malloc(ElnaTreeGotoStatement_size());
- result1^.kind := ElnaTreeKind.goto_statement;
- result1^.next := nil;
- result1^.label := _elna_lexer_global_get_start();
- result1^.length := _elna_lexer_global_get_end() - result1^.label;
+ result := malloc(ElnaTreeGotoStatement_size());
+ result^.kind := ElnaTreeKind.goto_statement;
+ result^.next := nil;
+ result^.label := _elna_lexer_global_get_start();
+ result^.length := _elna_lexer_global_get_end() - result^.label;
_elna_lexer_skip_token();
- return result1
+ return result
end;
proc elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement);
@@ -2632,17 +2705,7 @@ begin
if parser_node^.kind = ElnaTreeKind.dereference_expression then
dereference_expression := parser_node;
first_instruction := elna_tac_designator(dereference_expression^.pointer, symbol_table, is_address, operand_type, operand_value, operand_length);
-
- last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
- _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
- _elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^);
-
- operand_type^ := ElnaTacOperand.pseudo;
- operand_value^ := "$unary";
- operand_length^ := 6;
-
- is_address^ := 1;
- first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction);
+ is_address^ := 1
elsif parser_node^.kind = ElnaTreeKind.field_access_expression then
field_access_expression := parser_node;
expression_type := field_access_expression^.type_decoration;
@@ -4824,7 +4887,7 @@ begin
_assign_at(@classification, 33, ElnaLexerClass.space);
_assign_at(@classification, 34, ElnaLexerClass.single);
_assign_at(@classification, 35, ElnaLexerClass.double_quote);
- _assign_at(@classification, 36, ElnaLexerClass.other);
+ _assign_at(@classification, 36, ElnaLexerClass.number_sign);
_assign_at(@classification, 37, ElnaLexerClass.other);
_assign_at(@classification, 38, ElnaLexerClass.single);
_assign_at(@classification, 39, ElnaLexerClass.single);
@@ -4938,9 +5001,9 @@ var
target: Word;
begin
(* Each state is 8 bytes long (2 words: action and next state).
- There are 22 character classes, so a transition row 8 * 22 = 176 bytes long. *)
+ There are 23 character classes, so a transition row 8 * 23 = 184 bytes long. *)
row_position := current_state - 1;
- row_position := row_position * 176;
+ row_position := row_position * 184;
column_position := character_class - 1;
column_position := column_position * 8;
@@ -4999,7 +5062,8 @@ begin
_elna_lexer_set_transition(current_state, ElnaLexerClass.double_quote, default_action, next_state);
_elna_lexer_set_transition(current_state, ElnaLexerClass.greater, default_action, next_state);
_elna_lexer_set_transition(current_state, ElnaLexerClass.less, default_action, next_state);
- _elna_lexer_set_transition(current_state, ElnaLexerClass.other, default_action, next_state)
+ _elna_lexer_set_transition(current_state, ElnaLexerClass.other, default_action, next_state);
+ _elna_lexer_set_transition(current_state, ElnaLexerClass.number_sign, default_action, next_state)
end;
(**
@@ -5035,6 +5099,7 @@ begin
_elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.greater, ElnaLexerAction.accumulate, ElnaLexerState.greater);
_elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.less, ElnaLexerAction.accumulate, ElnaLexerState.less);
_elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.other, ElnaLexerAction.none, ElnaLexerState.finish);
+ _elna_lexer_set_transition(ElnaLexerState.start, ElnaLexerClass.number_sign, ElnaLexerAction.accumulate, ElnaLexerState.number_sign);
(* Colon state. *)
_elna_lexer_default_transition(ElnaLexerState.colon, ElnaLexerAction.finalize, ElnaLexerState.finish);
@@ -5119,7 +5184,21 @@ begin
(* Escape sequence in a string. *)
_elna_lexer_default_transition(ElnaLexerState.string_escape, ElnaLexerAction.accumulate, ElnaLexerState.string);
_elna_lexer_set_transition(ElnaLexerState.string_escape, ElnaLexerClass.invalid, ElnaLexerAction.none, ElnaLexerState.finish);
- _elna_lexer_set_transition(ElnaLexerState.string_escape, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish)
+ _elna_lexer_set_transition(ElnaLexerState.string_escape, ElnaLexerClass.eof, ElnaLexerAction.none, ElnaLexerState.finish);
+
+ (* Number sign state. *)
+ _elna_lexer_default_transition(ElnaLexerState.number_sign, ElnaLexerAction.key_id, ElnaLexerState.finish);
+ _elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.trait);
+ _elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.trait);
+ _elna_lexer_set_transition(ElnaLexerState.number_sign, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.trait);
+
+ (* Trait state. *)
+ _elna_lexer_default_transition(ElnaLexerState.trait, ElnaLexerAction.key_id, ElnaLexerState.finish);
+ _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.digit, ElnaLexerAction.accumulate, ElnaLexerState.trait);
+ _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.alpha, ElnaLexerAction.accumulate, ElnaLexerState.trait);
+ _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.hex, ElnaLexerAction.accumulate, ElnaLexerState.trait);
+ _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.zero, ElnaLexerAction.accumulate, ElnaLexerState.trait);
+ _elna_lexer_set_transition(ElnaLexerState.trait, ElnaLexerClass.x, ElnaLexerAction.accumulate, ElnaLexerState.trait)
end;
(**
@@ -5133,15 +5212,15 @@ end;
(**
* Lexer state is saved after the transition tables.
- * Each transition table entry is 8 bytes long. The table has 16 rows (transition states)
- * and 22 columns (character classes), so 2992 = 8 * 17 * 22.
+ * 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.
*)
proc _elna_lexer_global_state();
var
result: Word;
begin
result := _elna_lexer_get_transition_table();
- return result + 2992
+ return result + 3496
end;
(**
@@ -5274,7 +5353,9 @@ begin
result := ElnaLexerKind.identifier;
token_length := position_end - position_start;
- if string_compare(position_start, token_length, "const", 5) then
+ if _load_byte(position_start) = '#' then
+ result := ElnaLexerKind.trait
+ elsif string_compare(position_start, token_length, "const", 5) then
result := ElnaLexerKind._const
elsif string_compare(position_start, token_length, "var", 3) then
result := ElnaLexerKind._var