KiCad PCB EDA Suite
pcb_expr_evaluator.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 #ifndef __PCB_EXPR_EVALUATOR_H
26 #define __PCB_EXPR_EVALUATOR_H
27 
28 #include <unordered_map>
29 
30 #include <property.h>
31 #include <property_mgr.h>
32 
34 
35 class BOARD;
36 class BOARD_ITEM;
37 
38 class PCB_EXPR_VAR_REF;
39 
40 class PCB_EXPR_UCODE final : public LIBEVAL::UCODE
41 {
42 public:
44  virtual ~PCB_EXPR_UCODE() {};
45 
46  virtual std::unique_ptr<LIBEVAL::VAR_REF> CreateVarRef( const wxString& aVar,
47  const wxString& aField ) override;
48  virtual LIBEVAL::FUNC_CALL_REF CreateFuncCall( const wxString& aName ) override;
49 };
50 
51 
53 {
54 public:
55  PCB_EXPR_CONTEXT( int aConstraint, PCB_LAYER_ID aLayer ) :
56  m_constraint( aConstraint ),
57  m_layer( aLayer )
58  {
59  m_items[0] = nullptr;
60  m_items[1] = nullptr;
61  }
62 
63  void SetItems( BOARD_ITEM* a, BOARD_ITEM* b = nullptr )
64  {
65  m_items[0] = a;
66  m_items[1] = b;
67  }
68 
69  BOARD* GetBoard() const;
70 
71  int GetConstraint() const { return m_constraint; }
72  BOARD_ITEM* GetItem( int index ) const { return m_items[index]; }
73  PCB_LAYER_ID GetLayer() const { return m_layer; }
74 
75 private:
79 };
80 
81 
83 {
84 public:
85  PCB_EXPR_VAR_REF( int aItemIndex ) :
86  m_itemIndex( aItemIndex ),
88  m_isEnum( false )
89  {
90  //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
91  }
92 
94 
95  void SetIsEnum( bool s ) { m_isEnum = s; }
96  bool IsEnum() const { return m_isEnum; }
97 
98  void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; }
99  LIBEVAL::VAR_TYPE_T GetType() const override { return m_type; }
100 
101  void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop )
102  {
103  m_matchingTypes[type_hash] = prop;
104  }
105 
106  virtual LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
107 
108  BOARD_ITEM* GetObject( const LIBEVAL::CONTEXT* aCtx ) const;
109 
110 private:
111  std::unordered_map<TYPE_ID, PROPERTY_BASE*> m_matchingTypes;
114  bool m_isEnum;
115 };
116 
117 
118 // "Object code" version of a netclass reference (for performance).
120 {
121 public:
122  PCB_EXPR_NETCLASS_REF( int aItemIndex ) :
123  PCB_EXPR_VAR_REF( aItemIndex )
124  {
126  //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
127  }
128 
129  LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
130 };
131 
132 
133 // "Object code" version of a netname reference (for performance).
135 {
136 public:
137  PCB_EXPR_NETNAME_REF( int aItemIndex ) :
138  PCB_EXPR_VAR_REF( aItemIndex )
139  {
141  //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
142  }
143 
144  LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
145 };
146 
147 
149 {
150 public:
151  PCB_EXPR_TYPE_REF( int aItemIndex ) :
152  PCB_EXPR_VAR_REF( aItemIndex )
153  {
155  //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
156  }
157 
158  LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx ) override;
159 };
160 
161 
163 {
164 public:
166 
168  {
169  static PCB_EXPR_BUILTIN_FUNCTIONS self;
170  return self;
171  }
172 
173  LIBEVAL::FUNC_CALL_REF Get( const wxString& name )
174  {
175  return m_funcs[ name ];
176  }
177 
178  const wxArrayString GetSignatures() const
179  {
180  return m_funcSigs;
181  }
182 
183  void RegisterFunc( const wxString& funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr )
184  {
185  wxString funcName = funcSignature.BeforeFirst( '(' );
186  m_funcs[std::string( funcName.Lower() )] = std::move( funcPtr );
187  m_funcSigs.Add( funcSignature );
188  }
189 
190  void RegisterAllFunctions();
191 
192 private:
193  std::map<wxString, LIBEVAL::FUNC_CALL_REF> m_funcs;
194 
195  wxArrayString m_funcSigs;
196 };
197 
198 
200 {
201 public:
203 };
204 
205 
207 {
208 public:
211 
212  bool Evaluate( const wxString& aExpr );
213  int Result() const { return m_result; }
214 
215  void SetErrorCallback( std::function<void( const wxString& aMessage, int aOffset )> aCallback )
216  {
217  m_compiler.SetErrorCallback( aCallback );
218  }
219 
220  bool IsErrorPending() const { return m_errorStatus.pendingError; }
221  const LIBEVAL::ERROR_STATUS& GetError() const { return m_errorStatus; }
222 
223 private:
224  int m_result;
225 
229 };
230 
231 #endif
bool IsErrorPending() const
BOARD_ITEM * GetItem(int index) const
void SetItems(BOARD_ITEM *a, BOARD_ITEM *b=nullptr)
const wxArrayString GetSignatures() const
void SetErrorCallback(std::function< void(const wxString &aMessage, int aOffset)> aCallback)
const LIBEVAL::ERROR_STATUS & GetError() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
virtual LIBEVAL::FUNC_CALL_REF CreateFuncCall(const wxString &aName) override
size_t TYPE_ID
Unique type identifier.
Definition: property_mgr.h:42
void RegisterFunc(const wxString &funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr)
PCB_EXPR_UCODE m_ucode
LIBEVAL::FUNC_CALL_REF Get(const wxString &name)
BOARD * GetBoard() const
void SetIsEnum(bool s)
std::map< wxString, LIBEVAL::FUNC_CALL_REF > m_funcs
PCB_EXPR_CONTEXT(int aConstraint, PCB_LAYER_ID aLayer)
PCB_EXPR_NETNAME_REF(int aItemIndex)
PCB_EXPR_COMPILER m_compiler
std::function< void(CONTEXT *, void *)> FUNC_CALL_REF
LIBEVAL::VAR_TYPE_T m_type
virtual std::unique_ptr< LIBEVAL::VAR_REF > CreateVarRef(const wxString &aVar, const wxString &aField) override
void SetType(LIBEVAL::VAR_TYPE_T type)
BOARD_ITEM * m_items[2]
PCB_EXPR_NETCLASS_REF(int aItemIndex)
PCB_LAYER_ID m_layer
PCB_EXPR_VAR_REF(int aItemIndex)
LIBEVAL::ERROR_STATUS m_errorStatus
LIBEVAL::VALUE GetValue(LIBEVAL::CONTEXT *aCtx) override
virtual LIBEVAL::VALUE GetValue(LIBEVAL::CONTEXT *aCtx) override
void AddAllowedClass(TYPE_ID type_hash, PROPERTY_BASE *prop)
const char * name
Definition: DXF_plotter.cpp:56
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:191
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
bool Evaluate(const wxString &aExpr)
virtual ~PCB_EXPR_UCODE()
int GetConstraint() const
LIBEVAL::VALUE GetValue(LIBEVAL::CONTEXT *aCtx) override
PCB_EXPR_TYPE_REF(int aItemIndex)
void SetErrorCallback(std::function< void(const wxString &aMessage, int aOffset)> aCallback)
BOARD_ITEM * GetObject(const LIBEVAL::CONTEXT *aCtx) const
PCB_LAYER_ID GetLayer() const
std::unordered_map< TYPE_ID, PROPERTY_BASE * > m_matchingTypes
static PCB_EXPR_BUILTIN_FUNCTIONS & Instance()
LIBEVAL::VAR_TYPE_T GetType() const override
LIBEVAL::VALUE GetValue(LIBEVAL::CONTEXT *aCtx) override