summaryrefslogtreecommitdiff
path: root/gerber/gerber_statements.py
diff options
context:
space:
mode:
authorPaulo Henrique Silva <ph.silva@gmail.com>2015-03-03 03:41:55 -0300
committerPaulo Henrique Silva <ph.silva@gmail.com>2015-03-03 03:41:55 -0300
commit670d3fbbd7ebfb69bd223ac30b73ec47b195b380 (patch)
tree5373fdec50462a210f84d25caa93f1bc1204c4cb /gerber/gerber_statements.py
parentb8dcc86cb4560d033761db0ad41924f6d9669333 (diff)
downloadgerbonara-670d3fbbd7ebfb69bd223ac30b73ec47b195b380.tar.gz
gerbonara-670d3fbbd7ebfb69bd223ac30b73ec47b195b380.tar.bz2
gerbonara-670d3fbbd7ebfb69bd223ac30b73ec47b195b380.zip
Add aperture macro parsing and evaluation.
Aperture macros can get complex with arithmetical operations, variables and variables substitution. Current pcb-tools code just read each macro block as an independent unit, this cannot deal with variables that get changed after used. This patch splits the task in two: first we parse all macro content and creates a bytecode representation of all operations. This bytecode representation will be executed when an AD command is issues passing the required parameters. Parsing is heavily based on gerbv using a Shunting Yard approach to math parsing. Integration with rs274x.py code is not finished as I need to figure out how to integrate the final macro primitives with the graphical primitives already in use.
Diffstat (limited to 'gerber/gerber_statements.py')
-rw-r--r--gerber/gerber_statements.py58
1 files changed, 32 insertions, 26 deletions
diff --git a/gerber/gerber_statements.py b/gerber/gerber_statements.py
index 89f4f84..19c7138 100644
--- a/gerber/gerber_statements.py
+++ b/gerber/gerber_statements.py
@@ -22,7 +22,10 @@ Gerber (RS-274X) Statements
"""
from .utils import (parse_gerber_value, write_gerber_value, decimal_string,
inch, metric)
+
from .am_statements import *
+from .am_read import read_macro
+from .am_eval import eval_macro
class Statement(object):
@@ -340,34 +343,37 @@ class AMParamStmt(ParamStmt):
ParamStmt.__init__(self, param)
self.name = name
self.macro = macro
- self.primitives = self._parsePrimitives(macro)
- def _parsePrimitives(self, macro):
+ self.instructions = self.read(macro)
+ self.primitives = []
+
+ def read(self, macro):
+ return read_macro(macro)
+
+ def evaluate(self, modifiers=[]):
primitives = []
- for primitive in macro.strip('%\n').split('*'):
- # Couldn't find anything explicit about leading whitespace in the spec...
- primitive = primitive.strip(' *%\n')
- if len(primitive):
- if primitive[0] == '0':
- primitives.append(AMCommentPrimitive.from_gerber(primitive))
- elif primitive[0] == '1':
- primitives.append(AMCirclePrimitive.from_gerber(primitive))
- elif primitive[0:2] in ('2,', '20'):
- primitives.append(AMVectorLinePrimitive.from_gerber(primitive))
- elif primitive[0:2] == '21':
- primitives.append(AMCenterLinePrimitive.from_gerber(primitive))
- elif primitive[0:2] == '22':
- primitives.append(AMLowerLeftLinePrimitive.from_gerber(primitive))
- elif primitive[0] == '4':
- primitives.append(AMOutlinePrimitive.from_gerber(primitive))
- elif primitive[0] == '5':
- primitives.append(AMPolygonPrimitive.from_gerber(primitive))
- elif primitive[0] =='6':
- primitives.append(AMMoirePrimitive.from_gerber(primitive))
- elif primitive[0] == '7':
- primitives.append(AMThermalPrimitive.from_gerber(primitive))
- else:
- primitives.append(AMUnsupportPrimitive.from_gerber(primitive))
+ for primitive in eval_macro(self.instructions, modifiers[0]):
+ if primitive[0] == '0':
+ primitives.append(AMCommentPrimitive.from_gerber(primitive))
+ elif primitive[0] == '1':
+ primitives.append(AMCirclePrimitive.from_gerber(primitive))
+ elif primitive[0:2] in ('2,', '20'):
+ primitives.append(AMVectorLinePrimitive.from_gerber(primitive))
+ elif primitive[0:2] == '21':
+ primitives.append(AMCenterLinePrimitive.from_gerber(primitive))
+ elif primitive[0:2] == '22':
+ primitives.append(AMLowerLeftLinePrimitive.from_gerber(primitive))
+ elif primitive[0] == '4':
+ primitives.append(AMOutlinePrimitive.from_gerber(primitive))
+ elif primitive[0] == '5':
+ primitives.append(AMPolygonPrimitive.from_gerber(primitive))
+ elif primitive[0] =='6':
+ primitives.append(AMMoirePrimitive.from_gerber(primitive))
+ elif primitive[0] == '7':
+ primitives.append(AMThermalPrimitive.from_gerber(primitive))
+ else:
+ primitives.append(AMUnsupportPrimitive.from_gerber(primitive))
+
return primitives
def to_inch(self):