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.

246 lines
6.3 KiB

  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. #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, PCB_LAYER_ID aLayer ) :
  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. {}
  73. ~PCBEXPR_VAR_REF() {};
  74. void SetIsEnum( bool s ) { m_isEnum = s; }
  75. bool IsEnum() const { return m_isEnum; }
  76. void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; }
  77. LIBEVAL::VAR_TYPE_T GetType() const override { return m_type; }
  78. void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop )
  79. {
  80. m_matchingTypes[type_hash] = prop;
  81. }
  82. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  83. BOARD_ITEM* GetObject( const LIBEVAL::CONTEXT* aCtx ) const;
  84. private:
  85. std::unordered_map<TYPE_ID, PROPERTY_BASE*> m_matchingTypes;
  86. int m_itemIndex;
  87. LIBEVAL::VAR_TYPE_T m_type;
  88. bool m_isEnum;
  89. };
  90. // "Object code" version of a netclass reference (for performance).
  91. class PCBEXPR_NETCLASS_REF : public PCBEXPR_VAR_REF
  92. {
  93. public:
  94. PCBEXPR_NETCLASS_REF( int aItemIndex ) :
  95. PCBEXPR_VAR_REF( aItemIndex )
  96. {
  97. SetType( LIBEVAL::VT_STRING );
  98. }
  99. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  100. };
  101. // "Object code" version of a netname reference (for performance).
  102. class PCBEXPR_NETNAME_REF : public PCBEXPR_VAR_REF
  103. {
  104. public:
  105. PCBEXPR_NETNAME_REF( int aItemIndex ) :
  106. PCBEXPR_VAR_REF( aItemIndex )
  107. {
  108. SetType( LIBEVAL::VT_STRING );
  109. }
  110. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  111. };
  112. class PCBEXPR_TYPE_REF : public PCBEXPR_VAR_REF
  113. {
  114. public:
  115. PCBEXPR_TYPE_REF( int aItemIndex ) :
  116. PCBEXPR_VAR_REF( aItemIndex )
  117. {
  118. SetType( LIBEVAL::VT_STRING );
  119. }
  120. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  121. };
  122. class PCBEXPR_BUILTIN_FUNCTIONS
  123. {
  124. public:
  125. PCBEXPR_BUILTIN_FUNCTIONS();
  126. static PCBEXPR_BUILTIN_FUNCTIONS& Instance()
  127. {
  128. static PCBEXPR_BUILTIN_FUNCTIONS self;
  129. return self;
  130. }
  131. LIBEVAL::FUNC_CALL_REF Get( const wxString& name )
  132. {
  133. return m_funcs[ name ];
  134. }
  135. const wxArrayString GetSignatures() const
  136. {
  137. return m_funcSigs;
  138. }
  139. void RegisterFunc( const wxString& funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr )
  140. {
  141. wxString funcName = funcSignature.BeforeFirst( '(' );
  142. m_funcs[std::string( funcName.Lower() )] = std::move( funcPtr );
  143. m_funcSigs.Add( funcSignature );
  144. }
  145. void RegisterAllFunctions();
  146. private:
  147. std::map<wxString, LIBEVAL::FUNC_CALL_REF> m_funcs;
  148. wxArrayString m_funcSigs;
  149. };
  150. class PCBEXPR_UNIT_RESOLVER : public LIBEVAL::UNIT_RESOLVER
  151. {
  152. public:
  153. const std::vector<wxString>& GetSupportedUnits() const override;
  154. wxString GetSupportedUnitsMessage() const override;
  155. double Convert( const wxString& aString, int unitId ) const override;
  156. };
  157. class PCBEXPR_UNITLESS_RESOLVER : public LIBEVAL::UNIT_RESOLVER
  158. {
  159. public:
  160. const std::vector<wxString>& GetSupportedUnits() const override;
  161. double Convert( const wxString& aString, int unitId ) const override;
  162. };
  163. class PCBEXPR_COMPILER : public LIBEVAL::COMPILER
  164. {
  165. public:
  166. PCBEXPR_COMPILER( LIBEVAL::UNIT_RESOLVER* aUnitResolver );
  167. };
  168. class PCBEXPR_EVALUATOR
  169. {
  170. public:
  171. PCBEXPR_EVALUATOR( LIBEVAL::UNIT_RESOLVER* aUnitResolver );
  172. ~PCBEXPR_EVALUATOR();
  173. bool Evaluate( const wxString& aExpr );
  174. int Result() const { return m_result; }
  175. void SetErrorCallback( std::function<void( const wxString& aMessage, int aOffset )> aCallback )
  176. {
  177. m_compiler.SetErrorCallback( aCallback );
  178. }
  179. bool IsErrorPending() const { return m_errorStatus.pendingError; }
  180. const LIBEVAL::ERROR_STATUS& GetError() const { return m_errorStatus; }
  181. private:
  182. int m_result;
  183. PCBEXPR_COMPILER m_compiler;
  184. PCBEXPR_UCODE m_ucode;
  185. LIBEVAL::ERROR_STATUS m_errorStatus;
  186. };
  187. #endif