Add expression eval to constraint min/max/opt values.

Also adds error reporting for above.
This commit is contained in:
Jeff Young 2020-07-21 16:49:55 +01:00
parent 7cbd166df7
commit c52df811ae
6 changed files with 48 additions and 34 deletions

View File

@ -262,7 +262,7 @@ void PANEL_SETUP_RULES::OnSyntaxHelp( wxHyperlinkEvent& aEvent )
" (condition \"A.netclass == 'HV'\"))\r"
"\r"
"(rule HV_HV\r"
" (constraint clearance (min 2.0mm))\r"
" (constraint clearance (min \"1.5mm + 2.0mm\"))\r"
" (condition \"A.netclass == 'HV' && B.netclass == 'HV'\"))\r"
"</pre>";

View File

@ -27,6 +27,7 @@
#include <drc_rules_lexer.h>
#include <class_board.h>
#include <class_board_item.h>
#include <pcb_expr_evaluator.h>
using namespace DRCRULE_T;
@ -195,7 +196,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
{
case T_min:
NextTok();
value = parseValue( token );
parseValueWithUnits( FromUTF8(), value );
switch( constraintType )
{
@ -210,7 +211,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
case T_max:
NextTok();
value = parseValue( token );
parseValueWithUnits( FromUTF8(), value );
switch( constraintType )
{
@ -224,7 +225,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
case T_opt:
NextTok();
value = parseValue( token );
parseValueWithUnits( FromUTF8(), value );
switch( constraintType )
{
@ -243,7 +244,18 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
}
int DRC_RULES_PARSER::parseValue( DRCRULE_T::T aToken )
void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult )
{
return (int) ValueFromString( EDA_UNITS::MILLIMETRES, CurText(), true );
}
PCB_EXPR_EVALUATOR evaluator;
bool ok = evaluator.Evaluate( aExpr );
if( !ok )
{
LIBEVAL::ERROR_STATUS error = evaluator.GetErrorStatus();
THROW_PARSE_ERROR( error.message, CurSource(), CurLine(), CurLineNumber(),
CurOffset() + error.srcPos );
}
aResult = evaluator.Result();
};

View File

@ -51,7 +51,7 @@ private:
DRC_RULE* parseDRC_RULE();
void parseConstraint( DRC_RULE* aRule );
int parseValue( DRCRULE_T::T aToken );
void parseValueWithUnits( const wxString& aExpr, int& aResult );
private:
BOARD* m_board;

View File

@ -24,6 +24,7 @@
#include <cstdio>
#include <boost/algorithm/string/case_conv.hpp>
#include <memory>
#include "class_board.h"
#include "pcb_expr_evaluator.h"
@ -249,13 +250,14 @@ public:
PCB_EXPR_COMPILER::PCB_EXPR_COMPILER()
{
m_unitResolver.reset( new PCB_UNIT_RESOLVER );
m_unitResolver = std::make_unique<PCB_UNIT_RESOLVER>();
}
PCB_EXPR_EVALUATOR::PCB_EXPR_EVALUATOR()
{
m_error = false;
m_result = NAN;
m_errorStatus.pendingError = false;
}
PCB_EXPR_EVALUATOR::~PCB_EXPR_EVALUATOR()
@ -266,10 +268,15 @@ PCB_EXPR_EVALUATOR::~PCB_EXPR_EVALUATOR()
bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
{
PCB_EXPR_UCODE ucode;
if( !m_compiler.Compile( (const char*) aExpr.c_str(), &ucode ) )
return false;
auto result = ucode.Run();
if( !m_compiler.Compile( (const char*) aExpr.c_str(), &ucode ) )
{
m_errorStatus = m_compiler.GetErrorStatus();
return false;
}
// fixme: handle error conditions
LIBEVAL::VALUE* result = ucode.Run();
if( result->GetType() == LIBEVAL::VT_NUMERIC )
m_result = KiROUND( result->AsDouble() );
@ -277,8 +284,3 @@ bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
return true;
}
wxString PCB_EXPR_EVALUATOR::GetErrorString()
{
wxString errMsg;
return errMsg;
}

View File

@ -118,14 +118,16 @@ public:
bool Evaluate( const wxString& aExpr );
int Result() const { return m_result; }
wxString GetErrorString();
LIBEVAL::ERROR_STATUS GetErrorStatus() { return m_errorStatus; }
private:
bool m_error;
int m_result;
PCB_EXPR_COMPILER m_compiler;
PCB_EXPR_UCODE m_ucode;
PCB_EXPR_COMPILER m_compiler;
PCB_EXPR_UCODE m_ucode;
LIBEVAL::ERROR_STATUS m_errorStatus;
};
#endif

View File

@ -156,7 +156,7 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
{
DRC_RULE* rule = new DRC_RULE();
T token = NextTok();
int val;
int value;
if( !IsSymbol( token ) )
Expecting( "rule name" );
@ -181,20 +181,20 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
case T_min:
NeedSYMBOL();
parseValueWithUnits ( FromUTF8(), val );
rule->m_Constraint.m_Value.SetMin( val );
parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_Value.SetMin( value );
break;
case T_opt:
NeedSYMBOL();
parseValueWithUnits ( FromUTF8(), val );
rule->m_Constraint.m_Value.SetOpt( val );
parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_Value.SetOpt( value );
break;
case T_max:
NeedSYMBOL();
parseValueWithUnits ( FromUTF8(), val );
rule->m_Constraint.m_Value.SetMax( val );
parseValueWithUnits( FromUTF8(), value );
rule->m_Constraint.m_Value.SetMax( value );
break;
case T_allow:
@ -246,12 +246,10 @@ void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aR
if( !ok )
{
auto err = evaluator.GetErrorString();
//printf( "eval error: '%s'\n", (const char*) err.c_str() );
// fixme: message
THROW_PARSE_ERROR( err, "", "", 0, 0 );
LIBEVAL::ERROR_STATUS error = evaluator.GetErrorStatus();
THROW_PARSE_ERROR( error.message, CurSource(), CurLine(), CurLineNumber(),
CurOffset() + error.srcPos );
}
aResult = evaluator.Result();
//printf("parseValueWithUnits: value %d\n", aResult );
};