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 - `u` uint64_t
- `z` size_t - `z` size_t
- `f` double - `f` double
- `n` unicode uint8_t\[4\] (Not Implemented)
- `s` string.h SlsStr - `s` string.h SlsStr
- `t` lexer.h TokenType - `t` lexer.h TokenType
- `a` lexer.h ArrayType - `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); 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) { 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); 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; 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) { Boolean test_float_value(LexerTest *test, LexerResult result, size_t i, float *value) {
static const TokenType token_type = TOKEN_FLOAT; static const TokenType token_type = TOKEN_FLOAT;
LexerTokenResult *head = get_token(result.result, i); LexerTokenResult *head = get_token(result.result, i);

View File

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

View File

@ -287,7 +287,7 @@ class FloatTestGenerator(BaseTestGenerator):
self.generate_underscore_tests() self.generate_underscore_tests()
# Special values (inf, nan) # Special values (inf, nan)
self.generate_special_value_tests() # self.generate_special_value_tests()
# Edge cases for each type # Edge cases for each type
for type_name in ['f32', 'f64']: 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}}})' return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U16, {value}}})'
elif ttype == "u8": elif ttype == "u8":
return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U8, {value}}})' 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": elif ttype == "identifier":
return f'test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{FALSE, {len(value)}, "{value}"}})' # type: ignore return f'test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{FALSE, {len(value)}, "{value}"}})' # type: ignore
elif ttype == "identifier_literal": elif ttype == "identifier_literal":