Skip to content

Commit

Permalink
Error message: Undeclared identifier
Browse files Browse the repository at this point in the history
When an expression is expected and an undeclared symbol follows or comes instead, then this unknown symbol is most probably an undeclared identifier, Complain with a hand-crafted error message.
  • Loading branch information
fernewelten committed Aug 30, 2024
1 parent 12ab4ae commit fdc4101
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Compiler/script2/cs_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3890,6 +3890,14 @@ void AGS::Parser::ParseExpression(SrcList &src, EvaluationResult &eres)
size_t const expr_start = src.GetCursor();
SkipToEndOfExpression(src);
SrcList expression = SrcList(src, expr_start, src.GetCursor() - expr_start);
Symbol potential_ident = src.PeekNext();
if (_sym.IsIdentifier(potential_ident) &&
!_sym.IsPredefined(potential_ident) &&
_sym.kNoSrcLocation == _sym.GetDeclared(potential_ident))
{
UserError("Identifier '%s' is undeclared", _sym.GetName(potential_ident).c_str());
}

if (0u == expression.Length())
UserError("Expected an expression, found '%s' instead", _sym.GetName(src.GetNext()).c_str());

Expand Down
63 changes: 63 additions & 0 deletions Compiler/test2/cc_parser_test_1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2696,3 +2696,66 @@ TEST_F(Compile1, DynarrayOfArray) {
int compileResult = cc_compile(inpl, scrip);
ASSERT_STRNE("Ok", (compileResult >= 0) ? "Ok" : last_seen_cc_error());
}

TEST_F(Compile1, IdentUnknownMessage1)
{
// When an unknown identifier comes up after an expression,
// complain about that with a specific error message.

char const *inpl = "\
int foo () \n\
{ \n\
int i; \n\
while (i < Holzschuh) \n\
{} \n\
} \n\
";

int compile_result = cc_compile(inpl, scrip);
std::string msg = last_seen_cc_error();
ASSERT_STRNE("Ok", (compile_result >= 0) ? "Ok" : msg.c_str());
EXPECT_NE(std::string::npos, msg.find("'Holzschuh'"));
EXPECT_NE(std::string::npos, msg.find("undeclared"));
}

TEST_F(Compile1, IdentUnknownMessage2)
{
// When an unknown identifier comes up when an expression is expected,
// complain about that with a specific error message.

char const *inpl = "\
int foo () \n\
{ \n\
int i; \n\
if (Holzschuh) \n\
{} \n\
} \n\
";

int compile_result = cc_compile(inpl, scrip);
std::string msg = last_seen_cc_error();
ASSERT_STRNE("Ok", (compile_result >= 0) ? "Ok" : msg.c_str());
EXPECT_NE(std::string::npos, msg.find("'Holzschuh'"));
EXPECT_NE(std::string::npos, msg.find("undeclared"));
}

TEST_F(Compile1, ExpressionNotFoundMessage2)
{
// When others come up when an expression is expected,
// complain about that

char const *inpl = "\
int foo () \n\
{ \n\
int i; \n\
if (do) \n\
{} \n\
} \n\
";

int compile_result = cc_compile(inpl, scrip);
std::string msg = last_seen_cc_error();
ASSERT_STRNE("Ok", (compile_result >= 0) ? "Ok" : msg.c_str());
EXPECT_NE(std::string::npos, msg.find("an expression"));
EXPECT_NE(std::string::npos, msg.find("'do'"));
}

0 comments on commit fdc4101

Please sign in to comment.