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.

343 lines
11 KiB

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