KiCad PCB EDA Suite
class_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 <dick@softplc.com>
10  * Copyright (C) 1992-2017 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 defered value.
40  * When value is defered, it is defined when the aperture macro is instancied 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 deferend 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 defered 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 instanciation:
66  * %ADD19MOIRE10*%
67  *
68  * A simple definition, one parameter:
69  * %AMCIRCLE*
70  * 1,1,$1,0,0*
71  * Example of instanciation:
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 instanciation:
78  * %ADD12VECTOR,0.05X0X0*%
79  *
80  * A more complicated aperture macro definition, with parameters and arihmetic 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 instanciation:
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 instanciation:
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 defered 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 precendence 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 defered 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 
221 {
222 private:
223  parm_item_type m_type; // the type of item
224  double m_dvalue; // the value, for PUSHVALUE type item
225  int m_ivalue; // the integer value, for PUSHPARM type item
226 
227 public:
228  AM_PARAM_ITEM( parm_item_type aType, double aValue )
229  {
230  m_type = aType;
231  m_dvalue = aValue;
232  m_ivalue = 0;
233  }
234 
235  AM_PARAM_ITEM( parm_item_type aType, int aValue )
236  {
237  m_type = aType;
238  m_dvalue = 0.0;
239  m_ivalue = aValue;
240  }
241 
242  void SetValue( double aValue )
243  {
244  m_dvalue = aValue;
245  }
246 
247  double GetValue( ) const
248  {
249  return m_dvalue;
250  }
251 
253  {
254  return m_type;
255  }
256 
257  unsigned GetIndex() const
258  {
259  return (unsigned) m_ivalue;
260  }
261 
262  bool IsOperator() const
263  {
264  return m_type == ADD || m_type == SUB || m_type == MUL || m_type == DIV;
265  }
266  bool IsOperand() const
267  {
268  return m_type == PUSHVALUE || m_type == PUSHPARM;
269  }
270 
271  bool IsDefered() const
272  {
273  return m_type == PUSHPARM;
274  }
275 };
276 
286 class AM_PARAM
287 {
288 private:
289  int m_index; // has meaning to define parameter local to an aperture macro
290  std::vector<AM_PARAM_ITEM> m_paramStack; // list of operands/operators to evalutate the actual value
291  // if a par def is $3/2, there are 3 items in stack:
292  // 3 (type PUSHPARM) , / (type DIV), 2 (type PUSHVALUE)
293 
294 public:
295  AM_PARAM();
296 
303  void PushOperator( parm_item_type aType, double aValue );
304  void PushOperator( parm_item_type aType, int aValue = 0);
305 
306  double GetValue( const D_CODE* aDcode ) const;
307 
314  bool IsImmediate() const;
315 
316  unsigned GetIndex() const
317  {
318  return (unsigned) m_index;
319  }
320 
321  void SetIndex( int aIndex )
322  {
323  m_index = aIndex;
324  }
325 
338  bool ReadParam( char*& aText );
339 };
340 
341 typedef std::vector<AM_PARAM> AM_PARAMS;
342 
343 #endif // _AM_PARAM_H_
std::vector< AM_PARAM_ITEM > m_paramStack
parm_item_type GetOperator() const
static int GetPriority(parm_item_type aType)
std::vector< AM_PARAM_EVAL > AM_PARAM_EVAL_STACK
unsigned GetIndex() const
Class AM_PARAM holds an operand for an AM_PARAM as defined within standard RS274X.
AM_PARAM_EVAL(double aValue)
unsigned GetIndex() const
std::vector< AM_PARAM > AM_PARAMS
bool ReadParam(char *&aText)
Function ReadParam Read one aperture macro parameter a parameter can be: a number a reference to an a...
parm_item_type m_type
int GetPriority() const
void PushOperator(parm_item_type aType, double aValue)
function PushOperator add an operator/operand to the current stack
parm_item_type GetType() const
Class AM_PARAM holds a parameter value for an "aperture macro" as defined within standard RS274X...
AM_PARAM_EVAL(parm_item_type aType)
bool IsOperator() const
double GetValue(const D_CODE *aDcode) const
bool IsImmediate() const
Function IsImmediate tests if this AM_PARAM holds an immediate parameter or is a pointer into a param...
bool IsDefered() const
This helper class hold a value or an arithmetic operator to calculate the final value of a aperture m...
AM_PARAM_ITEM(parm_item_type aType, int aValue)
void SetValue(double aValue)
parm_item_type m_type
Class D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
bool IsOperator() const
parm_item_type
AM_PARAM_ITEM(parm_item_type aType, double aValue)
double GetValue() const
void SetIndex(int aIndex)
bool IsOperand() const
double GetValue() const
parm_item_type GetType() const