diff --git a/experiments/python/.gitignore b/experiments/python/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/experiments/python/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/experiments/python/hop/__init__.py b/experiments/python/hop/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/experiments/python/hop/sexp.py b/experiments/python/hop/sexp.py new file mode 100644 index 0000000..bed979f --- /dev/null +++ b/experiments/python/hop/sexp.py @@ -0,0 +1,76 @@ +## 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 skipws(f): + while True: + c = f.read(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 = f.read(1) + if c == ':': return f.read(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))