aboutsummaryrefslogtreecommitdiff
path: root/source/lexer.elna
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-13 18:14:45 +0200
committerEugen Wissner <belka@caraus.de>2026-07-13 18:14:45 +0200
commit500c0676b3f6cd5a2297987d5b0dc7ccf34a28d9 (patch)
treea394c73de9273489e6045f3d252714b5ac69b17c /source/lexer.elna
parent97741a01323021ccec8b0b60c6f8318c88ac373a (diff)
downloadelna-500c0676b3f6cd5a2297987d5b0dc7ccf34a28d9.tar.gz
Make return statement part of the body and not a statement
Diffstat (limited to 'source/lexer.elna')
-rw-r--r--source/lexer.elna205
1 files changed, 205 insertions, 0 deletions
diff --git a/source/lexer.elna b/source/lexer.elna
index 5029ec5..62ad3b1 100644
--- a/source/lexer.elna
+++ b/source/lexer.elna
@@ -622,4 +622,209 @@ begin
return result
end
+proc elna_lexer_classify_finalize(start_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken
+var
+ character: Char
+ result: ^ElnaLexerToken
+begin
+ character := start_position^;
+
+ if character = ':' then
+ result := elna_lexer_token_create(ElnaLexerKind.colon, position)
+ elsif character = '.' then
+ result := elna_lexer_token_create(ElnaLexerKind.dot, position)
+ elsif character = '(' then
+ result := elna_lexer_token_create(ElnaLexerKind.left_paren, position)
+ elsif character = '-' then
+ result := elna_lexer_token_create(ElnaLexerKind.minus, position)
+ elsif character = '<' then
+ result := elna_lexer_token_create(ElnaLexerKind.less_than, position)
+ elsif character = '>' then
+ result := elna_lexer_token_create(ElnaLexerKind.greater_than, position)
+ end;
+ return result
+end
+
+proc elna_lexer_classify_single(start_position: ^Char; position: ^ElnaPosition): ^ElnaLexerToken
+var
+ character: Char
+ result: ^ElnaLexerToken
+begin
+ result := malloc(#size(ElnaLexerToken));
+ character := start_position^;
+
+ if character = ';' then
+ result := elna_lexer_token_create(ElnaLexerKind.semicolon, position)
+ elsif character = ',' then
+ result := elna_lexer_token_create(ElnaLexerKind.comma, position)
+ elsif character = ')' then
+ result := elna_lexer_token_create(ElnaLexerKind.right_paren, position)
+ elsif character = '@' then
+ result := elna_lexer_token_create(ElnaLexerKind.at, position)
+ elsif character = '~' then
+ result := elna_lexer_token_create(ElnaLexerKind.not, position)
+ elsif character = '&' then
+ result := elna_lexer_token_create(ElnaLexerKind.and, position)
+ elsif character = '+' then
+ result := elna_lexer_token_create(ElnaLexerKind.plus, position)
+ elsif character = '*' then
+ result := elna_lexer_token_create(ElnaLexerKind.multiplication, position)
+ elsif character = '=' then
+ result := elna_lexer_token_create(ElnaLexerKind.equals, position)
+ elsif character = '%' then
+ result := elna_lexer_token_create(ElnaLexerKind.remainder, position)
+ elsif character = '/' then
+ result := elna_lexer_token_create(ElnaLexerKind.division, position)
+ elsif character = '.' then
+ result := elna_lexer_token_create(ElnaLexerKind.dot, position)
+ elsif character = '^' then
+ result := elna_lexer_token_create(ElnaLexerKind.hat, position)
+ elsif character = '[' then
+ result := elna_lexer_token_create(ElnaLexerKind.left_square, position)
+ elsif character = ']' then
+ result := elna_lexer_token_create(ElnaLexerKind.right_square, position)
+ end;
+ return result
+end
+
+proc elna_lexer_classify_composite(start_position, one_before_last: ^Char; position: ^ElnaPosition): ^ElnaLexerToken
+var
+ first_character: Char
+ last_character: Char
+ result: ^ElnaLexerToken
+begin
+ first_character := start_position^;
+ last_character := one_before_last^;
+
+ if first_character = ':' then
+ result := elna_lexer_token_create(ElnaLexerKind.assignment, position)
+ elsif first_character = '<' then
+ if last_character = '=' then
+ result := elna_lexer_token_create(ElnaLexerKind.less_equal, position)
+ elsif last_character = '>' then
+ result := elna_lexer_token_create(ElnaLexerKind.not_equal, position)
+ end
+ elsif first_character = '>' then
+ if last_character = '=' then
+ result := elna_lexer_token_create(ElnaLexerKind.greater_equal, position)
+ end
+ end;
+ return result
+end
+
+proc elna_lexer_execute_action(cursor: ^ElnaLexerCursor; action_to_perform: ElnaLexerAction): ^ElnaLexerToken
+var
+ token: ^ElnaLexerToken
+begin
+ token := nil;
+
+ if action_to_perform = ElnaLexerAction.none then
+ elsif action_to_perform = ElnaLexerAction.accumulate then
+ elna_lexer_advance(cursor)
+ elsif action_to_perform = ElnaLexerAction.skip then
+ elna_lexer_classify_space(cursor^.start, @cursor^.position.end_location);
+ cursor^.start := cursor^.start + 1;
+ cursor^.finish := cursor^.finish + 1
+ elsif action_to_perform = ElnaLexerAction.single then
+ elna_lexer_advance(cursor);
+
+ token := elna_lexer_classify_single(cursor^.start, @cursor^.position)
+ elsif action_to_perform = ElnaLexerAction.eof then
+ token := malloc(#size(ElnaLexerToken));
+ token^.kind := ElnaLexerKind.eof
+ elsif action_to_perform = ElnaLexerAction.finalize then
+ token := elna_lexer_classify_finalize(cursor^.start, @cursor^.position)
+ elsif action_to_perform = ElnaLexerAction.composite then
+ token := elna_lexer_classify_composite(cursor^.start, cursor^.finish, @cursor^.position);
+
+ elna_lexer_advance(cursor)
+ elsif action_to_perform = ElnaLexerAction.key_id then
+ token := elna_lexer_classify_keyword(cursor^.start, cursor^.finish, @cursor^.position)
+ elsif action_to_perform = ElnaLexerAction.integer then
+ token := elna_lexer_classify_integer(cursor^.start, cursor^.finish, @cursor^.position)
+ elsif action_to_perform = ElnaLexerAction.delimited then
+ elna_lexer_advance(cursor);
+
+ token := elna_lexer_classify_delimited(cursor^.start, cursor^.finish, @cursor^.position)
+ end;
+ return token
+end
+
+proc elna_lexer_execute_transition(cursor: ^ElnaLexerCursor): ^ElnaLexerToken
+var
+ next_transition: ^ElnaLexerTransition
+ current_character: Char
+begin
+ current_character := cursor^.finish^;
+ next_transition := elna_lexer_get_transition(cursor^.state,
+ classification[cast(current_character: Word) + 1u]);
+ cursor^.state := next_transition^.next_state;
+
+ return elna_lexer_execute_action(cursor, next_transition^.action)
+end
+
+(**
+ * One time lexer initialization.
+ *)
+proc elna_lexer_initialize(cursor: ^ElnaLexerCursor; code_pointer: ^Char)
+begin
+ elna_lexer_classifications();
+ elna_lexer_transitions();
+
+ cursor^.start := code_pointer;
+ cursor^.finish := code_pointer;
+ cursor^.token := nil;
+ cursor^.position.start_location := ElnaLocation(1u, 1u);
+ cursor^.position.end_location := ElnaLocation(1u, 1u);
+end
+
+(**
+ * Reads the next token and writes its type into the address in the kind parameter.
+ * Resets the lexer state for reading the next token.
+ *)
+proc elna_lexer_peek(cursor: ^ElnaLexerCursor): ^ElnaLexerToken
+var
+ token: ^ElnaLexerToken
+begin
+ if cursor^.token = nil then
+ cursor^.state := ElnaLexerState.start;
+
+ while cursor^.state <> ElnaLexerState.finish do
+ token := elna_lexer_execute_transition(cursor)
+ end;
+ cursor^.token := token
+ end;
+ return cursor^.token
+end
+
+(**
+ * Reads the token and advance the lexer.
+ *)
+proc elna_lexer_read(cursor: ^ElnaLexerCursor): ^ElnaLexerToken
+var
+ token: ^ElnaLexerToken
+begin
+ token := elna_lexer_peek(cursor);
+ cursor^.token := nil;
+ cursor^.start := cursor^.finish;
+ cursor^.position.start_location := cursor^.position.end_location;
+
+ return token
+end
+
+(**
+ * Skips comments.
+ *)
+proc elna_lexer_skip_empty_lines(cursor: ^ElnaLexerCursor)
+var
+ token: ^ElnaLexerToken
+begin
+ token := elna_lexer_peek(cursor);
+
+ while token^.kind = ElnaLexerKind.comment do
+ elna_lexer_read(cursor);
+ token := elna_lexer_peek(cursor)
+ end
+end
+
end.