diff --git a/SLS_C/src/lexer.c b/SLS_C/src/lexer.c index 0968f1d..3e87323 100644 --- a/SLS_C/src/lexer.c +++ b/SLS_C/src/lexer.c @@ -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) { // 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)); if (result == NULL) return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Failed to allocate memory."), 1}}; result->type = SLS_ERROR; - result->error.message = message; + result->error.message = sls_str_cpy(message); result->error.code = 1; result->file_info = get_file_info(lexer_info, start, start_line); result->next = NULL; @@ -143,14 +145,15 @@ typedef enum { NUMERIC_FLOAT = 1 << 0, NUMERIC_UNSIGNED = 1 << 1, NUMERIC_EXPONENTIAL = 1 << 2, - NUMERIC_64 = 1 << 3, - NUMERIC_32 = 1 << 4, - NUMERIC_16 = 1 << 5, - NUMERIC_8 = 1 << 6, - NUMERIC_BINARY = 1 << 7, - NUMERIC_OCTAL = 1 << 8, - NUMERIC_DECIMAL = 1 << 9, - NUMERIC_HEXADECIMAL = 1 << 10, + NUMERIC_NEGATIVE = 1 << 3, + NUMERIC_64 = 1 << 4, + NUMERIC_32 = 1 << 5, + NUMERIC_16 = 1 << 6, + NUMERIC_8 = 1 << 7, + NUMERIC_BINARY = 1 << 8, + NUMERIC_OCTAL = 1 << 9, + NUMERIC_DECIMAL = 1 << 10, + NUMERIC_HEXADECIMAL = 1 << 11, } NumericFlags; typedef struct { @@ -221,44 +224,69 @@ static Numeric div_n(Numeric a, Numeric b) { 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) { char c2 = far_peek(lexer_info, 1); if (isdigit(c) || c == '.' || (c == '-' && (isdigit(c2) || c2 == '.'))) return TRUE; return FALSE; } -static Boolean is_base_digit(LexerInfo *lexer_info, char c, size_t start, size_t start_line, uint16_t flags) { - if (flags & NUMERIC_BINARY) return (c == '0' || c == '1') ? TRUE : FALSE; - if (flags & NUMERIC_OCTAL) return (isdigit(c) && !(c == '8' || c == '9')) ? TRUE : FALSE; - if (flags & NUMERIC_DECIMAL) return (isdigit(c)) ? TRUE : FALSE; - if (flags & NUMERIC_HEXADECIMAL) return (isxdigit(c)) ? TRUE : FALSE; +static Boolean is_base_digit(LexerInfo *lexer_info, NumericNextResult value, size_t start, size_t start_line) { + if (value.flags & NUMERIC_BINARY) return (value.c == '0' || value.c == '1') ? TRUE : FALSE; + if (value.flags & NUMERIC_OCTAL) return (isdigit(value.c) && !(value.c == '8' || value.c == '9')) ? TRUE : FALSE; + if (value.flags & NUMERIC_DECIMAL) return (isdigit(value.c)) ? TRUE : FALSE; + if (value.flags & NUMERIC_HEXADECIMAL) return (isxdigit(value.c)) ? TRUE : FALSE; return FALSE; } -typedef struct { - SlsResultType type; - union { - uint16_t flags; - SlsError error; - }; -} NumericNextResult; +static Boolean is_numeric_end(LexerInfo *lexer_info, char c, size_t start, size_t start_line) { + if (isspace(c) || c == '/' || c == '\0') return TRUE; + return FALSE; +} -static NumericNextResult numeric_next(LexerInfo *lexer_info, char c, size_t start, size_t start_line, uint16_t flags) { - if (lexer_info->pos == start && c == '0') +static NumericNextResult numeric_next(LexerInfo *lexer_info, NumericNextResult value, size_t start, size_t start_line) { + 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))) { - c = advance(lexer_info); - if (c == 'b' || c == 'B') flags |= NUMERIC_BINARY; - else if (c == 'o' || c == 'O') flags |= NUMERIC_OCTAL; - else if (c == 'o' || c == 'O') flags |= NUMERIC_OCTAL; - else { - - }; - } else flags |= NUMERIC_DECIMAL; + value.c = advance(lexer_info); + if (value.c == 'b' || value.c == 'B') value.flags |= NUMERIC_BINARY; + else if (value.c == 'o' || value.c == 'O') value.flags |= NUMERIC_OCTAL; + else if (value.c == 'x' || value.c == 'X') value.flags |= NUMERIC_HEXADECIMAL; + 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); + } + 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) { (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) {