More numeric literal stuff
This commit is contained in:
parent
f921b58359
commit
6394ec7ddd
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue