summaryrefslogtreecommitdiff
path: root/gerbonara/gerber/aperture_macros/expression.py
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2022-01-30 20:11:38 +0100
committerjaseg <git@jaseg.de>2022-01-30 20:11:38 +0100
commitc3ca4f95bd59f69d45e582a4149327f57a360760 (patch)
tree5f43c61a261698e2f671b5238a7aa9a71a0f6d23 /gerbonara/gerber/aperture_macros/expression.py
parent259a56186820923c78a5688f59bd8249cf958b5f (diff)
downloadgerbonara-c3ca4f95bd59f69d45e582a4149327f57a360760.tar.gz
gerbonara-c3ca4f95bd59f69d45e582a4149327f57a360760.tar.bz2
gerbonara-c3ca4f95bd59f69d45e582a4149327f57a360760.zip
Rename gerbonara/gerber package to just gerbonara
Diffstat (limited to 'gerbonara/gerber/aperture_macros/expression.py')
-rw-r--r--gerbonara/gerber/aperture_macros/expression.py211
1 files changed, 0 insertions, 211 deletions
diff --git a/gerbonara/gerber/aperture_macros/expression.py b/gerbonara/gerber/aperture_macros/expression.py
deleted file mode 100644
index 0cf055a..0000000
--- a/gerbonara/gerber/aperture_macros/expression.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright 2021 Jan Götte <gerbonara@jaseg.de>
-
-import operator
-import re
-import ast
-
-from ..utils import MM, Inch, MILLIMETERS_PER_INCH
-
-
-def expr(obj):
- return obj if isinstance(obj, Expression) else ConstantExpression(obj)
-
-
-class Expression:
- def optimized(self, variable_binding={}):
- return self
-
- def __str__(self):
- return f'<{self.to_gerber()}>'
-
- def __repr__(self):
- return f'<E {self.to_gerber()}>'
-
- def converted(self, unit):
- return self
-
- def calculate(self, variable_binding={}, unit=None):
- expr = self.converted(unit).optimized(variable_binding)
- if not isinstance(expr, ConstantExpression):
- raise IndexError(f'Cannot fully resolve expression due to unresolved variables: {expr} with variables {variable_binding}')
- return expr.value
-
- def __add__(self, other):
- return OperatorExpression(operator.add, self, expr(other)).optimized()
-
- def __radd__(self, other):
- return expr(other) + self
-
- def __sub__(self, other):
- return OperatorExpression(operator.sub, self, expr(other)).optimized()
-
- def __rsub__(self, other):
- return expr(other) - self
-
- def __mul__(self, other):
- return OperatorExpression(operator.mul, self, expr(other)).optimized()
-
- def __rmul__(self, other):
- return expr(other) * self
-
- def __truediv__(self, other):
- return OperatorExpression(operator.truediv, self, expr(other)).optimized()
-
- def __rtruediv__(self, other):
- return expr(other) / self
-
- def __neg__(self):
- return 0 - self
-
- def __pos__(self):
- return self
-
-class UnitExpression(Expression):
- def __init__(self, expr, unit):
- self._expr = expr
- self.unit = unit
-
- def to_gerber(self, unit=None):
- return self.converted(unit).optimized().to_gerber()
-
- def __eq__(self, other):
- return type(other) == type(self) and \
- self.unit == other.unit and\
- self._expr == other._expr
-
- def __str__(self):
- return f'<{self._expr.to_gerber()} {self.unit}>'
-
- def __repr__(self):
- return f'<UE {self._expr.to_gerber()} {self.unit}>'
-
- def converted(self, unit):
- if self.unit is None or unit is None or self.unit == unit:
- return self._expr
-
- elif MM == unit:
- return self._expr * MILLIMETERS_PER_INCH
-
- elif Inch == unit:
- return self._expr / MILLIMETERS_PER_INCH
-
- else:
- raise ValueError(f'invalid unit {unit}, must be "inch" or "mm".')
-
- def __add__(self, other):
- if not isinstance(other, UnitExpression):
- raise ValueError('Unit mismatch: Can only add/subtract UnitExpression from UnitExpression, not scalar.')
-
- if self.unit == other.unit or self.unit is None or other.unit is None:
- return UnitExpression(self._expr + other._expr, self.unit)
-
- if other.unit == 'mm': # -> and self.unit == 'inch'
- return UnitExpression(self._expr + (other._expr / MILLIMETERS_PER_INCH), self.unit)
- else: # other.unit == 'inch' and self.unit == 'mm'
- return UnitExpression(self._expr + (other._expr * MILLIMETERS_PER_INCH), self.unit)
-
- def __radd__(self, other):
- # left hand side cannot have been an UnitExpression or __radd__ would not have been called
- raise ValueError('Unit mismatch: Can only add/subtract UnitExpression from UnitExpression, not scalar.')
-
- def __sub__(self, other):
- return (self + (-other)).optimize()
-
- def __rsub__(self, other):
- # see __radd__ above
- raise ValueError('Unit mismatch: Can only add/subtract UnitExpression from UnitExpression, not scalar.')
-
- def __mul__(self, other):
- return UnitExpression(self._expr * other, self.unit)
-
- def __rmul__(self, other):
- return UnitExpression(other * self._expr, self.unit)
-
- def __truediv__(self, other):
- return UnitExpression(self._expr / other, self.unit)
-
- def __rtruediv__(self, other):
- return UnitExpression(other / self._expr, self.unit)
-
- def __neg__(self):
- return UnitExpression(-self._expr, self.unit)
-
- def __pos__(self):
- return self
-
-
-class ConstantExpression(Expression):
- def __init__(self, value):
- self.value = value
-
- def __float__(self):
- return float(self.value)
-
- def __eq__(self, other):
- return type(self) == type(other) and self.value == other.value
-
- def to_gerber(self, _unit=None):
- return f'{self.value:.6f}'.rstrip('0').rstrip('.')
-
-
-class VariableExpression(Expression):
- def __init__(self, number):
- self.number = number
-
- def optimized(self, variable_binding={}):
- if self.number in variable_binding:
- return ConstantExpression(variable_binding[self.number])
- return self
-
- def __eq__(self, other):
- return type(self) == type(other) and \
- self.number == other.number
-
- def to_gerber(self, _unit=None):
- return f'${self.number}'
-
-
-class OperatorExpression(Expression):
- def __init__(self, op, l, r):
- self.op = op
- self.l = ConstantExpression(l) if isinstance(l, (int, float)) else l
- self.r = ConstantExpression(r) if isinstance(r, (int, float)) else r
-
- def __eq__(self, other):
- return type(self) == type(other) and \
- self.op == other.op and \
- self.l == other.l and \
- self.r == other.r
-
- def optimized(self, variable_binding={}):
- l = self.l.optimized(variable_binding)
- r = self.r.optimized(variable_binding)
-
- if self.op in (operator.add, operator.mul):
- if id(r) < id(l):
- l, r = r, l
-
- if isinstance(l, ConstantExpression) and isinstance(r, ConstantExpression):
- return ConstantExpression(self.op(float(l), float(r)))
-
- return OperatorExpression(self.op, l, r)
-
- def to_gerber(self, unit=None):
- lval = self.l.to_gerber(unit)
- rval = self.r.to_gerber(unit)
-
- if isinstance(self.l, OperatorExpression):
- lval = f'({lval})'
- if isinstance(self.r, OperatorExpression):
- rval = f'({rval})'
-
- op = {operator.add: '+',
- operator.sub: '-',
- operator.mul: 'X',
- operator.truediv: '/'} [self.op]
-
- return f'{lval}{op}{rval}'
-