Add expression eval to constraint min/max/opt values.
Also adds error reporting for above.
This commit is contained in:
parent
7cbd166df7
commit
c52df811ae
|
@ -262,7 +262,7 @@ void PANEL_SETUP_RULES::OnSyntaxHelp( wxHyperlinkEvent& aEvent )
|
||||||
" (condition \"A.netclass == 'HV'\"))\r"
|
" (condition \"A.netclass == 'HV'\"))\r"
|
||||||
"\r"
|
"\r"
|
||||||
"(rule HV_HV\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"
|
" (condition \"A.netclass == 'HV' && B.netclass == 'HV'\"))\r"
|
||||||
"</pre>";
|
"</pre>";
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <drc_rules_lexer.h>
|
#include <drc_rules_lexer.h>
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
#include <class_board_item.h>
|
#include <class_board_item.h>
|
||||||
|
#include <pcb_expr_evaluator.h>
|
||||||
|
|
||||||
using namespace DRCRULE_T;
|
using namespace DRCRULE_T;
|
||||||
|
|
||||||
|
@ -195,7 +196,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||||
{
|
{
|
||||||
case T_min:
|
case T_min:
|
||||||
NextTok();
|
NextTok();
|
||||||
value = parseValue( token );
|
parseValueWithUnits( FromUTF8(), value );
|
||||||
|
|
||||||
switch( constraintType )
|
switch( constraintType )
|
||||||
{
|
{
|
||||||
|
@ -210,7 +211,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||||
|
|
||||||
case T_max:
|
case T_max:
|
||||||
NextTok();
|
NextTok();
|
||||||
value = parseValue( token );
|
parseValueWithUnits( FromUTF8(), value );
|
||||||
|
|
||||||
switch( constraintType )
|
switch( constraintType )
|
||||||
{
|
{
|
||||||
|
@ -224,7 +225,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||||
|
|
||||||
case T_opt:
|
case T_opt:
|
||||||
NextTok();
|
NextTok();
|
||||||
value = parseValue( token );
|
parseValueWithUnits( FromUTF8(), value );
|
||||||
|
|
||||||
switch( constraintType )
|
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();
|
||||||
|
};
|
||||||
|
|
|
@ -51,7 +51,7 @@ private:
|
||||||
DRC_RULE* parseDRC_RULE();
|
DRC_RULE* parseDRC_RULE();
|
||||||
|
|
||||||
void parseConstraint( DRC_RULE* aRule );
|
void parseConstraint( DRC_RULE* aRule );
|
||||||
int parseValue( DRCRULE_T::T aToken );
|
void parseValueWithUnits( const wxString& aExpr, int& aResult );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
|
#include <memory>
|
||||||
#include "class_board.h"
|
#include "class_board.h"
|
||||||
#include "pcb_expr_evaluator.h"
|
#include "pcb_expr_evaluator.h"
|
||||||
|
|
||||||
|
@ -249,13 +250,14 @@ public:
|
||||||
|
|
||||||
PCB_EXPR_COMPILER::PCB_EXPR_COMPILER()
|
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()
|
PCB_EXPR_EVALUATOR::PCB_EXPR_EVALUATOR()
|
||||||
{
|
{
|
||||||
m_error = false;
|
m_result = NAN;
|
||||||
|
m_errorStatus.pendingError = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCB_EXPR_EVALUATOR::~PCB_EXPR_EVALUATOR()
|
PCB_EXPR_EVALUATOR::~PCB_EXPR_EVALUATOR()
|
||||||
|
@ -266,10 +268,15 @@ PCB_EXPR_EVALUATOR::~PCB_EXPR_EVALUATOR()
|
||||||
bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
|
bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
|
||||||
{
|
{
|
||||||
PCB_EXPR_UCODE ucode;
|
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 )
|
if( result->GetType() == LIBEVAL::VT_NUMERIC )
|
||||||
m_result = KiROUND( result->AsDouble() );
|
m_result = KiROUND( result->AsDouble() );
|
||||||
|
@ -277,8 +284,3 @@ bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString PCB_EXPR_EVALUATOR::GetErrorString()
|
|
||||||
{
|
|
||||||
wxString errMsg;
|
|
||||||
return errMsg;
|
|
||||||
}
|
|
||||||
|
|
|
@ -118,14 +118,16 @@ public:
|
||||||
|
|
||||||
bool Evaluate( const wxString& aExpr );
|
bool Evaluate( const wxString& aExpr );
|
||||||
int Result() const { return m_result; }
|
int Result() const { return m_result; }
|
||||||
wxString GetErrorString();
|
|
||||||
|
LIBEVAL::ERROR_STATUS GetErrorStatus() { return m_errorStatus; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_error;
|
|
||||||
int m_result;
|
int m_result;
|
||||||
|
|
||||||
PCB_EXPR_COMPILER m_compiler;
|
PCB_EXPR_COMPILER m_compiler;
|
||||||
PCB_EXPR_UCODE m_ucode;
|
PCB_EXPR_UCODE m_ucode;
|
||||||
|
|
||||||
|
LIBEVAL::ERROR_STATUS m_errorStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -156,7 +156,7 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
|
||||||
{
|
{
|
||||||
DRC_RULE* rule = new DRC_RULE();
|
DRC_RULE* rule = new DRC_RULE();
|
||||||
T token = NextTok();
|
T token = NextTok();
|
||||||
int val;
|
int value;
|
||||||
|
|
||||||
if( !IsSymbol( token ) )
|
if( !IsSymbol( token ) )
|
||||||
Expecting( "rule name" );
|
Expecting( "rule name" );
|
||||||
|
@ -181,20 +181,20 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
|
||||||
|
|
||||||
case T_min:
|
case T_min:
|
||||||
NeedSYMBOL();
|
NeedSYMBOL();
|
||||||
parseValueWithUnits ( FromUTF8(), val );
|
parseValueWithUnits( FromUTF8(), value );
|
||||||
rule->m_Constraint.m_Value.SetMin( val );
|
rule->m_Constraint.m_Value.SetMin( value );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_opt:
|
case T_opt:
|
||||||
NeedSYMBOL();
|
NeedSYMBOL();
|
||||||
parseValueWithUnits ( FromUTF8(), val );
|
parseValueWithUnits( FromUTF8(), value );
|
||||||
rule->m_Constraint.m_Value.SetOpt( val );
|
rule->m_Constraint.m_Value.SetOpt( value );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_max:
|
case T_max:
|
||||||
NeedSYMBOL();
|
NeedSYMBOL();
|
||||||
parseValueWithUnits ( FromUTF8(), val );
|
parseValueWithUnits( FromUTF8(), value );
|
||||||
rule->m_Constraint.m_Value.SetMax( val );
|
rule->m_Constraint.m_Value.SetMax( value );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_allow:
|
case T_allow:
|
||||||
|
@ -246,12 +246,10 @@ void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aR
|
||||||
|
|
||||||
if( !ok )
|
if( !ok )
|
||||||
{
|
{
|
||||||
auto err = evaluator.GetErrorString();
|
LIBEVAL::ERROR_STATUS error = evaluator.GetErrorStatus();
|
||||||
//printf( "eval error: '%s'\n", (const char*) err.c_str() );
|
THROW_PARSE_ERROR( error.message, CurSource(), CurLine(), CurLineNumber(),
|
||||||
// fixme: message
|
CurOffset() + error.srcPos );
|
||||||
THROW_PARSE_ERROR( err, "", "", 0, 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aResult = evaluator.Result();
|
aResult = evaluator.Result();
|
||||||
//printf("parseValueWithUnits: value %d\n", aResult );
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue