KiCad PCB EDA Suite
am_param.h
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 1992-2017 Jean-Pierre Charras <jp.charras at wanadoo.fr>
9  * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
10  * Copyright (C) 1992-2021 KiCad Developers, see change_log.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 #ifndef _AM_PARAM_H_
31 #define _AM_PARAM_H_
32 
33 /*
34  * An aperture macro defines a complex shape and is a list of aperture primitives.
35  * Each aperture primitive defines a simple shape (circle, rect, regular polygon...)
36  * Inside a given aperture primitive, a fixed list of parameters defines info
37  * about the shape: size, thickness, number of vertex ...
38  *
39  * Each parameter can be an immediate value or a deferred value.
40  * When value is deferred, it is defined when the aperture macro is instanced by
41  * an ADD macro command
42  *
43  * Actual values of a parameter can also be the result of an arithmetic operation.
44  *
45  * Here is some examples:
46  * An immediate value:
47  * 3.5
48  * A deferred value:
49  * $2 means: replace me by the second value given in the ADD command
50  * Actual value as arithmetic calculation:
51  * $2/2+1
52  *
53  * Note also a defer ed parameter can be defined in aperture macro,
54  * but outside aperture primitives. Example
55  * %AMRECTHERM*
56  * $4=$3/2* parameter $4 is half value of parameter $3
57  * 21,1,$1-$3,$2-$3,0-$1/2-$4,0-$2/2-$4,0*
58  * For the aperture primitive, parameters $1 to $3 will be defined in ADD command,
59  * and $4 is defined inside the macro
60  *
61  * Some examples of aperture macro definition
62  * A simple definition, no parameters:
63  * %AMMOIRE10*
64  * 6,0,0,0.350000,0.005,0.050,3,0.005,0.400000,0.0*%
65  * Example of instantiation:
66  * %ADD19MOIRE10*%
67  *
68  * A simple definition, one parameter:
69  * %AMCIRCLE*
70  * 1,1,$1,0,0*
71  * Example of instantiation:
72  * %ADD11CIRCLE,.5*%
73  *
74  * A definition, with parameters and arithmetic operations:
75  * %AMVECTOR*
76  * 2,1,$1,0,0,$2+1,$3,-135*%
77  * Example of instantiation:
78  * %ADD12VECTOR,0.05X0X0*%
79  *
80  * A more complicated aperture macro definition, with parameters and arithmetic operations:
81  * %AMRNDREC*
82  * 0 this is a comment*
83  * 21,1,$1+$1,$2+$2-$3-$3,0,0,0*
84  * 21,1,$1+$1-$3-$3,$2+$2,0,0,0*
85  * 1,1,$3+$3,$1-$3,$2-$3*
86  * 1,1,$3+$3,$3-$1,$2-$3*
87  * 1,1,$3+$3,$1-$3,$3-$2*
88  * 1,1,$3+$3,$3-$1,$3-$2*%
89  * Example of instantiation:
90  *
91  * A more complicated sample of aperture macro definition:
92  * G04 Rectangular Thermal Macro, params: W/2, H/2, T/2 *
93  * %AMRECTHERM*
94  * $4=$3/2*
95  * 21,1,$1-$3,$2-$3,0-$1/2-$4,0-$2/2-$4,0*
96  * 21,1,$1-$3,$2-$3,0-$1/2-$4,$2/2+$4,0*
97  * 21,1,$1-$3,$2-$3,$1/2+$4,0-$2/2-$4,0*
98  * 21,1,$1-$3,$2-$3,$1/2+$4,$2/2+$4,0*%
99  * Example of instantiation:
100  * %ADD28RECTHERM,0.035591X0.041496X0.005000*%
101  */
102 
103 #include <vector>
104 
105 #include <dcode.h>
106 /*
107 Values of a parameter can be the result of an arithmetic operation,
108 between immediate values and deferred value.
109 From an idea found in Gerbv, here is the way to evaluate a parameter.
110 a AM_PARAM_ITEM holds info about operands and operators in a parameter definition
111 ( a AM_PARAM ) like $2+$2-$3-$3/2
112 
113 Precedence was recently actually defined in gerber RS274X
114 (Previously, there was no actual info about this precedence)
115 This is the usual arithmetic precedence between + - x / ( ), the only ones used in Gerber
116 
117 Before 2015 apr 10, actual value was calculated step to step:
118 no precedence, and '(' ')' are ignored.
119 
120 Since 2015 apr 10 precedence is in use.
121 
122 Parameter definition is described by a very primitive assembler.
123 This "program "should describe how to calculate the parameter.
124 The assembler consist of 10 instruction intended for a stackbased machine.
125 The instructions are:
126 NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, OPEN_PAR, CLOSE_PAR, EQUATE
127 
128 The instructions
129 ----------------
130 NOP : The no operation. This is the default instruction and are
131  added as a security measure.
132 PUSHVALUE : Pushes an arithmetical value on the stack. This machine only works with floats
133  on the stack.
134 PUSHPARM: Pushes a deferred parameter onto the stack. Gerber aperture macros accepts
135  parameters to be set when later declared, so the same macro can
136  be used at several instances. Which parameter to be set is an integer
137  and starts with 1. definition is like $1 or $3
138 ADD : The mathematical operation +. Takes the two uppermost values on the
139  the stack, adds them and pushes the result back onto the stack.
140 SUB : Same as ADD, but with -.
141 MUL : Same as ADD, but with *.
142 DIV : Same as ADD, but with /.
143 OPEN_PAR : Opening parenthesis: modify the precedence of operators by opening a local block.
144 CLOSE_PAR : Closing parenthesis: modify the precedence of operators by closing the local block.
145 POPVALUE : used when evaluate the expression: store current calculated value
146 */
147 
149 {
151 };
152 
161 {
162 public:
164  : m_type( aType), m_dvalue( 0.0 )
165  {}
166 
167  AM_PARAM_EVAL( double aValue )
168  : m_type( parm_item_type::NOP ), m_dvalue( aValue )
169  {}
170 
172  {
173  return m_type;
174  }
175 
176  bool IsOperator() const { return m_type != NOP; }
177  double GetValue() const { return m_dvalue; }
178  parm_item_type GetOperator() const { return m_type; }
179  int GetPriority() const { return GetPriority( GetOperator() ); }
180 
181  static int GetPriority( parm_item_type aType )
182  {
183  switch( aType )
184  {
185  case ADD:
186  case SUB:
187  return 1;
188 
189  case MUL:
190  case DIV:
191  return 2;
192 
193  case OPEN_PAR:
194  case CLOSE_PAR:
195  return 3;
196 
197  default:
198  break;
199  }
200 
201  return 0;
202  }
203 
204 private:
205  parm_item_type m_type; // the type of item
206  double m_dvalue; // the value, for a numerical value
207  // used only when m_type == NOP
208 };
209 
210 typedef std::vector<AM_PARAM_EVAL> AM_PARAM_EVAL_STACK;
211 
220 {
221 public:
222  AM_PARAM_ITEM( parm_item_type aType, double aValue )
223  {
224  m_type = aType;
225  m_dvalue = aValue;
226  m_ivalue = 0;
227  }
228 
229  AM_PARAM_ITEM( parm_item_type aType, int aValue )
230  {
231  m_type = aType;
232  m_dvalue = 0.0;
233  m_ivalue = aValue;
234  }
235 
236  void SetValue( double aValue )
237  {
238  m_dvalue = aValue;
239  }
240 
241  double GetValue( ) const
242  {
243  return m_dvalue;
244  }
245 
247  {
248  return m_type;
249  }
250 
251  unsigned GetIndex() const
252  {
253  return (unsigned) m_ivalue;
254  }
255 
256  bool IsOperator() const
257  {
258  return m_type == ADD || m_type == SUB || m_type == MUL || m_type == DIV;
259  }
260  bool IsOperand() const
261  {
262  return m_type == PUSHVALUE || m_type == PUSHPARM;
263  }
264 
265  bool IsDefered() const
266  {
267  return m_type == PUSHPARM;
268  }
269 
270 private:
271  parm_item_type m_type; // the type of item
272  double m_dvalue; // the value, for PUSHVALUE type item
273  int m_ivalue; // the integer value, for PUSHPARM type item
274 };
275 
284 class AM_PARAM
285 {
286 public:
287  AM_PARAM();
288 
295  void PushOperator( parm_item_type aType, double aValue );
296  void PushOperator( parm_item_type aType, int aValue = 0);
297 
298  double GetValue( const D_CODE* aDcode ) const;
299 
307  bool IsImmediate() const;
308 
309  unsigned GetIndex() const
310  {
311  return (unsigned) m_index;
312  }
313 
314  void SetIndex( int aIndex )
315  {
316  m_index = aIndex;
317  }
318 
332  bool ReadParam( char*& aText );
333 
334 private:
335  int m_index;
336  std::vector<AM_PARAM_ITEM> m_paramStack;
337 
341 };
342 
343 typedef std::vector<AM_PARAM> AM_PARAMS;
344 
345 #endif // _AM_PARAM_H_
std::vector< AM_PARAM_ITEM > m_paramStack
List of operands/operators to evaluate the actual value if a par def is $3/2, there are 3 items in st...
Definition: am_param.h:336
static int GetPriority(parm_item_type aType)
Definition: am_param.h:181
double GetValue(const D_CODE *aDcode) const
Definition: am_param.cpp:74
double m_dvalue
Definition: am_param.h:272
Definition: am_param.h:150
unsigned GetIndex() const
Definition: am_param.h:251
bool IsImmediate() const
Test if this AM_PARAM holds an immediate parameter or is a pointer into a parameter held by an owning...
Definition: am_param.cpp:59
parm_item_type GetType() const
Definition: am_param.h:246
parm_item_type GetOperator() const
Definition: am_param.h:178
Definition: am_param.h:150
int GetPriority() const
Definition: am_param.h:179
Hold an operand for an AM_PARAM as defined within standard RS274X.
Definition: am_param.h:219
AM_PARAM_EVAL(double aValue)
Definition: am_param.h:167
bool ReadParam(char *&aText)
Read one aperture macro parameter.
Definition: am_param.cpp:177
parm_item_type m_type
Definition: am_param.h:271
void PushOperator(parm_item_type aType, double aValue)
Add an operator/operand to the current stack.
Definition: am_param.cpp:152
parm_item_type GetType() const
Definition: am_param.h:171
std::vector< AM_PARAM > AM_PARAMS
Definition: am_param.h:343
parm_item_type
Definition: am_param.h:148
Hold a parameter value for an "aperture macro" as defined within standard RS274X.
Definition: am_param.h:284
AM_PARAM_EVAL(parm_item_type aType)
Definition: am_param.h:163
double m_dvalue
Definition: am_param.h:206
Definition: am_param.h:150
bool IsOperator() const
Definition: am_param.h:256
Definition: am_param.h:150
bool IsDefered() const
Definition: am_param.h:265
std::vector< AM_PARAM_EVAL > AM_PARAM_EVAL_STACK
Definition: am_param.h:210
bool IsOperator() const
Definition: am_param.h:176
This helper class hold a value or an arithmetic operator to calculate the final value of a aperture m...
Definition: am_param.h:160
AM_PARAM_ITEM(parm_item_type aType, int aValue)
Definition: am_param.h:229
void SetValue(double aValue)
Definition: am_param.h:236
parm_item_type m_type
Definition: am_param.h:205
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
unsigned GetIndex() const
Definition: am_param.h:309
AM_PARAM_ITEM(parm_item_type aType, double aValue)
Definition: am_param.h:222
double GetValue() const
Definition: am_param.h:241
void SetIndex(int aIndex)
Definition: am_param.h:314
int m_index
has meaning to define parameter local to an aperture macro
Definition: am_param.h:335
Definition: am_param.h:150
bool IsOperand() const
Definition: am_param.h:260
AM_PARAM()
Definition: am_param.cpp:49
double GetValue() const
Definition: am_param.h:177