Float literals are working
This commit is contained in:
parent
204a819b52
commit
77b43b9595
|
|
@ -4,3 +4,4 @@ This is a list of things defined as currently in the specification, but not incl
|
|||
|
||||
- Unicode support
|
||||
- Exponential literals
|
||||
- Arrays
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ static uint64_t create_decimal_integer(LexerInfo *lexer_info, size_t start) {
|
|||
}
|
||||
for (; i < lexer_info->pos - start; i++) {
|
||||
if (isspace(token[i]) || token[i] == '/' || token[i] == '\0' || token[i] == ':') break;
|
||||
if (token[i] == '.' || token[i] == '_') continue;
|
||||
if (token[i] == '_') continue;
|
||||
value *= 10;
|
||||
switch (token[i]) {
|
||||
case '1': value += 1; break;
|
||||
|
|
@ -366,6 +366,49 @@ static LexerResult create_integer_token(LexerInfo *lexer_info, IntegerBuiltInTyp
|
|||
return lexer_result(lexer_info, (Token){TOKEN_INTEGER, .integer_literal = (IntegerLiteral){.type = type, .value = value}}, start, start_line);
|
||||
}
|
||||
|
||||
static double create_float(LexerInfo *lexer_info, size_t start) {
|
||||
double value = 0;
|
||||
Boolean negative = FALSE;
|
||||
uint64_t fractional = 0;
|
||||
const char *token = get_token_text(lexer_info, start);
|
||||
size_t i = 0;
|
||||
if (token[0] == '-') {
|
||||
negative = TRUE;
|
||||
i += 1;
|
||||
}
|
||||
for (; i < lexer_info->pos - start; i++) {
|
||||
if (isspace(token[i]) || token[i] == '/' || token[i] == '\0' || token[i] == ':') break;
|
||||
if (token[i] == '_') continue;
|
||||
if (token[i] == '.') {
|
||||
fractional = 1;
|
||||
continue;
|
||||
}
|
||||
if (fractional == 0) value *= 10;
|
||||
else fractional *= 10;
|
||||
switch (token[i]) {
|
||||
case '1': value += 1.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '2': value += 2.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '3': value += 3.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '4': value += 4.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '5': value += 5.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '6': value += 6.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '7': value += 7.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '8': value += 8.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
case '9': value += 9.0 / (fractional == 0 ? 1 : fractional); break;
|
||||
}
|
||||
}
|
||||
if (negative) value = -value;
|
||||
return value;
|
||||
}
|
||||
|
||||
static LexerResult create_float_token(LexerInfo *lexer_info, NumericTypes type, size_t start, size_t start_line) {
|
||||
double value = create_float(lexer_info, start);
|
||||
if (type == NUMERIC_F64)
|
||||
return lexer_result(lexer_info, (Token){TOKEN_DOUBLE, .double_literal = value}, start, start_line);
|
||||
else
|
||||
return lexer_result(lexer_info, (Token){TOKEN_FLOAT, .float_literal = (float){value}}, start, start_line);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
NUMERIC_BINARY,
|
||||
NUMERIC_OCTAL,
|
||||
|
|
@ -450,7 +493,7 @@ static LexerResult parse_numeric_type(LexerInfo *lexer_info, char c, size_t star
|
|||
value = create_hexadecimal_integer(lexer_info, start);
|
||||
return create_integer_token(lexer_info, integer_type.integer_type, value, start, start_line);
|
||||
case NUMERIC_FLOAT:
|
||||
break;
|
||||
return create_float_token(lexer_info, numeric_type, start, start_line);
|
||||
case NUMERIC_EXPONENTIAL:
|
||||
break;
|
||||
}
|
||||
|
|
@ -491,14 +534,22 @@ static LexerResult parse_exponential(LexerInfo *lexer_info, char c, size_t start
|
|||
}
|
||||
|
||||
static LexerResult parse_float(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){SLS_STR("Lexer: Float Not Implemented Error."), 1}};
|
||||
while (isdigit(c) || c == '_') c = advance(lexer_info);
|
||||
if (c == 'e' || c == 'E') return parse_exponential(lexer_info, c, start, start_line);
|
||||
if (c == ':') return parse_numeric_type(lexer_info, c, start, start_line, NUMERIC_FLOAT);
|
||||
if (isspace(c) || c == '/' || c == '\0')
|
||||
return create_float_token(lexer_info, NUMERIC_F64, start, start_line);
|
||||
SlsStr error_msg = sls_format(SLS_STR("Invalid float literal: unexpected '%c' in float literal."), c);
|
||||
if (error_msg.str == NULL) return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Out Of Memory Error."), 1}};
|
||||
return lexer_error(lexer_info, error_msg, start, start_line);
|
||||
}
|
||||
|
||||
static LexerResult parse_decimal_integer(LexerInfo *lexer_info, char c, size_t start, size_t start_line) {
|
||||
while (isdigit(c) || c == '_') c = advance(lexer_info);
|
||||
if (c == '.') return parse_float(lexer_info, c, start, start_line);
|
||||
if (c == 'e' || c == 'E') return parse_exponential(lexer_info, c, start, start_line);
|
||||
if (c == '.') {
|
||||
c = advance(lexer_info);
|
||||
return parse_float(lexer_info, c, start, start_line);
|
||||
} if (c == 'e' || c == 'E') return parse_exponential(lexer_info, c, start, start_line);
|
||||
if (c == ':') return parse_numeric_type(lexer_info, c, start, start_line, NUMERIC_DECIMAL);
|
||||
if (isspace(c) || c == '/' || c == '\0') {
|
||||
uint64_t value = create_decimal_integer(lexer_info, start);
|
||||
|
|
@ -588,7 +639,8 @@ static LexerResult lexer_next(LexerInfo *lexer_info) {
|
|||
// End of file tokens
|
||||
if (c == '\0') return lexer_result(lexer_info, (Token){.type = TOKEN_EOF}, start, start_line);
|
||||
// Integers and Floats
|
||||
if (isdigit(c) || c == '.' || (c == '-' && isdigit(far_peek(lexer_info, 1)))) return parse_numeric_literal(lexer_info, c, start, start_line);
|
||||
if (isdigit(c) || (c == '.' && isdigit(far_peek(lexer_info, 1))) || (c == '-' && isdigit(far_peek(lexer_info, 1))))
|
||||
return parse_numeric_literal(lexer_info, c, start, start_line);
|
||||
// Character Literals
|
||||
if (c == '\'') return parse_character_literal(lexer_info, c, start, start_line);
|
||||
// String Literals
|
||||
|
|
|
|||
|
|
@ -61,14 +61,14 @@ TestResult logic_fail_test(LexerTest *test, LexerResult result, SlsStr message)
|
|||
}
|
||||
|
||||
TestResult logic_error_fail_test(LexerTest *test, LexerResult result, SlsError error) {
|
||||
clean_up_test(result);
|
||||
|
||||
if (error.message.str == NULL) return error_test_out_of_mem(test);
|
||||
|
||||
test->result.status = TEST_LOGIC_ERROR_FAIL;
|
||||
test->result.error = error;
|
||||
test->result.error.message = sls_str_cpy(error.message);
|
||||
|
||||
clean_up_test(result);
|
||||
|
||||
if (test->result.error.message.str == NULL) return error_test_out_of_mem(test);
|
||||
return test->result;
|
||||
}
|
||||
|
|
@ -319,8 +319,8 @@ Boolean test_double_value(LexerTest *test, LexerResult result, size_t i, double
|
|||
LexerTokenResult *head = get_token(result.result, i);
|
||||
if (test_token_type(test, result, i, token_type)) {
|
||||
return TRUE;
|
||||
} if (fabs(head->result.float_literal - *value) >= FLOAT_TEST_PRECISION) {
|
||||
logic_fail_test(test, result, float_value_should_be(i + 1, *value, head->result.float_literal));
|
||||
} if (fabs(head->result.double_literal - *value) >= FLOAT_TEST_PRECISION) {
|
||||
logic_fail_test(test, result, float_value_should_be(i + 1, *value, head->result.double_literal));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "sls/errors.h"
|
||||
#include "tests/tests.h"
|
||||
|
||||
static const Boolean PRINT_SUCCESSFUL_TESTS = FALSE;
|
||||
static const Boolean PRINT_SUCCESSFUL_TESTS = TRUE;
|
||||
|
||||
const SlsStr TEST_FILE_NAME = SLS_STR("TEST_FILE.SLS");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue