Last active
March 18, 2018 10:57
-
-
Save milesrout/e2a86e5716e287dfd150f228c8fca39b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# to print an s-expression | |
# | |
# e.g. | |
# (macro-definition | |
# (id-expression name) | |
# (statements | |
# (...) | |
# (...) | |
# (...))) | |
# | |
# 1. Print opening bracket | |
# 2. Print first item in list directly | |
# 3. If the list contains any lists or the length condition holds | |
# a. Increment the indentation level | |
# b. For each item in the list: | |
# i. Print a newline | |
# ii. Print enough spaces to reach the current indentation level | |
# iii. Print the sub-expression | |
# 4. Otherwise | |
# a. For each item in the list: | |
# i. Print a space | |
# ii. Print the sub-expression *without considering the first branch of the if* | |
# 5. Print a closing bracket | |
# | |
# (Without the restriction on considering the first branch of the if, this is exponential complexity) | |
def to_sexpr(o, indent=None): | |
return fmt_sexpr(json.loads(MyJSONEncoder().encode(o))) | |
def fmt_sexpr(o, depth=1): | |
if isinstance(o, dict): | |
return fmt_sexpr(list(o.values()), depth) | |
if isinstance(o, tuple): | |
return fmt_sexpr(list(o), depth) | |
if isinstance(o, list): | |
if len(o) == 0: | |
return '()' | |
if len(o) == 1: | |
return fmt_sexpr(o[0], depth) | |
return fmt_sexpr_list(o, depth) | |
return str(o) | |
def fmt_sexpr_short(o, depth=1): | |
if isinstance(o, dict): | |
return fmt_sexpr_short(list(o.values())) | |
if isinstance(o, tuple): | |
return fmt_sexpr_short(list(o)) | |
if isinstance(o, list): | |
if len(o) == 0: | |
return '()' | |
if len(o) == 1: | |
return fmt_sexpr_short(o[0]) | |
return fmt_sexpr_list_short(o) | |
return str(o) | |
@compose(''.join) | |
def fmt_sexpr_list_long(o, depth): | |
yield '(' | |
yield fmt_sexpr(o[0], depth + 1) | |
for item in o[1:]: | |
yield '\n' | |
yield (2 * depth * ' ') | |
yield fmt_sexpr(item, depth + 1) | |
yield ')' | |
@compose(''.join) | |
def fmt_sexpr_list_short(o): | |
yield '(' | |
yield fmt_sexpr_short(o[0]) | |
for item in o[1:]: | |
yield ' ' | |
yield fmt_sexpr_short(item) | |
yield ')' | |
def fmt_sexpr_list(o, depth): | |
result = fmt_sexpr_list_short(o) | |
if max(map(len, result.splitlines())) > 80: | |
return fmt_sexpr_list_long(o, depth) | |
return result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment