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.

231 lines
6.0 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 __PCB_EXPR_EVALUATOR_H
  24. #define __PCB_EXPR_EVALUATOR_H
  25. #include <unordered_map>
  26. #include <property.h>
  27. #include <property_mgr.h>
  28. #include <libeval_compiler/libeval_compiler.h>
  29. class BOARD;
  30. class BOARD_ITEM;
  31. class PCB_EXPR_VAR_REF;
  32. class PCB_EXPR_UCODE final : public LIBEVAL::UCODE
  33. {
  34. public:
  35. PCB_EXPR_UCODE() {};
  36. virtual ~PCB_EXPR_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 PCB_EXPR_CONTEXT : public LIBEVAL::CONTEXT
  42. {
  43. public:
  44. PCB_EXPR_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 PCB_EXPR_VAR_REF : public LIBEVAL::VAR_REF
  66. {
  67. public:
  68. PCB_EXPR_VAR_REF( int aItemIndex ) :
  69. m_itemIndex( aItemIndex ),
  70. m_type( LIBEVAL::VT_UNDEFINED ),
  71. m_isEnum( false )
  72. {
  73. //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
  74. }
  75. ~PCB_EXPR_VAR_REF() {};
  76. void SetIsEnum( bool s ) { m_isEnum = s; }
  77. bool IsEnum() const { return m_isEnum; }
  78. void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; }
  79. LIBEVAL::VAR_TYPE_T GetType() const override { return m_type; }
  80. void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop )
  81. {
  82. m_matchingTypes[type_hash] = prop;
  83. }
  84. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  85. BOARD_ITEM* GetObject( const LIBEVAL::CONTEXT* aCtx ) const;
  86. private:
  87. std::unordered_map<TYPE_ID, PROPERTY_BASE*> m_matchingTypes;
  88. int m_itemIndex;
  89. LIBEVAL::VAR_TYPE_T m_type;
  90. bool m_isEnum;
  91. };
  92. // "Object code" version of a netclass reference (for performance).
  93. class PCB_EXPR_NETCLASS_REF : public PCB_EXPR_VAR_REF
  94. {
  95. public:
  96. PCB_EXPR_NETCLASS_REF( int aItemIndex ) :
  97. PCB_EXPR_VAR_REF( aItemIndex )
  98. {
  99. SetType( LIBEVAL::VT_STRING );
  100. //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
  101. }
  102. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  103. };
  104. // "Object code" version of a netname reference (for performance).
  105. class PCB_EXPR_NETNAME_REF : public PCB_EXPR_VAR_REF
  106. {
  107. public:
  108. PCB_EXPR_NETNAME_REF( int aItemIndex ) :
  109. PCB_EXPR_VAR_REF( aItemIndex )
  110. {
  111. SetType( LIBEVAL::VT_STRING );
  112. //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
  113. }
  114. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  115. };
  116. class PCB_EXPR_TYPE_REF : public PCB_EXPR_VAR_REF
  117. {
  118. public:
  119. PCB_EXPR_TYPE_REF( int aItemIndex ) :
  120. PCB_EXPR_VAR_REF( aItemIndex )
  121. {
  122. SetType( LIBEVAL::VT_STRING );
  123. //printf("*** CreateVarRef %p %d\n", this, aItemIndex );
  124. }
  125. LIBEVAL::VALUE* GetValue( LIBEVAL::CONTEXT* aCtx ) override;
  126. };
  127. class PCB_EXPR_BUILTIN_FUNCTIONS
  128. {
  129. public:
  130. PCB_EXPR_BUILTIN_FUNCTIONS();
  131. static PCB_EXPR_BUILTIN_FUNCTIONS& Instance()
  132. {
  133. static PCB_EXPR_BUILTIN_FUNCTIONS self;
  134. return self;
  135. }
  136. LIBEVAL::FUNC_CALL_REF Get( const wxString& name )
  137. {
  138. return m_funcs[ name ];
  139. }
  140. const wxArrayString GetSignatures() const
  141. {
  142. return m_funcSigs;
  143. }
  144. void RegisterFunc( const wxString& funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr )
  145. {
  146. wxString funcName = funcSignature.BeforeFirst( '(' );
  147. m_funcs[std::string( funcName.Lower() )] = std::move( funcPtr );
  148. m_funcSigs.Add( funcSignature );
  149. }
  150. void RegisterAllFunctions();
  151. private:
  152. std::map<wxString, LIBEVAL::FUNC_CALL_REF> m_funcs;
  153. wxArrayString m_funcSigs;
  154. };
  155. class PCB_EXPR_COMPILER : public LIBEVAL::COMPILER
  156. {
  157. public:
  158. PCB_EXPR_COMPILER();
  159. };
  160. class PCB_EXPR_EVALUATOR
  161. {
  162. public:
  163. PCB_EXPR_EVALUATOR( );
  164. ~PCB_EXPR_EVALUATOR();
  165. bool Evaluate( const wxString& aExpr );
  166. int Result() const { return m_result; }
  167. void SetErrorCallback( std::function<void( const wxString& aMessage, int aOffset )> aCallback )
  168. {
  169. m_compiler.SetErrorCallback( aCallback );
  170. }
  171. bool IsErrorPending() const { return m_errorStatus.pendingError; }
  172. const LIBEVAL::ERROR_STATUS& GetError() const { return m_errorStatus; }
  173. private:
  174. int m_result;
  175. PCB_EXPR_COMPILER m_compiler;
  176. PCB_EXPR_UCODE m_ucode;
  177. LIBEVAL::ERROR_STATUS m_errorStatus;
  178. };
  179. #endif