#import "Jai_Lexer";
Turns Jai source text into tokens, with their types, values and positions.
Set a Lexer's input with set_input_from_string or set_input_from_file, look at upcoming tokens with peek_next_token and peek_token, and consume them with eat_token. The end of the input is a token of type END_OF_INPUT.
lexer: Lexer;
set_input_from_string(*lexer, "orchid 23");
token := peek_next_token(*lexer);
assert(token.type == .IDENT && token.ident_value.name == "orchid");
eat_token(*lexer);
token = peek_next_token(*lexer);
assert(token.type == .NUMBER && token.integer_value == 23);Procedures#
Characters#
Prints an error at the lexer's current position, formatted like print, and marks the lexer as having reported one.
True for a character that can begin an identifier: a letter or _.
assert(starts_identifier(#char "_") && !starts_identifier(#char "7"));↗Tokens#
Consumes the next token.
lexer: Lexer;
set_input_from_string(*lexer, "a b");
eat_token(*lexer);
assert(peek_next_token(*lexer).ident_value.name == "b");↗Returns a copy of the token most recently consumed with eat_token, for reporting its position after you have moved on.
Returns the next token without consuming it. Same as peek_token(lexer, 0).
Returns the token lookahead_index places ahead without consuming it; 0 is the next token. The index must be below MAX_CONCURRENT_TOKENS, and the pointer stays valid until you eat past it.
lexer: Lexer;
set_input_from_string(*lexer, "a + b");
assert(peek_token(*lexer, 1).type == #char "+");
assert(peek_token(*lexer, 0).ident_value.name == "a");↗Reads the file at file_path and lexes it. Returns false if it cannot be read. The lexer frees the text when it is given new input.
lexer: Lexer;
assert(!set_input_from_file(*lexer, "no/such/file.jai"));Doesn't run in the browser (skipped on wasm).
Points lexer at input and resets its position. The lexer reads input in place, so keep it alive while you lex.
lexer: Lexer;
set_input_from_string(*lexer, "x := 1;");
assert(peek_next_token(*lexer).type == .IDENT);↗Keywords#
Sets an identifier token's type to the keyword it spells, if any, and returns the type.
lexer: Lexer;
set_input_from_string(*lexer, "struct");
token := peek_next_token(*lexer);
assert(check_for_keyword(token) == .KEYWORD_STRUCT);↗Strings#
Numbers#
Types#
Which hex escape a string is reading: \x (two digits), \u (four) or \U (eight).
- ASCII_8_BIT
- UNICODE_16
- UNICODE_32
Flags on a @note.
- IS_SYSTEM_LEVEL
One token: its type, where it starts (l0, c0, line and column) and ends (l1, c1), and its value. Read ident_value for an identifier, integer_value or float64_value for a number (check value_flags), string_value for a string.
- type: Token_Type
- l0: s32
- c0: s32
- l1: s32
- c1: s32
- value_flags: Value_Flags
- ident_is_backticked: := false
What kind of token this is. Single-character tokens use their character as the value (#char "+"); everything else is named.
- BITWISE_XOR
- BITWISE_NOT
- BITWISE_AND
- BITWISE_OR
- IDENT
- NUMBER
- STRING
- PLUSEQUALS
- MINUSEQUALS
- TIMESEQUALS
- DIVEQUALS
- MODEQUALS
- ISEQUAL
- ISNOTEQUAL
- LOGICAL_AND
- LOGICAL_OR
- LESSEQUALS
- GREATEREQUALS
- RIGHT_ARROW
- DOUBLE_DOT
- DOUBLE_DOLLAR
- SHIFT_LEFT
- SHIFT_RIGHT
- ROTATE_LEFT
- ROTATE_RIGHT
- TRIPLE_EQUALS
- SHIFT_LEFT_EQUALS
- SHIFT_RIGHT_EQUALS
- ROTATE_LEFT_EQUALS
- ROTATE_RIGHT_EQUALS
- BITWISE_AND_EQUALS
- BITWISE_OR_EQUALS
- BITWISE_XOR_EQUALS
- LOGICAL_AND_EQUALS
- LOGICAL_OR_EQUALS
- POINTER_DEREFERENCE
- POSTFIX_DEREFERENCE
- ISEQUAL_FOR_SWITCH_STATEMENT
- DOUBLE_MINUS
- TRIPLE_MINUS
- DOUBLE_COMMA
- BEGIN_STRUCT_LITERAL
- BEGIN_ARRAY_LITERAL
- KEYWORD_FOR
- __FIRST_KEYWORD
- KEYWORD_IF
- KEYWORD_IFX
- KEYWORD_THEN
- KEYWORD_ELSE
- KEYWORD_CASE
- KEYWORD_RETURN
- KEYWORD_STRUCT
- KEYWORD_WHILE
- KEYWORD_BREAK
- KEYWORD_CONTINUE
- KEYWORD_REMOVE
- KEYWORD_USING
- KEYWORD_DEFER
- KEYWORD_SIZE_OF
- KEYWORD_TYPE_OF
- KEYWORD_CODE_OF
- KEYWORD_INITIALIZER_OF
- KEYWORD_TYPE_INFO
- KEYWORD_NULL
- KEYWORD_ENUM
- KEYWORD_TRUE
- KEYWORD_FALSE
- KEYWORD_INLINE
- KEYWORD_NO_INLINE
- KEYWORD_CAST
- KEYWORD_AUTO_CAST
- KEYWORD_CONTEXT
- KEYWORD_PUSH_CONTEXT
- KEYWORD_OPERATOR
- KEYWORD_IS_CONSTANT
- KEYWORD_ENUM_FLAGS
- KEYWORD_UNION
- KEYWORD_INTERFACE
- __LAST_KEYWORD
- QUICK_LAMBDA
- NOTE
- END_OF_INPUT
- POINTER_DEREFERENCE_OR_SHIFT_LEFT
- OPERATOR_ARRAY_SUBSCRIPT
- OPERATOR_ASSIGNMENT_TO_ARRAY_SUBSCRIPT
- ERROR
How a string or number token was written: as a here-string, in hex or binary, as a float, a float that needs 64-bit precision, or an integer that overflowed.
- HERE_STRING
- NUMBER
- HEX
- BINARY
- FLOAT
- REQUIRES_FLOAT64
- DEFAULTS_TO_FLOAT64
- REQUIRES_FLOAT64_DUE_TO_SIGNIFICANT_DIGITS
- OVERFLOWED
The state of a lex in progress: the input, the position, and the tokens read ahead. Start from a zeroed Lexer and call set_input_from_string or set_input_from_file.
- current_line_number: s32
- current_external_file_error_report_line_number: s32
- current_character_index: s32
- atom_pool: P.Pool
- tokens: [MAX_CONCURRENT_TOKENS] Token
- token_array_cursor: s32
- num_incoming_tokens: s32
- input: string
- input_cursor: s64
- should_free_input: := false
- total_lines_processed: s64
- nonblank_lines_processed: s64
- previous_token_line_number: s64
- eof_token: Token
- user_data: *void
- scratch_buffer: [MAX_IDENTIFIER_LENGTH] u8
- reported_error: := false