More numeric literal stuff

This commit is contained in:
Kyler Olsen 2025-11-12 00:11:02 -07:00
parent f921b58359
commit 6394ec7ddd
1 changed files with 60 additions and 32 deletions

View File

@ -127,11 +127,13 @@ static LexerResult lexer_result(LexerInfo *lexer_info, Token token, size_t start
static LexerResult lexer_error(LexerInfo *lexer_info, SlsStr message, size_t start, size_t start_line) { static LexerResult lexer_error(LexerInfo *lexer_info, SlsStr message, size_t start, size_t start_line) {
// Create a LexerTokenResult to store an error from lexing the current token // Create a LexerTokenResult to store an error from lexing the current token
if (message.str == NULL)
return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Failed to allocate memory."), 1}};
LexerTokenResult *result = (LexerTokenResult *)malloc(sizeof(LexerTokenResult)); LexerTokenResult *result = (LexerTokenResult *)malloc(sizeof(LexerTokenResult));
if (result == NULL) if (result == NULL)
return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Failed to allocate memory."), 1}}; return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Failed to allocate memory."), 1}};
result->type = SLS_ERROR; result->type = SLS_ERROR;
result->error.message = message; result->error.message = sls_str_cpy(message);
result->error.code = 1; result->error.code = 1;
result->file_info = get_file_info(lexer_info, start, start_line); result->file_info = get_file_info(lexer_info, start, start_line);
result->next = NULL; result->next = NULL;
@ -143,14 +145,15 @@ typedef enum {
NUMERIC_FLOAT = 1 << 0, NUMERIC_FLOAT = 1 << 0,
NUMERIC_UNSIGNED = 1 << 1, NUMERIC_UNSIGNED = 1 << 1,
NUMERIC_EXPONENTIAL = 1 << 2, NUMERIC_EXPONENTIAL = 1 << 2,
NUMERIC_64 = 1 << 3, NUMERIC_NEGATIVE = 1 << 3,
NUMERIC_32 = 1 << 4, NUMERIC_64 = 1 << 4,
NUMERIC_16 = 1 << 5, NUMERIC_32 = 1 << 5,
NUMERIC_8 = 1 << 6, NUMERIC_16 = 1 << 6,
NUMERIC_BINARY = 1 << 7, NUMERIC_8 = 1 << 7,
NUMERIC_OCTAL = 1 << 8, NUMERIC_BINARY = 1 << 8,
NUMERIC_DECIMAL = 1 << 9, NUMERIC_OCTAL = 1 << 9,
NUMERIC_HEXADECIMAL = 1 << 10, NUMERIC_DECIMAL = 1 << 10,
NUMERIC_HEXADECIMAL = 1 << 11,
} NumericFlags; } NumericFlags;
typedef struct { typedef struct {
@ -221,44 +224,69 @@ static Numeric div_n(Numeric a, Numeric b) {
return i; return i;
} }
typedef struct {
SlsResultType type;
union {
SlsError error;
struct {
uint16_t flags;
Numeric value;
char c
};
};
} NumericNextResult;
static Boolean is_numeric_start(LexerInfo *lexer_info, char c, size_t start, size_t start_line) { static Boolean is_numeric_start(LexerInfo *lexer_info, char c, size_t start, size_t start_line) {
char c2 = far_peek(lexer_info, 1); char c2 = far_peek(lexer_info, 1);
if (isdigit(c) || c == '.' || (c == '-' && (isdigit(c2) || c2 == '.'))) return TRUE; if (isdigit(c) || c == '.' || (c == '-' && (isdigit(c2) || c2 == '.'))) return TRUE;
return FALSE; return FALSE;
} }
static Boolean is_base_digit(LexerInfo *lexer_info, char c, size_t start, size_t start_line, uint16_t flags) { static Boolean is_base_digit(LexerInfo *lexer_info, NumericNextResult value, size_t start, size_t start_line) {
if (flags & NUMERIC_BINARY) return (c == '0' || c == '1') ? TRUE : FALSE; if (value.flags & NUMERIC_BINARY) return (value.c == '0' || value.c == '1') ? TRUE : FALSE;
if (flags & NUMERIC_OCTAL) return (isdigit(c) && !(c == '8' || c == '9')) ? TRUE : FALSE; if (value.flags & NUMERIC_OCTAL) return (isdigit(value.c) && !(value.c == '8' || value.c == '9')) ? TRUE : FALSE;
if (flags & NUMERIC_DECIMAL) return (isdigit(c)) ? TRUE : FALSE; if (value.flags & NUMERIC_DECIMAL) return (isdigit(value.c)) ? TRUE : FALSE;
if (flags & NUMERIC_HEXADECIMAL) return (isxdigit(c)) ? TRUE : FALSE; if (value.flags & NUMERIC_HEXADECIMAL) return (isxdigit(value.c)) ? TRUE : FALSE;
return FALSE; return FALSE;
} }
typedef struct { static Boolean is_numeric_end(LexerInfo *lexer_info, char c, size_t start, size_t start_line) {
SlsResultType type; if (isspace(c) || c == '/' || c == '\0') return TRUE;
union { return FALSE;
uint16_t flags; }
SlsError error;
};
} NumericNextResult;
static NumericNextResult numeric_next(LexerInfo *lexer_info, char c, size_t start, size_t start_line, uint16_t flags) { static NumericNextResult numeric_next(LexerInfo *lexer_info, NumericNextResult value, size_t start, size_t start_line) {
if (lexer_info->pos == start && c == '0') if (lexer_info->pos == start && value.c == '-') {
value.flags |= NUMERIC_NEGATIVE;
value.c = advance(lexer_info);
}
if (!(value.flags & (NUMERIC_BINARY | NUMERIC_OCTAL | NUMERIC_DECIMAL | NUMERIC_HEXADECIMAL)) && value.c == '0') {
if (isalpha(far_peek(lexer_info, 1))) { if (isalpha(far_peek(lexer_info, 1))) {
c = advance(lexer_info); value.c = advance(lexer_info);
if (c == 'b' || c == 'B') flags |= NUMERIC_BINARY; if (value.c == 'b' || value.c == 'B') value.flags |= NUMERIC_BINARY;
else if (c == 'o' || c == 'O') flags |= NUMERIC_OCTAL; else if (value.c == 'o' || value.c == 'O') value.flags |= NUMERIC_OCTAL;
else if (c == 'o' || c == 'O') flags |= NUMERIC_OCTAL; else if (value.c == 'x' || value.c == 'X') value.flags |= NUMERIC_HEXADECIMAL;
else { else return (NumericNextResult){SLS_ERROR, .error = sls_format(SLS_STR("Invalid numeric literal: unexpected '%c' in numeric type."), value.c)};
} else value.flags |= NUMERIC_DECIMAL;
}; value.c = advance(lexer_info);
} else flags |= NUMERIC_DECIMAL; }
if (value.c == '_') value.c = advance(lexer_info);
else if (value.c == '.') return (NumericNextResult){SLS_ERROR, .error = SLS_STR("Lexer: Floats Not Implemented Error.")};
else if (value.c == 'e') return (NumericNextResult){SLS_ERROR, .error = SLS_STR("Lexer: Floats Not Implemented Error.")};
else if (is_base_digit(lexer_info, value, start, start_line)) {
value.c = advance(lexer_info);
} else return (NumericNextResult){SLS_ERROR, .error = sls_format(SLS_STR("Invalid numeric literal: unexpected '%c' in numeric type."), value.c)};
return value;
} }
static LexerResult read_numeric(LexerInfo *lexer_info, char c, size_t start, size_t start_line) { static LexerResult read_numeric(LexerInfo *lexer_info, char c, size_t start, size_t start_line) {
(void)lexer_info; (void)c; (void)start; (void)start_line; (void)lexer_info; (void)c; (void)start; (void)start_line;
return (LexerResult){SLS_ERROR, .error = (SlsError){"Lexer: Integers Not Implemented Error.", 1}}; NumericNextResult result = (NumericNextResult){SLS_RESULT, .flags = 0, .value = ZERO, .c = c};
while (!is_numeric_end(lexer_info, result.c, start, start_line)) {
result = numeric_next(lexer_info, result, start, start_line);
if (result.type == SLS_ERROR) return lexer_error(lexer_info, result.error.message, start, start_line);
}
return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Lexer: Integers Not Implemented Error."), 1}};
} }
static LexerResult parse_character_literal(LexerInfo *lexer_info, char c, size_t start, size_t start_line) { static LexerResult parse_character_literal(LexerInfo *lexer_info, char c, size_t start, size_t start_line) {