diff options
Diffstat (limited to 'Final/python/pal2py')
-rwxr-xr-x | Final/python/pal2py | 274 |
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() |