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,42 +206,43 @@ class CharTestGenerator(BaseTestGenerator):
# Invalid hex digits
self.make_error_test("Char Hex Invalid Digit",
"'\\xGG'",
"'\\\\xGG'",
"Invalid character literal: invalid hexadecimal digit 'G'.")
# Invalid Unicode escape (no braces)
self.make_error_test("Char Unicode No Braces",
"'\\u1F600'",
"Invalid character literal: Unicode escape must use braces \\u{...}.")
if self.ENABLE_UNICODE:
# Invalid Unicode escape (no braces)
self.make_error_test("Char Unicode No Braces",
"'\\u1F600'",
"Invalid character literal: Unicode escape must use braces \\u{...}.")
# Invalid Unicode escape (empty)
self.make_error_test("Char Unicode Empty",
"'\\u{}'",
"Invalid character literal: empty Unicode escape sequence.")
# Invalid Unicode escape (empty)
self.make_error_test("Char Unicode Empty",
"'\\u{}'",
"Invalid character literal: empty Unicode escape sequence.")
# Invalid Unicode escape (too many digits)
self.make_error_test("Char Unicode Too Many Digits",
"'\\u{1234567}'",
"Invalid character literal: Unicode escape sequence too long (max 6 hex digits).")
# Invalid Unicode escape (too many digits)
self.make_error_test("Char Unicode Too Many Digits",
"'\\u{1234567}'",
"Invalid character literal: Unicode escape sequence too long (max 6 hex digits).")
# Invalid Unicode escape (invalid code point)
self.make_error_test("Char Unicode Invalid Code Point",
"'\\u{D800}'",
"Invalid character literal: invalid Unicode code point (surrogate range).")
# Invalid Unicode escape (invalid code point)
self.make_error_test("Char Unicode Invalid Code Point",
"'\\u{D800}'",
"Invalid character literal: invalid Unicode code point (surrogate range).")
self.make_error_test("Char Unicode Out Of Range",
"'\\u{110000}'",
"Invalid character literal: Unicode code point out of range (max 0x10FFFF).")
self.make_error_test("Char Unicode Out Of Range",
"'\\u{110000}'",
"Invalid character literal: Unicode code point out of range (max 0x10FFFF).")
# Invalid Unicode escape (non-hex digits)
self.make_error_test("Char Unicode Invalid Hex",
"'\\u{GGGG}'",
"Invalid character literal: invalid hexadecimal digit 'G' in Unicode escape.")
# Invalid Unicode escape (non-hex digits)
self.make_error_test("Char Unicode Invalid Hex",
"'\\u{GGGG}'",
"Invalid character literal: invalid hexadecimal digit 'G' in Unicode escape.")
# Unclosed Unicode escape
self.make_error_test("Char Unicode Unclosed",
"'\\u{1F600'",
"Invalid character literal: unclosed Unicode escape sequence.")
# Unclosed Unicode escape
self.make_error_test("Char Unicode Unclosed",
"'\\u{1F600'",
"Invalid character literal: unclosed Unicode escape sequence.")
# Double quotes instead of single
self.make_error_test("Char Double Quotes",
@ -263,29 +266,30 @@ 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')
# 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')
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')
# Right-to-left marks
self.make_success_test("Char RTL Mark", "'\\u{200F}'", "char", '\u200F')
# Right-to-left marks
self.make_success_test("Char RTL Mark", "'\\u{200F}'", "char", '\u200F')
# Combining characters
self.make_success_test("Char Combining Acute", "'\\u{0301}'", "char", '\u0301')
# Combining characters
self.make_success_test("Char Combining Acute", "'\\u{0301}'", "char", '\u0301')
# Low Unicode values
self.make_success_test("Char Unicode Zero", "'\\u{0}'", "char", '\0')
self.make_success_test("Char Unicode One", "'\\u{1}'", "char", '\x01')
# Low Unicode values
self.make_success_test("Char Unicode Zero", "'\\u{0}'", "char", '\0')
self.make_success_test("Char Unicode One", "'\\u{1}'", "char", '\x01')
# High Unicode values (but valid)
self.make_success_test("Char Unicode High Valid", "'\\u{10FFFF}'", "char", '\U0010FFFF')
# High Unicode values (but valid)
self.make_success_test("Char Unicode High Valid", "'\\u{10FFFF}'", "char", '\U0010FFFF')
# Backslash before valid character
self.make_success_test("Char Backslash Literal", "'\\\\'", "char", '\\')
# 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,13 +301,14 @@ 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')
# Unicode escapes - lowercase u
self.make_success_test("Char Unicode Lowercase u", "'\\u{41}'", "char", 'A')
if self.ENABLE_UNICODE:
# Unicode escapes - lowercase u
self.make_success_test("Char Unicode Lowercase u", "'\\u{41}'", "char", 'A')
# Unicode hex digits - both cases
self.make_success_test("Char Unicode Hex Uppercase", "'\\u{1F600}'", "char", '😀')
self.make_success_test("Char Unicode Hex Lowercase", "'\\u{1f600}'", "char", '😀')
self.make_success_test("Char Unicode Hex Mixed", "'\\u{1F60a}'", "char", '😊')
# Unicode hex digits - both cases
self.make_success_test("Char Unicode Hex Uppercase", "'\\u{1F600}'", "char", '😀')
self.make_success_test("Char Unicode Hex Lowercase", "'\\u{1f600}'", "char", '😀')
self.make_success_test("Char Unicode Hex Mixed", "'\\u{1F60a}'", "char", '😊')
def generate_all_tests(self) -> List[Dict[str, Any]]:
"""Generate all character literal test cases."""
@ -316,11 +321,12 @@ class CharTestGenerator(BaseTestGenerator):
# Hexadecimal escapes
self.generate_hexadecimal_escape_tests()
# Unicode escapes
self.generate_unicode_escape_tests()
if self.ENABLE_UNICODE:
# Unicode escapes
self.generate_unicode_escape_tests()
# Direct Unicode characters
self.generate_unicode_direct_tests()
# Direct Unicode characters
self.generate_unicode_direct_tests()
# Whitespace handling
self.generate_whitespace_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":