Setting up float and character tests

This commit is contained in:
Kyler Olsen 2025-11-14 17:22:06 -07:00
parent db14867474
commit 60925dab53
5 changed files with 107 additions and 77 deletions

View File

@ -10,6 +10,7 @@
- `u` uint64_t
- `z` size_t
- `f` double
- `n` unicode uint8_t\[4\] (Not Implemented)
- `s` string.h SlsStr
- `t` lexer.h TokenType
- `a` lexer.h ArrayType

View File

@ -127,6 +127,11 @@ static SlsStr integer_value_should_be(size_t i, uint64_t should, uint64_t found)
return sls_format(SLS_STR("Token #%z integer value should be %i, but found %i"), i, should, found);
}
static SlsStr character_value_should_be(size_t i, uint8_t should, uint8_t found) {
return sls_format(SLS_STR("Token #%z integer value should be %i, but found %i"), i, should, found);
// return sls_format(SLS_STR("Token #%z character value should be '', but found ''"), i, should[0], found[0]);
}
static SlsStr float_value_should_be(size_t i, double should, double found) {
return sls_format(SLS_STR("Token #%z float value should be %f, but found %f"), i, should, found);
}
@ -285,6 +290,18 @@ Boolean test_integer_value(LexerTest *test, LexerResult result, size_t i, TestIn
return FALSE;
}
Boolean test_character_value(LexerTest *test, LexerResult result, size_t i, uint8_t *value) {
static const TokenType token_type = TOKEN_INTEGER;
LexerTokenResult *head = get_token(result.result, i);
if (test_token_type(test, result, i, token_type)) {
return TRUE;
} if (head->result.integer_literal.value != *value) {
logic_fail_test(test, result, character_value_should_be(i + 1, *value, head->result.float_literal));
return TRUE;
}
return FALSE;
}
Boolean test_float_value(LexerTest *test, LexerResult result, size_t i, float *value) {
static const TokenType token_type = TOKEN_FLOAT;
LexerTokenResult *head = get_token(result.result, i);

View File

@ -5,15 +5,17 @@ from .base_tests import BaseTestGenerator
class CharTestGenerator(BaseTestGenerator):
"""Generate test cases for character literals."""
ENABLE_UNICODE = False
# Common escape sequences
ESCAPE_SEQUENCES = {
'\\n': '\n', # Newline
'\\r': '\r', # Carriage return
'\\t': '\t', # Tab
'\\\\': '\\', # Backslash
'\\"': '"', # Double quote
"\\'": "'", # Single quote
'\\0': '\0', # Null character
("Newline", '\\n', '\n',), # Newline
("Carriage return", '\\r', '\r',), # Carriage return
("Tab", '\\t', '\t',), # Tab
("Backslash", '\\\\', '\\',), # Backslash
("Double quote", '\\\\"', '"',), # Double quote
("Single quote", "\\'", "'",), # Single quote
("Null character", '\\0', '\0',), # Null character
}
# Hexadecimal escape examples
@ -77,8 +79,8 @@ class CharTestGenerator(BaseTestGenerator):
def generate_escape_sequence_tests(self):
"""Generate tests for escape sequences."""
# Standard escape sequences
for escape_str, char_val in self.ESCAPE_SEQUENCES.items():
name = f"Char Escape {escape_str}"
for escape_name, escape_str, char_val in self.ESCAPE_SEQUENCES:
name = f"Char Escape {escape_name}"
code = f"'{escape_str}'"
self.make_success_test(name, code, "char", char_val)
@ -88,7 +90,7 @@ class CharTestGenerator(BaseTestGenerator):
("Carriage Return", "'\\r'", '\r'),
("Tab", "'\\t'", '\t'),
("Backslash", "'\\\\'", '\\'),
("Double Quote", "'\\\"'", '"'),
("Double Quote", "'\\\\\"'", '"'),
("Single Quote", "'\\''", "'"),
("Null", "'\\0'", '\0'),
]
@ -163,8 +165,8 @@ class CharTestGenerator(BaseTestGenerator):
self.make_success_test("Char With Leading Whitespace", " 'A'", "char", 'A')
self.make_success_test("Char With Trailing Whitespace", "'A' ", "char", 'A')
self.make_success_test("Char With Both Whitespace", " 'A' ", "char", 'A')
self.make_success_test("Char Tab Before", "\t'B'", "char", 'B')
self.make_success_test("Char Newline Before", "\n'C'", "char", 'C')
self.make_success_test("Char Tab Before", "\\t'B'", "char", 'B')
self.make_success_test("Char Newline Before", "\\n'C'", "char", 'C')
def generate_error_tests(self):
"""Generate error test cases."""
@ -185,7 +187,7 @@ class CharTestGenerator(BaseTestGenerator):
# Unescaped newline
self.make_error_test("Char Unescaped Newline",
"'\n'",
"'\\n'",
"Invalid character literal: unescaped newline in character literal.")
# Invalid escape sequence
@ -204,9 +206,10 @@ class CharTestGenerator(BaseTestGenerator):
# Invalid hex digits
self.make_error_test("Char Hex Invalid Digit",
"'\\xGG'",
"'\\\\xGG'",
"Invalid character literal: invalid hexadecimal digit 'G'.")
if self.ENABLE_UNICODE:
# Invalid Unicode escape (no braces)
self.make_error_test("Char Unicode No Braces",
"'\\u1F600'",
@ -263,6 +266,7 @@ class CharTestGenerator(BaseTestGenerator):
self.make_success_test("Char Extended ASCII Lower", "'\\x80'", "char", '\x80')
self.make_success_test("Char Extended ASCII Upper", "'\\xFF'", "char", '\xFF')
if self.ENABLE_UNICODE:
# Zero-width characters
self.make_success_test("Char Zero Width Space", "'\\u{200B}'", "char", '\u200B')
self.make_success_test("Char Zero Width Joiner", "'\\u{200D}'", "char", '\u200D')
@ -285,7 +289,7 @@ class CharTestGenerator(BaseTestGenerator):
# Quote escaping
self.make_success_test("Char Single Quote Escaped", "'\\''", "char", "'")
self.make_success_test("Char Double Quote Escaped", "'\\\"'", "char", '"')
# self.make_success_test("Char Double Quote Escaped", "'\\\"'", "char", '"')
def generate_case_sensitivity_tests(self):
"""Generate tests for case sensitivity in escape sequences."""
@ -297,6 +301,7 @@ class CharTestGenerator(BaseTestGenerator):
self.make_success_test("Char Hex Digits Lowercase", "'\\xff'", "char", '\xff')
self.make_success_test("Char Hex Digits Mixed", "'\\xAb'", "char", '\xAB')
if self.ENABLE_UNICODE:
# Unicode escapes - lowercase u
self.make_success_test("Char Unicode Lowercase u", "'\\u{41}'", "char", 'A')
@ -316,6 +321,7 @@ class CharTestGenerator(BaseTestGenerator):
# Hexadecimal escapes
self.generate_hexadecimal_escape_tests()
if self.ENABLE_UNICODE:
# Unicode escapes
self.generate_unicode_escape_tests()

View File

@ -287,7 +287,7 @@ class FloatTestGenerator(BaseTestGenerator):
self.generate_underscore_tests()
# Special values (inf, nan)
self.generate_special_value_tests()
# self.generate_special_value_tests()
# Edge cases for each type
for type_name in ['f32', 'f64']:

View File

@ -68,6 +68,12 @@ def _token_to_c_call(token: dict, idx_var="i") -> str:
return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U16, {value}}})'
elif ttype == "u8":
return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U8, {value}}})'
elif ttype == "f64":
return f'test_double_value(&test, result, {idx_var}++, &(double){{{value}}})'
elif ttype == "f32":
return f'test_float_value(&test, result, {idx_var}++, &(float){{{value}}})'
elif ttype == "char":
return f'test_character_value(&test, result, {idx_var}++, &(uint8_t){{{ord(value)}}})' # type: ignore
elif ttype == "identifier":
return f'test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{FALSE, {len(value)}, "{value}"}})' # type: ignore
elif ttype == "identifier_literal":