You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
7.1 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The 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. #ifndef PCBEXPR_EVALUATOR_H
  24. #define PCBEXPR_EVALUATOR_H
  25. #include <unordered_map>
  26. #include <properties/property.h>
  27. #include <properties/property_mgr.h>
  28. #include <libeval_compiler/libeval_compiler.h>
  29. class BOARD;
  30. class BOARD_ITEM;
  31. class PCBEXPR_VAR_REF;
  32. class PCBEXPR_UCODE final : public LIBEVAL::UCODE
  33. {
  34. public:
  35. PCBEXPR_UCODE() {};
  36. virtual ~PCBEXPR_UCODE() {};
  37. virtual std::unique_ptr<LIBEVAL::VAR_REF> CreateVarRef( const wxString& aVar,
  38. const wxString& aField ) override;
  39. virtual LIBEVAL::FUNC_CALL_REF CreateFuncCall( const wxString& aName ) override;
  40. };
  41. class PCBEXPR_CONTEXT : public LIBEVAL::CONTEXT
  42. {
  43. public:
  44. PCBEXPR_CONTEXT( int aConstraint = 0, PCB_LAYER_ID aLayer = F_Cu ) :
  45. m_constraint( aConstraint ),
  46. m_layer( aLayer )
  47. {
  48. m_items[0] = nullptr;
  49. m_items[1] = nullptr;
  50. }
  51. void SetItems( BOARD_ITEM* a, BOARD_ITEM* b = nullptr )
  52. {
  53. m_items[0] = a;
  54. m_items[1] = b;
  55. }
  56. BOARD* GetBoard() const;
  57. int GetConstraint() const { return m_constraint; }
  58. BOARD_ITEM* GetItem( int index ) const { return m_items[index]; }
  59. PCB_LAYER_ID GetLayer() const { return m_layer; }
  60. private:
  61. int m_constraint;
  62. BOARD_ITEM* m_items[2];
  63. PCB_LAYER_ID m_layer;
  64. };
  65. class PCBEXPR_VAR_REF : public LIBEVAL::VAR_REF
  66. {
  67. public:
  68. PCBEXPR_VAR_REF( int aItemIndex ) :
  69. m_itemIndex( aItemIndex ),
  70. m_type( LIBEVAL::VT_UNDEFINED ),
  71. m_isEnum( false ),
  72. m_isOptional( false )
  73. {}
  74. ~PCBEXPR_VAR_REF() {};
  75. void SetIsEnum( bool s ) { m_isEnum = s; }
  76. bool IsEnum() const { return m_isEnum; }
  77. void SetIsOptional( bool s = true ) { m_isOptional = s; }
  78. bool IsOptional() const { return m_isOptional; }
  79. void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; }
  80. LIBEVAL::VAR_TYPE_T GetType() const override { return m_type; }
  81. void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop )
  82. {
  83. m_matchingTypes[type_hash] = prop;
  84. }
  85. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  86. BOARD_ITEM* GetObject( const LIBEVAL::CONTEXT* aCtx ) const;
  87. private:
  88. std::unordered_map<TYPE_ID, PROPERTY_BASE*> m_matchingTypes;
  89. int m_itemIndex;
  90. LIBEVAL::VAR_TYPE_T m_type;
  91. bool m_isEnum;
  92. bool m_isOptional;
  93. };
  94. // "Object code" version of a netclass reference (for performance).
  95. class PCBEXPR_NETCLASS_REF : public PCBEXPR_VAR_REF
  96. {
  97. public:
  98. PCBEXPR_NETCLASS_REF( int aItemIndex ) :
  99. PCBEXPR_VAR_REF( aItemIndex )
  100. {
  101. SetType( LIBEVAL::VT_STRING );
  102. }
  103. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  104. };
  105. // "Object code" version of a component class reference (for performance).
  106. class PCBEXPR_COMPONENT_CLASS_REF : public PCBEXPR_VAR_REF
  107. {
  108. public:
  109. PCBEXPR_COMPONENT_CLASS_REF( int aItemIndex ) : PCBEXPR_VAR_REF( aItemIndex )
  110. {
  111. SetType( LIBEVAL::VT_STRING );
  112. }
  113. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  114. };
  115. // "Object code" version of a netname reference (for performance).
  116. class PCBEXPR_NETNAME_REF : public PCBEXPR_VAR_REF
  117. {
  118. public:
  119. PCBEXPR_NETNAME_REF( int aItemIndex ) :
  120. PCBEXPR_VAR_REF( aItemIndex )
  121. {
  122. SetType( LIBEVAL::VT_STRING );
  123. }
  124. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  125. };
  126. class PCBEXPR_TYPE_REF : public PCBEXPR_VAR_REF
  127. {
  128. public:
  129. PCBEXPR_TYPE_REF( int aItemIndex ) :
  130. PCBEXPR_VAR_REF( aItemIndex )
  131. {
  132. SetType( LIBEVAL::VT_STRING );
  133. }
  134. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  135. };
  136. class PCBEXPR_BUILTIN_FUNCTIONS
  137. {
  138. public:
  139. PCBEXPR_BUILTIN_FUNCTIONS();
  140. static PCBEXPR_BUILTIN_FUNCTIONS& Instance()
  141. {
  142. static PCBEXPR_BUILTIN_FUNCTIONS self;
  143. return self;
  144. }
  145. LIBEVAL::FUNC_CALL_REF Get( const wxString& name )
  146. {
  147. return m_funcs[ name ];
  148. }
  149. const wxArrayString GetSignatures() const
  150. {
  151. return m_funcSigs;
  152. }
  153. void RegisterFunc( const wxString& funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr )
  154. {
  155. wxString funcName = funcSignature.BeforeFirst( '(' );
  156. m_funcs[std::string( funcName.Lower() )] = std::move( funcPtr );
  157. m_funcSigs.Add( funcSignature );
  158. }
  159. void RegisterAllFunctions();
  160. private:
  161. std::map<wxString, LIBEVAL::FUNC_CALL_REF> m_funcs;
  162. wxArrayString m_funcSigs;
  163. };
  164. class PCBEXPR_UNIT_RESOLVER : public LIBEVAL::UNIT_RESOLVER
  165. {
  166. public:
  167. const std::vector<wxString>& GetSupportedUnits() const override;
  168. const std::vector<EDA_UNITS>& GetSupportedUnitsTypes() const override;
  169. wxString GetSupportedUnitsMessage() const override;
  170. double Convert( const wxString& aString, int unitId ) const override;
  171. };
  172. class PCBEXPR_UNITLESS_RESOLVER : public LIBEVAL::UNIT_RESOLVER
  173. {
  174. public:
  175. const std::vector<wxString>& GetSupportedUnits() const override;
  176. const std::vector<EDA_UNITS>& GetSupportedUnitsTypes() const override;
  177. double Convert( const wxString& aString, int unitId ) const override;
  178. };
  179. class PCBEXPR_COMPILER : public LIBEVAL::COMPILER
  180. {
  181. public:
  182. PCBEXPR_COMPILER( LIBEVAL::UNIT_RESOLVER* aUnitResolver );
  183. };
  184. class PCBEXPR_EVALUATOR
  185. {
  186. public:
  187. PCBEXPR_EVALUATOR( LIBEVAL::UNIT_RESOLVER* aUnitResolver );
  188. ~PCBEXPR_EVALUATOR();
  189. bool Evaluate( const wxString& aExpr );
  190. int Result() const { return m_result; }
  191. EDA_UNITS Units() const { return m_units; }
  192. void SetErrorCallback( std::function<void( const wxString& aMessage, int aOffset )> aCallback )
  193. {
  194. m_compiler.SetErrorCallback( std::move( aCallback ) );
  195. }
  196. bool IsErrorPending() const { return m_errorStatus.pendingError; }
  197. const LIBEVAL::ERROR_STATUS& GetError() const { return m_errorStatus; }
  198. private:
  199. int m_result;
  200. EDA_UNITS m_units;
  201. PCBEXPR_COMPILER m_compiler;
  202. PCBEXPR_UCODE m_ucode;
  203. LIBEVAL::ERROR_STATUS m_errorStatus;
  204. };
  205. #endif