## Copyright 2010, 2011, 2012 Tony Garnock-Jones . ## ## This file is part of Hop. ## ## Hop is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Hop is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ## License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Hop. If not, see . # SPKI SEXP import StringIO class SyntaxError(Exception): pass def write_sexp_str(f, x): f.write(str(len(x))) f.write(':') f.write(x) def write_sexp(f, sexp): if type(sexp) is list: f.write('(') for x in sexp: write_sexp(f, x) f.write(')') return if type(sexp) is str: write_sexp_str(f, sexp) return if type(sexp) is tuple: f.write('[') write_sexp_str(f, sexp[0]) f.write(']') write_sexp_str(f, sexp[1]) return def next(f, n): chunk = f.read(n) if len(chunk) < n: raise EOFError("reading sexp") return chunk def skipws(f): while True: c = next(f, 1) if not c.isspace(): return c def read_sexp(f): c = skipws(f) if c == '(': l = [] while True: val = read_sexp(f) if val is None: return l l.append(val) if c == '[': h = read_sexp(f) c = skipws(f) if c != ']': raise SyntaxError("Missing hint close bracket") b = read_sexp(f) return (h, b) if c.isdigit(): size = ord(c) - 48 while True: c = next(f, 1) if c == ':': return next(f, size) if not c.isdigit(): raise SyntaxError("Illegal character in byte vector length") size = size * 10 + ord(c) - 48 if c == ')': return None raise SyntaxError("Illegal character in sexp") def parse(s): return read_sexp(StringIO.StringIO(s)) def format(x): f = StringIO.StringIO() write_sexp(f, x) v = f.getvalue() f.close() return v