Skip to content

Commit

Permalink
Merge pull request #77176 from andrei8l/math_parser-error
Browse files Browse the repository at this point in the history
eoc/math: show JSON context for math errors
  • Loading branch information
Night-Pryanik authored Oct 20, 2024
2 parents 1c35f90 + 63512d0 commit 74e77cc
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 21 deletions.
24 changes: 16 additions & 8 deletions src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,16 @@ static const json_character_flag json_flag_MUTATION_THRESHOLD( "MUTATION_THRESHO
namespace
{
struct deferred_math {
JsonObject jo;
std::string str;
bool assignment;
std::shared_ptr<math_exp> exp;

deferred_math( std::string_view str_, bool ass_ ) : str( str_ ), assignment( ass_ ),
exp( std::make_shared<math_exp>() ) {}
deferred_math( JsonObject const &jo_, std::string_view str_, bool ass_ )
: jo( jo_ ), str( str_ ), assignment( ass_ ), exp( std::make_shared<math_exp>() ) {

jo.allow_omitted_members();
}
};

struct condition_parser {
Expand Down Expand Up @@ -146,9 +150,9 @@ std::queue<deferred_math> &get_deferred_math()
return dfr_math;
}

std::shared_ptr<math_exp> &defer_math( std::string_view str, bool ass )
std::shared_ptr<math_exp> &defer_math( JsonObject const &jo, std::string_view str, bool ass )
{
get_deferred_math().emplace( str, ass );
get_deferred_math().emplace( jo, str, ass );
return get_deferred_math().back().exp;
}

Expand Down Expand Up @@ -574,7 +578,11 @@ void finalize_conditions()
std::queue<deferred_math> &dfr = get_deferred_math();
while( !dfr.empty() ) {
deferred_math &math = dfr.front();
math.exp->parse( math.str, math.assignment );
try {
math.exp->parse( math.str, math.assignment, false );
} catch( std::invalid_argument const &ex ) {
math.jo.throw_error_at( "math", ex.what() );
}
dfr.pop();
}
}
Expand Down Expand Up @@ -2411,7 +2419,7 @@ void eoc_math::from_json( const JsonObject &jo, std::string_view member, type_t
return;
}
} else if( objects.size() == 3 ) {
rhs = defer_math( objects.get_string( 2 ), false );
rhs = defer_math( jo, objects.get_string( 2 ), false );
if( oper == "=" ) {
action = oper::assign;
} else if( oper == "+=" ) {
Expand Down Expand Up @@ -2443,9 +2451,9 @@ void eoc_math::from_json( const JsonObject &jo, std::string_view member, type_t
}
_validate_type( objects, type_ );
bool const lhs_assign = action >= oper::assign && action <= oper::decrease;
lhs = defer_math( objects.get_string( 0 ), lhs_assign );
lhs = defer_math( jo, objects.get_string( 0 ), lhs_assign );
if( action >= oper::plus_assign && action <= oper::decrease ) {
mhs = defer_math( objects.get_string( 0 ), false );
mhs = defer_math( jo, objects.get_string( 0 ), false );
}
}

Expand Down
29 changes: 17 additions & 12 deletions src/math_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ class math_exp::math_exp_impl
math_exp_impl() = default;
explicit math_exp_impl( thingie &&t ): tree( t ) {}

bool parse( std::string_view str, bool assignment ) {
bool parse( std::string_view str, bool assignment, bool handle_errors ) {
if( str.empty() ) {
return false;
}
Expand All @@ -283,12 +283,16 @@ class math_exp::math_exp_impl
try {
_parse( str, assignment );
} catch( std::invalid_argument const &ex ) {
error( str, ex.what() );
ops = {};
output = {};
arity = {};
tree = thingie { 0.0 };
return false;
if( handle_errors ) {
debugmsg( error( str, ex.what() ) );
ops = {};
output = {};
arity = {};
tree = thingie { 0.0 };
return false;
}

throw std::invalid_argument( error( str, ex.what() ) );
}
return true;
}
Expand Down Expand Up @@ -357,7 +361,7 @@ class math_exp::math_exp_impl
void new_ternary( thingie &lhs, thingie &rhs );
void new_array();
void maybe_first_argument();
void error( std::string_view str, std::string_view what );
std::string error( std::string_view str, std::string_view what );
void validate_string( std::string_view str, std::string_view label, std::string_view badlist );
static std::vector<diag_value> _get_diag_vals( std::vector<thingie> &params );
static diag_value _get_diag_value( thingie &param );
Expand Down Expand Up @@ -796,7 +800,7 @@ void math_exp::math_exp_impl::new_var( std::string_view str )
output.emplace( std::in_place_type_t<var>(), type, "npctalk_var_" + std::string{ scoped } );
}

void math_exp::math_exp_impl::error( std::string_view str, std::string_view what )
std::string math_exp::math_exp_impl::error( std::string_view str, std::string_view what )
{
std::ptrdiff_t offset =
std::max<std::ptrdiff_t>( 0, last_token.data() - str.data() );
Expand All @@ -815,7 +819,8 @@ void math_exp::math_exp_impl::error( std::string_view str, std::string_view what
}

offset = std::max<std::ptrdiff_t>( 0, offset - 1 );
debugmsg( "%s\n\n%.80s\n%*s▲▲▲\n", mess, str, offset, " " );
// NOLINTNEXTLINE(cata-translate-string-literal): debug message
return string_format( "\n%s\n\n%.80s\n%*s▲▲▲\n", mess, str, offset, " " );
}

void math_exp::math_exp_impl::validate_string( std::string_view str, std::string_view label,
Expand All @@ -835,10 +840,10 @@ math_exp::math_exp( math_exp_impl impl_ )
{
}

bool math_exp::parse( std::string_view str, bool assignment )
bool math_exp::parse( std::string_view str, bool assignment, bool handle_errors )
{
impl = std::make_unique<math_exp_impl>();
return impl->parse( str, assignment );
return impl->parse( str, assignment, handle_errors );
}

math_exp::math_exp( math_exp const &other ) :
Expand Down
2 changes: 1 addition & 1 deletion src/math_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class math_exp
math_exp &operator=( math_exp &&/* other */ ) noexcept;
explicit math_exp( math_exp_impl impl_ );

bool parse( std::string_view str, bool assignment = false );
bool parse( std::string_view str, bool assignment = false, bool handle_errors = true );
double eval( dialogue &d ) const;
void assign( dialogue &d, double val ) const;

Expand Down

0 comments on commit 74e77cc

Please sign in to comment.