summaryrefslogtreecommitdiff
path: root/Final/python/pal2py
diff options
context:
space:
mode:
Diffstat (limited to 'Final/python/pal2py')
-rwxr-xr-xFinal/python/pal2py274
1 files changed, 274 insertions, 0 deletions
diff --git a/Final/python/pal2py b/Final/python/pal2py
new file mode 100755
index 0000000000..544151bf76
--- /dev/null
+++ b/Final/python/pal2py
@@ -0,0 +1,274 @@
+#!/usr/bin/env python
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+import sys, os, xml
+
+from qpid.spec import load, pythonize
+from textwrap import TextWrapper
+from xml.sax.handler import ContentHandler
+
+class Block:
+
+ def __init__(self, children):
+ self.children = children
+
+ def emit(self, out):
+ for child in self.children:
+ if not hasattr(child, "emit"):
+ raise ValueError(child)
+ child.emit(out)
+
+ if not self.children:
+ out.line("pass")
+
+class If:
+
+ def __init__(self, expr, cons, alt = None):
+ self.expr = expr
+ self.cons = cons
+ self.alt = alt
+
+ def emit(self, out):
+ out.line("if ")
+ self.expr.emit(out)
+ out.write(":")
+ out.level += 1
+ self.cons.emit(out)
+ out.level -= 1
+ if self.alt:
+ out.line("else:")
+ out.level += 1
+ self.alt.emit(out)
+ out.level -= 1
+
+class Stmt:
+
+ def __init__(self, code):
+ self.code = code
+
+ def emit(self, out):
+ out.line(self.code)
+
+class Expr:
+
+ def __init__(self, code):
+ self.code = code
+
+ def emit(self, out):
+ out.write(self.code)
+
+class Abort:
+
+ def __init__(self, expr):
+ self.expr = expr
+
+ def emit(self, out):
+ out.line("assert False, ")
+ self.expr.emit(out)
+
+WRAPPER = TextWrapper()
+
+def wrap(text):
+ return WRAPPER.wrap(" ".join(text.split()))
+
+class Doc:
+
+ def __init__(self, text):
+ self.text = text
+
+ def emit(self, out):
+ out.line('"""')
+ for line in wrap(self.text):
+ out.line(line)
+ out.line('"""')
+
+class Frame:
+
+ def __init__(self, attrs):
+ self.attrs = attrs
+ self.children = []
+ self.text = None
+
+ def __getattr__(self, attr):
+ return self.attrs[attr]
+
+def isunicode(s):
+ if isinstance(s, str):
+ return False
+ for ch in s:
+ if ord(ch) > 127:
+ return True
+ return False
+
+def string_literal(s):
+ if s == None:
+ return None
+ if isunicode(s):
+ return "%r" % s
+ else:
+ return "%r" % str(s)
+
+TRUTH = {
+ "1": True,
+ "0": False,
+ "true": True,
+ "false": False
+ }
+
+LITERAL = {
+ "shortstr": string_literal,
+ "longstr": string_literal,
+ "bit": lambda s: TRUTH[s.lower()],
+ "longlong": lambda s: "%r" % long(s)
+ }
+
+def literal(s, field):
+ return LITERAL[field.type](s)
+
+def palexpr(s, field):
+ if s.startswith("$"):
+ return "msg.%s" % s[1:]
+ else:
+ return literal(s, field)
+
+class Translator(ContentHandler):
+
+ def __init__(self, spec):
+ self.spec = spec
+ self.stack = []
+ self.content = None
+ self.root = Frame(None)
+ self.push(self.root)
+
+ def emit(self, out):
+ blk = Block(self.root.children)
+ blk.emit(out)
+ out.write("\n")
+
+ def peek(self):
+ return self.stack[-1]
+
+ def pop(self):
+ return self.stack.pop()
+
+ def push(self, frame):
+ self.stack.append(frame)
+
+ def startElement(self, name, attrs):
+ self.push(Frame(attrs))
+
+ def endElement(self, name):
+ frame = self.pop()
+ if hasattr(self, name):
+ child = getattr(self, name)(frame)
+ else:
+ child = self.handle(name, frame)
+
+ if child:
+ self.peek().children.append(child)
+
+ def characters(self, text):
+ frame = self.peek()
+ if frame.text:
+ frame.text += text
+ else:
+ frame.text = text
+
+ def handle(self, name, frame):
+ for klass in self.spec.classes:
+ pyklass = pythonize(klass.name)
+ if name.startswith(pyklass):
+ name = name[len(pyklass) + 1:]
+ break
+ else:
+ raise ValueError("unknown class: %s" % name)
+
+ for method in klass.methods:
+ pymethod = pythonize(method.name)
+ if name == pymethod:
+ break
+ else:
+ raise ValueError("unknown method: %s" % name)
+
+ args = ["%s = %s" % (key, palexpr(val, method.fields.bypyname[key]))
+ for key, val in frame.attrs.items()]
+ if method.content and self.content:
+ args.append("content = %r" % string_literal(self.content))
+ code = "ssn.%s_%s(%s)" % (pyklass, pymethod, ", ".join(args))
+ if pymethod == "consume":
+ code = "consumer_tag = %s.consumer_tag" % code
+ return Stmt(code)
+
+ def pal(self, frame):
+ return Block([Doc(frame.text)] + frame.children)
+
+ def include(self, frame):
+ base, ext = os.path.splitext(frame.filename)
+ return Stmt("from %s import *" % base)
+
+ def session(self, frame):
+ return Block([Stmt("cli = open()"), Stmt("ssn = cli.channel(0)"),
+ Stmt("ssn.channel_open()")] + frame.children)
+
+ def empty(self, frame):
+ return If(Expr("msg == None"), Block(frame.children))
+
+ def abort(self, frame):
+ return Abort(Expr(string_literal(frame.text)))
+
+ def wait(self, frame):
+ return Stmt("msg = ssn.queue(consumer_tag).get(timeout=%r)" %
+ (int(frame.timeout)/1000))
+
+ def basic_arrived(self, frame):
+ if frame.children:
+ return If(Expr("msg != None"), Block(frame.children))
+
+ def basic_content(self, frame):
+ self.content = frame.text
+
+class Emitter:
+
+ def __init__(self, out):
+ self.out = out
+ self.level = 0
+
+ def write(self, code):
+ self.out.write(code)
+
+ def line(self, code):
+ self.write("\n%s%s" % (" "*self.level, code))
+
+ def flush(self):
+ self.out.flush()
+
+ def close(self):
+ self.out.close()
+
+
+for f in sys.argv[2:]:
+ base, ext = os.path.splitext(f)
+ spec = load(sys.argv[1])
+ t = Translator(spec)
+ xml.sax.parse(f, t)
+# out = Emitter(open("%s.py" % base))
+ out = Emitter(sys.stdout)
+ t.emit(out)
+ out.close()