// Kyler Olsen // YREA SLS // Lexer Header // October 2025 #ifndef SLS_LEXER_H #define SLS_LEXER_H #include #include "sls_errors.h" const size_t TYPE_NAMES_SAFE_LENGTH = 20; typedef struct { const char *filename; const char *source_code; size_t pos; size_t column; size_t line; } LexerInfo; typedef enum { TOKEN_EOF, TOKEN_IDENTIFIER, TOKEN_INTEGER, TOKEN_FLOAT, TOKEN_DOUBLE, TOKEN_STRING, TOKEN_BOOLEAN, TOKEN_ARRAY, TOKEN_TOKEN_STRING, TOKEN_TYPE_TUPLE, } TokenType; const char *TOKEN_TYPES_NAMES[] = { "End of File", "Identifier", "Integer", "Float", "Double", "String", "Boolean", "Array", "Token String", "Type Tuple", }; typedef enum { ARRAY_IDENTIFIER, ARRAY_I64, ARRAY_I32, ARRAY_I16, ARRAY_I8, ARRAY_U64, ARRAY_U32, ARRAY_U16, ARRAY_U8, ARRAY_FLOAT, ARRAY_DOUBLE, ARRAY_STRING, ARRAY_BOOLEAN, ARRAY_STRUCT_INLINE, } ArrayType; const char *ARRAY_TYPES_NAMES[] = { "Identifier", "i64", "i32", "i16", "i8", "u64", "u32", "u16", "u8", "Float", "Double", "String", "Boolean", "Inline Struct", }; typedef struct { const char *name; size_t length; Boolean is_literal; } Identifier; typedef enum { INTEGER_I64, INTEGER_I32, INTEGER_I16, INTEGER_I8, INTEGER_U64, INTEGER_U32, INTEGER_U16, INTEGER_U8, } IntegerBuiltInType; const char *INTEGER_TYPES_NAMES[] = { "i64", "i32", "i16", "i8", "u64", "u32", "u16", "u8", }; typedef struct { uint64_t value; IntegerBuiltInType type; } IntegerLiteral; typedef struct { const char *value; size_t length; } StringLiteral; typedef struct { const Token *tokens; size_t length; } TokenString; typedef struct { Identifier *input_identifiers; size_t input_length; Identifier *output_identifiers; size_t output_length; } TypeTuple; typedef struct { TokenString values; Identifier name; } StructInline; typedef struct ArrayLiteral { ArrayType type; union { Identifier *identifiers; // type == ARRAY_IDENTIFIER uint64_t *integer_literals; // type in { ARRAY_I64, ARRAY_I32, ARRAY_I16, ARRAY_I8, ARRAY_U64, ARRAY_U32, ARRAY_U16, ARRAY_U8, } float *float_literals; // type == ARRAY_FLOAT double *double_literals; // type == ARRAY_DOUBLE StringLiteral *string_literals; // type == ARRAY_STRING Boolean *boolean_literals; // type == ARRAY_BOOLEAN TokenString *token_strings; // type == ARRAY_TOKEN_STRING TypeTuple *type_tuples; // type == ARRAY_TYPE_TUPLE StructInline *type_tuples; // type == ARRAY_STRUCT_INLINE }; size_t *shape; size_t dimensions; } ArrayLiteral; typedef struct { TokenType type; union { Identifier identifier; // type == TOKEN_IDENTIFIER IntegerLiteral integer_literal; // type == TOKEN_INTEGER float float_literal; // type == TOKEN_FLOAT double double_literal; // type == TOKEN_DOUBLE StringLiteral string_literal; // type == TOKEN_STRING Boolean boolean_literal; // type == TOKEN_BOOLEAN ArrayLiteral array_literal; // type == TOKEN_ARRAY TokenString token_string; // type == TOKEN_TOKEN_STRING TypeTuple type_tuple; // type == TOKEN_TYPE_TUPLE }; } Token; typedef struct LexerTokenResult { SlsResultType type; union { Token result; // type == SLS_RESULT SlsError error; // type == SLS_ERROR }; FileInfo file_info; struct LexerTokenResult *next; } LexerTokenResult; typedef struct { SlsResultType type; union { LexerTokenResult *result; // type == SLS_RESULT SlsError error; // type == SLS_ERROR }; } LexerResult; void init_lexer(LexerInfo *lexer_info, const char *filename, const char *source_code); LexerResult lexical_analysis(LexerInfo *lexer_info); LexerTokenResult *get_token(LexerTokenResult *head, size_t i); void clean_token_result(LexerTokenResult *head); #endif // SLS_LEXER_H