summaryrefslogtreecommitdiff
path: root/gerber/am_eval.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerber/am_eval.py')
-rw-r--r--gerber/am_eval.py106
1 files changed, 106 insertions, 0 deletions
diff --git a/gerber/am_eval.py b/gerber/am_eval.py
new file mode 100644
index 0000000..29b380d
--- /dev/null
+++ b/gerber/am_eval.py
@@ -0,0 +1,106 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# copyright 2014 Hamilton Kibbe <ham@hamiltonkib.be>
+# copyright 2014 Paulo Henrique Silva <ph.silva@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+""" This module provides RS-274-X AM macro evaluation.
+"""
+
+class OpCode:
+ PUSH = 1
+ LOAD = 2
+ STORE = 3
+ ADD = 4
+ SUB = 5
+ MUL = 6
+ DIV = 7
+ PRIM = 8
+
+ @staticmethod
+ def str(opcode):
+ if opcode == OpCode.PUSH:
+ return "OPCODE_PUSH"
+ elif opcode == OpCode.LOAD:
+ return "OPCODE_LOAD"
+ elif opcode == OpCode.STORE:
+ return "OPCODE_STORE"
+ elif opcode == OpCode.ADD:
+ return "OPCODE_ADD"
+ elif opcode == OpCode.SUB:
+ return "OPCODE_SUB"
+ elif opcode == OpCode.MUL:
+ return "OPCODE_MUL"
+ elif opcode == OpCode.DIV:
+ return "OPCODE_DIV"
+ elif opcode == OpCode.PRIM:
+ return "OPCODE_PRIM"
+ else:
+ return "UNKNOWN"
+
+def eval_macro(instructions, parameters={}):
+
+ if not isinstance(parameters, type({})):
+ p = {}
+ for i, val in enumerate(parameters):
+ p[i+1] = val
+
+ parameters = p
+
+ stack = []
+ def pop():
+ return stack.pop()
+
+ def push(op):
+ stack.append(op)
+
+ def top():
+ return stack[-1]
+
+ def empty():
+ return len(stack) == 0
+
+ for opcode, argument in instructions:
+ if opcode == OpCode.PUSH:
+ push(argument)
+
+ elif opcode == OpCode.LOAD:
+ push(parameters.get(argument, 0))
+
+ elif opcode == OpCode.STORE:
+ parameters[argument] = pop()
+
+ elif opcode == OpCode.ADD:
+ op1 = pop()
+ op2 = pop()
+ push(op2 + op1)
+
+ elif opcode == OpCode.SUB:
+ op1 = pop()
+ op2 = pop()
+ push(op2 - op2)
+
+ elif opcode == OpCode.MUL:
+ op1 = pop()
+ op2 = pop()
+ push(op2 * op1)
+
+ elif opcode == OpCode.DIV:
+ op1 = pop()
+ op2 = pop()
+ push(op2 / op1)
+
+ elif opcode == OpCode.PRIM:
+ yield "%d,%s" % (argument, ",".join([str(x) for x in stack]))
+ stack = []