42 #pragma GCC diagnostic push 43 #pragma GCC diagnostic ignored "-Wunused-variable" 44 #pragma GCC diagnostic ignored "-Wsign-compare" 47 #include <libeval_compiler/grammar.c> 48 #include <libeval_compiler/grammar.h> 51 #pragma GCC diagnostic pop 55 #define libeval_dbg(level, fmt, ...) \ 56 wxLogTrace( "libeval_compiler", fmt, __VA_ARGS__ ); 64 t2->value.str = value.
str ?
new wxString( *value.
str ) :
nullptr;
65 t2->value.num = value.
num;
66 t2->value.idx = value.
idx;
68 t2->leaf[0] =
nullptr;
69 t2->leaf[1] =
nullptr;
70 t2->isTerminal =
false;
74 libeval_dbg(10,
" ostr %p nstr %p nnode %p op %d", value.
str, t2->value.str, t2, t2->op );
77 compiler->
GcItem( t2->value.str );
101 for(
int i = 0; simpleOps[i].op >= 0; i++ )
103 if( simpleOps[i].op == op )
104 return simpleOps[i].mnemonic;
207 while( p <
m_str.length() && cond(
m_str[p] ) )
209 rv.append( 1,
m_str[p] );
217 const std::function<
bool( wxUniChar )>& stopCond )
const 221 if( remaining < (
int) match.length() )
224 if(
m_str.substr(
m_pos, match.length() ) == match )
225 return ( remaining == (
int) match.length() || stopCond(
m_str[
m_pos + match.length()] ) );
232 m_lexerState(
COMPILER::LS_DEFAULT )
238 m_parser = LIBEVAL::ParseAlloc( malloc );
246 LIBEVAL::ParseFree(
m_parser, free );
312 libeval_dbg(0,
"str: '%s' empty: %d\n", aString.c_str(), !!aString.empty() );
314 if( aString.empty() )
341 }
while( tok.
token );
384 aToken.
token = G_STRING;
385 aToken.
value.
str =
new wxString( str );
397 for(
const wxString& unitName :
m_unitResolver->GetSupportedUnits() )
401 libeval_dbg(10,
"Match unit '%s'\n", unitName.c_str() );
421 retval.
token = G_ENDS;
429 auto isDecimalSeparator =
430 [&]( wxUniChar ch ) ->
bool 439 bool haveSeparator =
false;
444 if( isDecimalSeparator( ch ) && haveSeparator )
447 current.append( 1, ch );
449 if( isDecimalSeparator( ch ) )
450 haveSeparator =
true;
454 }
while( isdigit( ch ) || isDecimalSeparator( ch ) );
457 for(
int i = current.length(); i; i-- )
459 if( isDecimalSeparator( current[i - 1] ) )
484 else if( isdigit( ch ) )
488 retval.
token = G_VALUE;
489 retval.
value.
str =
new wxString( current );
499 retval.
token = G_UNIT;
502 else if( ch ==
'\'' )
508 else if( isalpha( ch ) || ch ==
'_' )
510 current =
m_tokenizer.
GetChars( [](
int c ) ->
bool {
return isalnum( c ) || c ==
'_'; } );
511 retval.
token = G_IDENTIFIER;
512 retval.
value.
str =
new wxString( current );
517 retval.
token = G_EQUAL;
522 retval.
token = G_NOT_EQUAL;
527 retval.
token = G_LESS_EQUAL_THAN;
532 retval.
token = G_GREATER_EQUAL_THAN;
537 retval.
token = G_BOOL_AND;
542 retval.
token = G_BOOL_OR;
550 case '+': retval.
token = G_PLUS;
break;
551 case '!': retval.
token = G_BOOL_NOT;
break;
552 case '-': retval.
token = G_MINUS;
break;
553 case '*': retval.
token = G_MULT;
break;
554 case '/': retval.
token = G_DIVIDE;
break;
555 case '<': retval.
token = G_LESS_THAN;
break;
556 case '>': retval.
token = G_GREATER_THAN;
break;
557 case '(': retval.
token = G_PARENL;
break;
558 case ')': retval.
token = G_PARENR;
break;
559 case ';': retval.
token = G_SEMCOL;
break;
560 case '.': retval.
token = G_STRUCT_REF;
break;
561 case ',': retval.
token = G_COMMA;
break;
591 str.Printf(
"\n[%p L0:%-20p L1:%-20p] ", tok, tok->
leaf[0], tok->
leaf[1] );
594 for(
int i = 0; i < 2 * depth; i++ )
650 str.Printf(
"UNIT: %d ", tok->
value.
idx );
706 std::unique_ptr<VALUE> val = std::make_unique<VALUE>( aValue );
707 uop =
new UOP( aOp, std::move( val ) );
715 std::unique_ptr<VALUE> val = std::make_unique<VALUE>( aValue, aStringIsWildcard );
716 uop =
new UOP( aOp, std::move( val ) );
724 uop =
new UOP( aOp, std::move( aRef ) );
732 uop =
new UOP( aOp, std::move( aFunc ), std::move( aRef ) );
757 std::vector<TREE_NODE*> args;
766 args.push_back( root );
774 args.push_back(n->
leaf[1]);
785 std::reverse( args.begin(), args.end() );
787 for(
size_t i = 0; i < args.size(); i++ )
788 libeval_dbg(10,
"squash arg%d: %s\n",
int( i ), *args[i]->value.str );
796 std::vector<TREE_NODE*> stack;
801 std::unique_ptr<VALUE> val = std::make_unique<VALUE>( 1.0 );
809 stack.push_back(
m_tree );
816 while( !stack.empty() )
820 libeval_dbg( 4,
"process node %p [op %d] [stack %lu]\n",
821 node, node->
op, (
unsigned long)stack.size() );
847 pos -= static_cast<int>( node->
leaf[0]->
value.
str->length() );
859 switch( node->
leaf[1]->
op )
868 std::unique_ptr<VAR_REF> vref = aCode->
CreateVarRef( itemName, propName );
872 msg.Printf(
_(
"Unrecognized item '%s'" ), itemName );
877 msg.Printf(
_(
"Unrecognized property '%s'" ), propName );
896 std::unique_ptr<VAR_REF> vref = aCode->
CreateVarRef( itemName,
"" );
900 msg.Printf(
_(
"Unrecognized item '%s'" ), itemName );
908 libeval_dbg( 10,
"emit func call: %s\n", functionName );
912 msg.Printf(
_(
"Unrecognized function '%s'" ), functionName );
923 param->
Set( *pnode->value.str );
924 aPreflightContext->
Push( param );
928 [&](
const wxString& aMessage,
int aOffset )
936 func( aPreflightContext, vref.get() );
937 aPreflightContext->
Pop();
953 stack.push_back( node->
leaf[1] );
956 stack.push_back( pnode );
969 std::unique_ptr<VAR_REF> vref = aCode->
CreateVarRef( itemName, propName );
973 msg.Printf(
_(
"Unrecognized item '%s'" ), itemName );
977 msg.Printf(
_(
"Unrecognized property '%s'" ), propName );
1007 msg.Printf(
_(
"Missing units for '%s'| (%s)" ),
1023 bool isWildcard = str.Contains(
"?") || str.Contains(
"*");
1035 msg.Printf(
_(
"Unrecognized item '%s'" ), *node->
value.
str );
1055 stack.push_back( node->
leaf[0] );
1061 stack.push_back( node->
leaf[1] );
1073 node->
uop =
nullptr;
1092 value->
Set(
m_ref->GetValue( ctx ) );
1113 double arg2Value = arg2 ? arg2->
AsDouble() : 0.0;
1114 double arg1Value = arg1 ? arg1->
AsDouble() : 0.0;
1120 result = arg1Value + arg2Value;
1123 result = arg1Value - arg2Value;
1126 result = arg1Value * arg2Value;
1129 result = arg1Value / arg2Value;
1132 result = arg1Value <= arg2Value ? 1 : 0;
1135 result = arg1Value >= arg2Value ? 1 : 0;
1138 result = arg1Value < arg2Value ? 1 : 0;
1141 result = arg1Value > arg2Value ? 1 : 0;
1144 result = arg1 && arg2 && arg1->
EqualTo( arg2 ) ? 1 : 0;
1147 result = arg1 && arg2 && arg1->
NotEqualTo( arg2 ) ? 1 : 0;
1150 result = arg1Value != 0.0 && arg2Value != 0.0 ? 1 : 0;
1153 result = arg1Value != 0.0 || arg2Value != 0.0 ? 1 : 0;
1168 double arg1Value = arg1 ? arg1->
AsDouble() : 0.0;
1174 result = arg1Value != 0.0 ? 0 : 1;
1191 static VALUE g_false( 0 );
1204 if( ctx->
SP() == 1 )
1214 wxASSERT( ctx->
SP() == 1 );
void Restart(const wxString &aStr)
wxString GetChars(const std::function< bool(wxUniChar)> &cond) const
virtual FUNC_CALL_REF CreateFuncCall(const wxString &name)
bool generateUCode(UCODE *aCode, CONTEXT *aPreflightContext)
std::unique_ptr< UNIT_RESOLVER > m_unitResolver
std::vector< TREE_NODE * > m_gcItems
void freeTree(LIBEVAL::TREE_NODE *tree)
std::function< void(const wxString &aMessage, int aOffset)> m_errorCallback
std::unique_ptr< VALUE > m_value
void NextChar(int aAdvance=1)
#define TR_OP_BINARY_MASK
#define TR_OP_METHOD_CALL
void setRoot(LIBEVAL::TREE_NODE *root)
#define libeval_dbg(level, fmt,...)
#define TR_OP_GREATER_EQUAL
constexpr T_TOKEN defaultToken
bool MatchAhead(const wxString &match, const std::function< bool(wxUniChar)> &stopCond) const
bool lexString(T_TOKEN &aToken)
bool Compile(const wxString &aString, UCODE *aCode, CONTEXT *aPreflightContext)
void GcItem(TREE_NODE *aItem)
std::vector< wxString * > m_gcStrings
void SetErrorCallback(std::function< void(const wxString &aMessage, int aOffset)> aCallback)
void SetUop(int aOp, double aValue)
virtual std::unique_ptr< VAR_REF > CreateVarRef(const wxString &var, const wxString &field)
std::function< void(CONTEXT *, void *)> FUNC_CALL_REF
wxString dump(const wxArrayString &aArray)
Debug helper for printing wxArrayString contents.
static void prepareTree(LIBEVAL::TREE_NODE *node)
virtual bool EqualTo(const VALUE *b) const
bool WildCompareString(const wxString &pattern, const wxString &string_to_tst, bool case_sensitive)
Compare a string against wild card (* and ?) pattern using the usual rules.
char m_localeDecimalSeparator
ERROR_STATUS m_errorStatus
std::function< void(const wxString &aMessage, int aOffset)> m_errorCallback
void newString(const wxString &aString)
virtual bool NotEqualTo(const VALUE *b) const
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
static const wxString formatOpName(int op)
void ReportError(const wxString &aErrorMsg)
void reportError(COMPILATION_STAGE stage, const wxString &aErrorMsg, int aPos=-1)
virtual double AsDouble() const
TREE_NODE * newNode(LIBEVAL::COMPILER *compiler, int op, const T_TOKEN_VALUE &value)
ERROR_STATUS m_errorStatus
std::vector< UOP * > m_ucode
static std::vector< TREE_NODE * > squashParamList(TREE_NODE *root)
void parseError(const char *s)
bool lexDefault(T_TOKEN &aToken)
std::unique_ptr< VAR_REF > m_ref
VALUE * Run(CONTEXT *ctx)
const wxString formatNode(TREE_NODE *node)
double DoubleValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType)
Function DoubleValueFromString converts aTextValue to a double.
#define TR_UOP_PUSH_VALUE
void dumpNode(wxString &buf, TREE_NODE *tok, int depth=0)