Fixes and cleaning up

This commit is contained in:
Kyler Olsen 2025-11-21 00:13:47 -07:00
parent ee8b7a8f45
commit d2e990fe9b
5 changed files with 156 additions and 324 deletions

View File

@ -658,33 +658,43 @@ static LexerResult parse_type_tuples(LexerInfo *lexer_info, char c, size_t start
} }
Boolean is_identifier_continue(LexerInfo *lexer_info, char c) { Boolean is_identifier_continue(LexerInfo *lexer_info, char c) {
// If the current character and its context are a valid identifier character
if (!isprint(c)) return FALSE; if (!isprint(c)) return FALSE;
if (c == '/' && far_peek(lexer_info, 1) == '/') return FALSE; if (c == '/' && far_peek(lexer_info, 1) == '/') return FALSE;
if (c == '{' || c == '}') return FALSE; if (c == '{' || c == '}') return FALSE;
if (c == '[' || c == ']') return FALSE; if (c == '[' || c == ']') return FALSE;
if (c == '(' || c == ')') return FALSE; if (c == '(' || c == ')') return FALSE;
if (c == '\'' || c == '"') return FALSE; if (c == '\'' || c == '"' || c == '#') return FALSE;
if (c == '.' || c == ':' || c == '#') return FALSE;
if (isspace(c) || c == '\0') return FALSE; if (isspace(c) || c == '\0') return FALSE;
return TRUE; return TRUE;
} }
Boolean is_identifier_start(LexerInfo *lexer_info, char c) { Boolean is_identifier_start(LexerInfo *lexer_info) {
// If the current character and its context are a valid identifier start
char c = peek(lexer_info);
if (c == ':' && far_peek(lexer_info, 1) == ':') c = far_peek(lexer_info, 2); if (c == ':' && far_peek(lexer_info, 1) == ':') c = far_peek(lexer_info, 2);
if ((!isdigit(c)) && is_identifier_continue(lexer_info, c)) return TRUE; if ((!isdigit(c)) && is_identifier_continue(lexer_info, c)) return TRUE;
else return FALSE; else return FALSE;
} }
static LexerResult parse_identifiers_and_booleans(LexerInfo *lexer_info, char c, size_t start, size_t start_line) { static LexerResult parse_identifiers_and_booleans(LexerInfo *lexer_info, char c, size_t start, size_t start_line) {
// Parses identifier, identifier literals, and boolean tokens
Boolean literal = FALSE; Boolean literal = FALSE;
// Skip leading `::` for identifier literals
if (c == ':' && far_peek(lexer_info, 1) == ':') { if (c == ':' && far_peek(lexer_info, 1) == ':') {
literal = TRUE; literal = TRUE;
c = advance(lexer_info); c = advance(lexer_info);
c = advance(lexer_info); c = advance(lexer_info);
} }
// Read the name of the identifier
size_t length = 0; size_t length = 0;
while (is_identifier_continue(lexer_info, c)) { while (is_identifier_continue(lexer_info, c)) {
if (c == ':') // && !literal)
return lexer_error(lexer_info, SLS_STR("Invalid identifier: ':' is not allowed in identifiers."), start, start_line);
if (c == '.') // && !literal)
return lexer_error(lexer_info, SLS_STR("Invalid identifier: '.' is not allowed in identifiers."), start, start_line);
c = advance(lexer_info); c = advance(lexer_info);
length++; length++;
} }
@ -693,6 +703,8 @@ static LexerResult parse_identifiers_and_booleans(LexerInfo *lexer_info, char c,
name_value[i] = lexer_info->source_code.str[start + i + (2 * literal)]; name_value[i] = lexer_info->source_code.str[start + i + (2 * literal)];
SlsStr name = sls_str_malloc(name_value, length); SlsStr name = sls_str_malloc(name_value, length);
free(name_value); free(name_value);
// Return as identifier or boolean tokens
if (sls_str_cmp(name, SLS_STR("false")) == 0) if (sls_str_cmp(name, SLS_STR("false")) == 0)
return lexer_result(lexer_info, (Token){TOKEN_BOOLEAN, .boolean_literal = FALSE}, start, start_line); return lexer_result(lexer_info, (Token){TOKEN_BOOLEAN, .boolean_literal = FALSE}, start, start_line);
else if (sls_str_cmp(name, SLS_STR("true")) == 0) else if (sls_str_cmp(name, SLS_STR("true")) == 0)
@ -707,7 +719,8 @@ static LexerResult lexer_next(LexerInfo *lexer_info) {
while (isspace(peek(lexer_info)) || peek(lexer_info) == '/' || peek(lexer_info) == '#') { while (isspace(peek(lexer_info)) || peek(lexer_info) == '/' || peek(lexer_info) == '#') {
// Skip Comments // Skip Comments
if ((peek(lexer_info) == '/' && far_peek(lexer_info, 1) == '/') || peek(lexer_info) == '#') if ((peek(lexer_info) == '/' && far_peek(lexer_info, 1) == '/') || peek(lexer_info) == '#')
while (peek(lexer_info) != '\n') advance(lexer_info); while (!(peek(lexer_info) == '\n' || peek(lexer_info) == '\0'))
advance(lexer_info);
// Skip whitespace // Skip whitespace
while (isspace(peek(lexer_info))) advance(lexer_info); while (isspace(peek(lexer_info))) advance(lexer_info);
} }
@ -728,16 +741,22 @@ static LexerResult lexer_next(LexerInfo *lexer_info) {
return parse_character_literal(lexer_info, c, start, start_line); return parse_character_literal(lexer_info, c, start, start_line);
} }
// String Literals // String Literals
if (c == '\"') return parse_string_literal(lexer_info, c, start, start_line); // if (c == '\"') return parse_string_literal(lexer_info, c, start, start_line);
// Token Strings // Token Strings
if (c == '{') return parse_token_string(lexer_info, c, start, start_line); if (c == '{') return parse_token_string(lexer_info, c, start, start_line);
// Array Literals // Array Literals
if (c == '[') return parse_array_literal(lexer_info, c, start, start_line); // if (c == '[') return parse_array_literal(lexer_info, c, start, start_line);
// Type Tuples // Type Tuples
if (c == '(') return parse_type_tuples(lexer_info, c, start, start_line); // if (c == '(') return parse_type_tuples(lexer_info, c, start, start_line);
// Identifiers and Booleans // Identifiers and Booleans
if (is_identifier_start(lexer_info, c)) if (is_identifier_start(lexer_info))
return parse_identifiers_and_booleans(lexer_info, c, start, start_line); return parse_identifiers_and_booleans(lexer_info, c, start, start_line);
// Random Characters
if (c == ':' || c == '\"' || c == '[' || c == '(') {
SlsStr error_msg = sls_format(SLS_STR("Unexpected character: unexpected '%c' during parsing."), 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);
}
// Lexing Error // Lexing Error
return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Lexer: Unknown Character Error."), 1}}; return (LexerResult){SLS_ERROR, .error = (SlsError){SLS_STR("Lexer: Unknown Character Error."), 1}};
} }

View File

@ -16,7 +16,7 @@
#include "tests/tests.h" #include "tests/tests.h"
static const size_t NUM_OF_TESTS = 356; static const size_t NUM_OF_TESTS = 344;
static TestResult test_Empty_Statement() { static TestResult test_Empty_Statement() {
LexerTest test = start_up_test(SLS_STR("Empty_Statement"), SLS_STR("")); LexerTest test = start_up_test(SLS_STR("Empty_Statement"), SLS_STR(""));
@ -2073,26 +2073,6 @@ static TestResult test_Char_Right_Brace() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Escape_Carriage_return() {
LexerTest test = start_up_test(SLS_STR("Char Escape Carriage return"), SLS_STR("'\\r'"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){13})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Char_Escape_Tab() {
LexerTest test = start_up_test(SLS_STR("Char Escape Tab"), SLS_STR("'\\t'"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){9})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Char_Escape_Null_character() { static TestResult test_Char_Escape_Null_character() {
LexerTest test = start_up_test(SLS_STR("Char Escape Null character"), SLS_STR("'\\0'")); LexerTest test = start_up_test(SLS_STR("Char Escape Null character"), SLS_STR("'\\0'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
@ -2103,6 +2083,26 @@ static TestResult test_Char_Escape_Null_character() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Escape_Backslash() {
LexerTest test = start_up_test(SLS_STR("Char Escape Backslash"), SLS_STR("'\\\\'"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){92})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Char_Escape_Carriage_return() {
LexerTest test = start_up_test(SLS_STR("Char Escape Carriage return"), SLS_STR("'\\r'"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){13})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Char_Escape_Single_quote() { static TestResult test_Char_Escape_Single_quote() {
LexerTest test = start_up_test(SLS_STR("Char Escape Single quote"), SLS_STR("'\\''")); LexerTest test = start_up_test(SLS_STR("Char Escape Single quote"), SLS_STR("'\\''"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
@ -2113,12 +2113,12 @@ static TestResult test_Char_Escape_Single_quote() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Char_Escape_Backslash() { static TestResult test_Char_Escape_Tab() {
LexerTest test = start_up_test(SLS_STR("Char Escape Backslash"), SLS_STR("'\\\\'")); LexerTest test = start_up_test(SLS_STR("Char Escape Tab"), SLS_STR("'\\t'"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_character_value(&test, result, i++, &(uint8_t){92})) return test.result; if (test_character_value(&test, result, i++, &(uint8_t){9})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -2600,7 +2600,7 @@ static TestResult test_Identifier_With_Dash() {
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){TRUE, SLS_STR("my-var")})) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, SLS_STR("my-var")})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result; if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -2849,25 +2849,8 @@ static TestResult test_Identifier_With_Octothorpe() {
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: '#' is not allowed in identifiers."))) return test.result; if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, SLS_STR("my")})) return test.result;
return pass_test(&test, result); if (test_eof_value(&test, result, i++, 0)) return test.result;
}
static TestResult test_Identifier_With_Dot() {
LexerTest test = start_up_test(SLS_STR("Identifier With Dot"), SLS_STR("my.var"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: '.' is not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Space() {
LexerTest test = start_up_test(SLS_STR("Identifier With Space"), SLS_STR("my var"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: whitespace not allowed in identifiers."))) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -2885,79 +2868,7 @@ static TestResult test_Identifier_Double_Colon_Inside() {
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: '::' only allowed as prefix for identifier literals."))) return test.result; if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: ':' is not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_At() {
LexerTest test = start_up_test(SLS_STR("Identifier With At"), SLS_STR("@variable"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: '@' is not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Dollar() {
LexerTest test = start_up_test(SLS_STR("Identifier With Dollar"), SLS_STR("$variable"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: '$' is not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Percent() {
LexerTest test = start_up_test(SLS_STR("Identifier With Percent"), SLS_STR("%variable"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: '%' is not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Brackets() {
LexerTest test = start_up_test(SLS_STR("Identifier With Brackets"), SLS_STR("my[var]"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: brackets not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Braces() {
LexerTest test = start_up_test(SLS_STR("Identifier With Braces"), SLS_STR("my{var}"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: braces not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Parens() {
LexerTest test = start_up_test(SLS_STR("Identifier With Parens"), SLS_STR("my(var)"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: parentheses not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Single_Quote() {
LexerTest test = start_up_test(SLS_STR("Identifier With Single Quote"), SLS_STR("my'var"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: quotes not allowed in identifiers."))) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_With_Double_Quote() {
LexerTest test = start_up_test(SLS_STR("Identifier With Double Quote"), SLS_STR("my\"var"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier: quotes not allowed in identifiers."))) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -2966,7 +2877,8 @@ static TestResult test_Identifier_Only_Numbers() {
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Not an identifier: numeric literal."))) return test.result; if (test_integer_value(&test, result, i++, &(TestIntegerValue){INTEGER_I64, 123})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -2975,7 +2887,7 @@ static TestResult test_Identifier_Literal_Empty() {
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error); if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0; size_t i = 0;
if (test_for_error(&test, result, i++, SLS_STR("Invalid identifier literal: empty identifier after '::'."))) return test.result; if (test_for_error(&test, result, i++, SLS_STR("Unexpected character: unexpected ':' during parsing."))) return test.result;
return pass_test(&test, result); return pass_test(&test, result);
} }
@ -3029,26 +2941,6 @@ static TestResult test_Identifier_Case_Pascal() {
return pass_test(&test, result); return pass_test(&test, result);
} }
static TestResult test_Identifier_Reserved_Word_true() {
LexerTest test = start_up_test(SLS_STR("Identifier Reserved Word true"), SLS_STR("true"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, SLS_STR("true")})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_Reserved_Word_false() {
LexerTest test = start_up_test(SLS_STR("Identifier Reserved Word false"), SLS_STR("false"));
LexerResult result = lexical_analysis(&test.lexer_info);
if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);
size_t i = 0;
if (test_identifier_value(&test, result, i++, &(TestIdentifierValue){FALSE, SLS_STR("false")})) return test.result;
if (test_eof_value(&test, result, i++, 0)) return test.result;
return pass_test(&test, result);
}
static TestResult test_Identifier_Reserved_Word_if() { static TestResult test_Identifier_Reserved_Word_if() {
LexerTest test = start_up_test(SLS_STR("Identifier Reserved Word if"), SLS_STR("if")); LexerTest test = start_up_test(SLS_STR("Identifier Reserved Word if"), SLS_STR("if"));
LexerResult result = lexical_analysis(&test.lexer_info); LexerResult result = lexical_analysis(&test.lexer_info);
@ -3750,11 +3642,11 @@ TestsReport run_lexer_tests() {
test_report.tests[i++] = test_Char_Right_Bracket(); test_report.tests[i++] = test_Char_Right_Bracket();
test_report.tests[i++] = test_Char_Left_Brace(); test_report.tests[i++] = test_Char_Left_Brace();
test_report.tests[i++] = test_Char_Right_Brace(); test_report.tests[i++] = test_Char_Right_Brace();
test_report.tests[i++] = test_Char_Escape_Carriage_return();
test_report.tests[i++] = test_Char_Escape_Tab();
test_report.tests[i++] = test_Char_Escape_Null_character(); test_report.tests[i++] = test_Char_Escape_Null_character();
test_report.tests[i++] = test_Char_Escape_Single_quote();
test_report.tests[i++] = test_Char_Escape_Backslash(); test_report.tests[i++] = test_Char_Escape_Backslash();
test_report.tests[i++] = test_Char_Escape_Carriage_return();
test_report.tests[i++] = test_Char_Escape_Single_quote();
test_report.tests[i++] = test_Char_Escape_Tab();
test_report.tests[i++] = test_Char_Escape_Newline(); test_report.tests[i++] = test_Char_Escape_Newline();
test_report.tests[i++] = test_Char_Hex_Lowercase_A(); test_report.tests[i++] = test_Char_Hex_Lowercase_A();
test_report.tests[i++] = test_Char_Hex_Uppercase_A(); test_report.tests[i++] = test_Char_Hex_Uppercase_A();
@ -3829,18 +3721,8 @@ TestsReport run_lexer_tests() {
test_report.tests[i++] = test_Identifier_Long_With_Numbers(); test_report.tests[i++] = test_Identifier_Long_With_Numbers();
test_report.tests[i++] = test_Identifier_Starting_With_Number(); test_report.tests[i++] = test_Identifier_Starting_With_Number();
test_report.tests[i++] = test_Identifier_With_Octothorpe(); test_report.tests[i++] = test_Identifier_With_Octothorpe();
test_report.tests[i++] = test_Identifier_With_Dot();
test_report.tests[i++] = test_Identifier_With_Space();
test_report.tests[i++] = test_Identifier_With_Colon(); test_report.tests[i++] = test_Identifier_With_Colon();
test_report.tests[i++] = test_Identifier_Double_Colon_Inside(); test_report.tests[i++] = test_Identifier_Double_Colon_Inside();
test_report.tests[i++] = test_Identifier_With_At();
test_report.tests[i++] = test_Identifier_With_Dollar();
test_report.tests[i++] = test_Identifier_With_Percent();
test_report.tests[i++] = test_Identifier_With_Brackets();
test_report.tests[i++] = test_Identifier_With_Braces();
test_report.tests[i++] = test_Identifier_With_Parens();
test_report.tests[i++] = test_Identifier_With_Single_Quote();
test_report.tests[i++] = test_Identifier_With_Double_Quote();
test_report.tests[i++] = test_Identifier_Only_Numbers(); test_report.tests[i++] = test_Identifier_Only_Numbers();
test_report.tests[i++] = test_Identifier_Literal_Empty(); test_report.tests[i++] = test_Identifier_Literal_Empty();
test_report.tests[i++] = test_Identifier_Case_Lower(); test_report.tests[i++] = test_Identifier_Case_Lower();
@ -3848,8 +3730,6 @@ TestsReport run_lexer_tests() {
test_report.tests[i++] = test_Identifier_Case_Mixed(); test_report.tests[i++] = test_Identifier_Case_Mixed();
test_report.tests[i++] = test_Identifier_Case_Camel(); test_report.tests[i++] = test_Identifier_Case_Camel();
test_report.tests[i++] = test_Identifier_Case_Pascal(); test_report.tests[i++] = test_Identifier_Case_Pascal();
test_report.tests[i++] = test_Identifier_Reserved_Word_true();
test_report.tests[i++] = test_Identifier_Reserved_Word_false();
test_report.tests[i++] = test_Identifier_Reserved_Word_if(); test_report.tests[i++] = test_Identifier_Reserved_Word_if();
test_report.tests[i++] = test_Identifier_Reserved_Word_while(); test_report.tests[i++] = test_Identifier_Reserved_Word_while();
test_report.tests[i++] = test_Identifier_Reserved_Word_for(); test_report.tests[i++] = test_Identifier_Reserved_Word_for();

View File

@ -2317,30 +2317,6 @@
stack_final: stack_final:
- type: char - type: char
value: '}' value: '}'
- name: Char Escape Carriage return
code: '''\\r'''
tokens:
- type: char
value: "\r"
operations:
- function: push
type: char
value: "\r"
stack_final:
- type: char
value: "\r"
- name: Char Escape Tab
code: '''\\t'''
tokens:
- type: char
value: "\t"
operations:
- function: push
type: char
value: "\t"
stack_final:
- type: char
value: "\t"
- name: Char Escape Null character - name: Char Escape Null character
code: '''\\0''' code: '''\\0'''
tokens: tokens:
@ -2353,18 +2329,6 @@
stack_final: stack_final:
- type: char - type: char
value: "\0" value: "\0"
- name: Char Escape Single quote
code: '''\\'''''
tokens:
- type: char
value: ''''
operations:
- function: push
type: char
value: ''''
stack_final:
- type: char
value: ''''
- name: Char Escape Backslash - name: Char Escape Backslash
code: '''\\\\''' code: '''\\\\'''
tokens: tokens:
@ -2377,6 +2341,42 @@
stack_final: stack_final:
- type: char - type: char
value: \ value: \
- name: Char Escape Carriage return
code: '''\\r'''
tokens:
- type: char
value: "\r"
operations:
- function: push
type: char
value: "\r"
stack_final:
- type: char
value: "\r"
- name: Char Escape Single quote
code: '''\\'''''
tokens:
- type: char
value: ''''
operations:
- function: push
type: char
value: ''''
stack_final:
- type: char
value: ''''
- name: Char Escape Tab
code: '''\\t'''
tokens:
- type: char
value: "\t"
operations:
- function: push
type: char
value: "\t"
stack_final:
- type: char
value: "\t"
- name: Char Escape Newline - name: Char Escape Newline
code: '''\\n''' code: '''\\n'''
tokens: tokens:
@ -2912,14 +2912,14 @@
- name: Identifier With Dash - name: Identifier With Dash
code: my-var code: my-var
tokens: tokens:
- type: identifier_literal - type: identifier
value: my-var value: my-var
operations: operations:
- function: push - function: push
type: identifier_literal type: identifier
value: my-var value: my-var
stack_final: stack_final:
- type: identifier_literal - type: identifier
value: my-var value: my-var
- name: Identifier Literal Simple - name: Identifier Literal Simple
code: ::hello code: ::hello
@ -3205,18 +3205,15 @@
- name: Identifier With Octothorpe - name: Identifier With Octothorpe
code: my#var code: my#var
tokens: tokens:
- type: error - type: identifier
value: 'Invalid identifier: ''#'' is not allowed in identifiers.' value: my
- name: Identifier With Dot operations:
code: my.var - function: push
tokens: type: identifier
- type: error value: my
value: 'Invalid identifier: ''.'' is not allowed in identifiers.' stack_final:
- name: Identifier With Space - type: identifier
code: my var value: my
tokens:
- type: error
value: 'Invalid identifier: whitespace not allowed in identifiers.'
- name: Identifier With Colon - name: Identifier With Colon
code: my:var code: my:var
tokens: tokens:
@ -3226,57 +3223,24 @@
code: my::var code: my::var
tokens: tokens:
- type: error - type: error
value: 'Invalid identifier: ''::'' only allowed as prefix for identifier literals.' value: 'Invalid identifier: '':'' is not allowed in identifiers.'
- name: Identifier With At
code: '@variable'
tokens:
- type: error
value: 'Invalid identifier: ''@'' is not allowed in identifiers.'
- name: Identifier With Dollar
code: $variable
tokens:
- type: error
value: 'Invalid identifier: ''$'' is not allowed in identifiers.'
- name: Identifier With Percent
code: '%variable'
tokens:
- type: error
value: 'Invalid identifier: ''%'' is not allowed in identifiers.'
- name: Identifier With Brackets
code: my[var]
tokens:
- type: error
value: 'Invalid identifier: brackets not allowed in identifiers.'
- name: Identifier With Braces
code: my{var}
tokens:
- type: error
value: 'Invalid identifier: braces not allowed in identifiers.'
- name: Identifier With Parens
code: my(var)
tokens:
- type: error
value: 'Invalid identifier: parentheses not allowed in identifiers.'
- name: Identifier With Single Quote
code: my'var
tokens:
- type: error
value: 'Invalid identifier: quotes not allowed in identifiers.'
- name: Identifier With Double Quote
code: my"var
tokens:
- type: error
value: 'Invalid identifier: quotes not allowed in identifiers.'
- name: Identifier Only Numbers - name: Identifier Only Numbers
code: '123' code: '123'
tokens: tokens:
- type: error - type: i64
value: 'Not an identifier: numeric literal.' value: 123
operations:
- function: push
type: i64
value: 123
stack_final:
- type: i64
value: 123
- name: Identifier Literal Empty - name: Identifier Literal Empty
code: '::' code: '::'
tokens: tokens:
- type: error - type: error
value: 'Invalid identifier literal: empty identifier after ''::''.' value: 'Unexpected character: unexpected '':'' during parsing.'
- name: Identifier Case Lower - name: Identifier Case Lower
code: variable code: variable
tokens: tokens:
@ -3337,30 +3301,6 @@
stack_final: stack_final:
- type: identifier - type: identifier
value: VariableName value: VariableName
- name: Identifier Reserved Word true
code: 'true'
tokens:
- type: identifier
value: 'true'
operations:
- function: push
type: identifier
value: 'true'
stack_final:
- type: identifier
value: 'true'
- name: Identifier Reserved Word false
code: 'false'
tokens:
- type: identifier
value: 'false'
operations:
- function: push
type: identifier
value: 'false'
stack_final:
- type: identifier
value: 'false'
- name: Identifier Reserved Word if - name: Identifier Reserved Word if
code: if code: if
tokens: tokens:

View File

@ -3,7 +3,7 @@ from .general_tests import GeneralTestGenerator
from .integer_tests import IntegerTestGenerator from .integer_tests import IntegerTestGenerator
from .float_tests import FloatTestGenerator from .float_tests import FloatTestGenerator
from .char_tests import CharTestGenerator from .char_tests import CharTestGenerator
from .string_tests import StringTestGenerator # from .string_tests import StringTestGenerator
from .idents_and_bools_tests import IdentifierTestGenerator, BooleanTestGenerator from .idents_and_bools_tests import IdentifierTestGenerator, BooleanTestGenerator
__all__ = [ __all__ = [
@ -12,7 +12,7 @@ __all__ = [
"IntegerTestGenerator", "IntegerTestGenerator",
"FloatTestGenerator", "FloatTestGenerator",
"CharTestGenerator", "CharTestGenerator",
"StringTestGenerator", # "StringTestGenerator",
"IdentifierTestGenerator", "IdentifierTestGenerator",
"BooleanTestGenerator", "BooleanTestGenerator",
] ]

View File

@ -7,7 +7,7 @@ class IdentifierTestGenerator(BaseTestGenerator):
# Reserved words that might be operators or keywords # Reserved words that might be operators or keywords
RESERVED_WORDS = [ RESERVED_WORDS = [
'true', 'false', 'if', 'while', 'for', 'match', 'break', 'continue', 'if', 'while', 'for', 'match', 'break', 'continue',
'fn', 'struct', 'union', 'enum', 'trait', 'impl', 'inher', 'fn', 'struct', 'union', 'enum', 'trait', 'impl', 'inher',
'dup', 'drop', 'swap', 'over', 'rot', 'pick', 'roll', 'depth', 'dup', 'drop', 'swap', 'over', 'rot', 'pick', 'roll', 'depth',
] ]
@ -66,7 +66,7 @@ class IdentifierTestGenerator(BaseTestGenerator):
# Others # Others
self.make_success_test("Identifier With Dash", "my-var", self.make_success_test("Identifier With Dash", "my-var",
"identifier_literal", "my-var") "identifier", "my-var")
def generate_identifier_literal_tests(self): def generate_identifier_literal_tests(self):
"""Generate identifier literal tests (with :: prefix).""" """Generate identifier literal tests (with :: prefix)."""
@ -153,17 +153,12 @@ class IdentifierTestGenerator(BaseTestGenerator):
"Invalid decimal literal: unexpected 'a' in decimal integer.") "Invalid decimal literal: unexpected 'a' in decimal integer.")
# Invalid characters # Invalid characters
self.make_error_test("Identifier With Octothorpe", self.make_success_test("Identifier With Octothorpe", "my#var",
"my#var", "identifier", "my")
"Invalid identifier: '#' is not allowed in identifiers.")
self.make_error_test("Identifier With Dot", # self.make_error_test("Identifier With Space",
"my.var", # "my var",
"Invalid identifier: '.' is not allowed in identifiers.") # "Invalid identifier: whitespace not allowed in identifiers.")
self.make_error_test("Identifier With Space",
"my var",
"Invalid identifier: whitespace not allowed in identifiers.")
self.make_error_test("Identifier With Colon", self.make_error_test("Identifier With Colon",
"my:var", "my:var",
@ -172,52 +167,50 @@ class IdentifierTestGenerator(BaseTestGenerator):
# Note: :: is allowed only as prefix for identifier literals # Note: :: is allowed only as prefix for identifier literals
self.make_error_test("Identifier Double Colon Inside", self.make_error_test("Identifier Double Colon Inside",
"my::var", "my::var",
"Invalid identifier: '::' only allowed as prefix for identifier literals.") "Invalid identifier: ':' is not allowed in identifiers.")
# Special characters # Special characters
self.make_error_test("Identifier With At", # self.make_error_test("Identifier With At",
"@variable", # "@variable",
"Invalid identifier: '@' is not allowed in identifiers.") # "Invalid identifier: '@' is not allowed in identifiers.")
self.make_error_test("Identifier With Dollar", # self.make_error_test("Identifier With Dollar",
"$variable", # "$variable",
"Invalid identifier: '$' is not allowed in identifiers.") # "Invalid identifier: '$' is not allowed in identifiers.")
self.make_error_test("Identifier With Percent", # self.make_error_test("Identifier With Percent",
"%variable", # "%variable",
"Invalid identifier: '%' is not allowed in identifiers.") # "Invalid identifier: '%' is not allowed in identifiers.")
# Brackets not allowed # Brackets not allowed
self.make_error_test("Identifier With Brackets", # self.make_error_test("Identifier With Brackets",
"my[var]", # "my[var]",
"Invalid identifier: brackets not allowed in identifiers.") # "Invalid identifier: brackets not allowed in identifiers.")
self.make_error_test("Identifier With Braces", # self.make_error_test("Identifier With Braces",
"my{var}", # "my{var}",
"Invalid identifier: braces not allowed in identifiers.") # "Invalid identifier: braces not allowed in identifiers.")
self.make_error_test("Identifier With Parens", # self.make_error_test("Identifier With Parens",
"my(var)", # "my(var)",
"Invalid identifier: parentheses not allowed in identifiers.") # "Invalid identifier: parentheses not allowed in identifiers.")
# Quotes not allowed # Quotes not allowed
self.make_error_test("Identifier With Single Quote", # self.make_error_test("Identifier With Single Quote",
"my'var", # "my'var",
"Invalid identifier: quotes not allowed in identifiers.") # "Invalid identifier: quotes not allowed in identifiers.")
self.make_error_test("Identifier With Double Quote", # self.make_error_test("Identifier With Double Quote",
'my"var', # 'my"var',
"Invalid identifier: quotes not allowed in identifiers.") # "Invalid identifier: quotes not allowed in identifiers.")
# Only numbers (not valid identifier) # Only numbers (not valid identifier)
self.make_error_test("Identifier Only Numbers", self.make_success_test("Identifier Only Numbers", "123", "i64", 123)
"123",
"Not an identifier: numeric literal.")
# Empty identifier literal # Empty identifier literal
self.make_error_test("Identifier Literal Empty", self.make_error_test("Identifier Literal Empty",
"::", "::",
"Invalid identifier literal: empty identifier after '::'.") "Unexpected character: unexpected ':' during parsing.")
def generate_case_sensitivity_tests(self): def generate_case_sensitivity_tests(self):
"""Generate tests showing case sensitivity.""" """Generate tests showing case sensitivity."""