Created
May 8, 2020 12:07
-
-
Save belmarca/551fce9c487d79f3fe670f450ab42504 to your computer and use it in GitHub Desktop.
This file contains 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
import os | |
from ast import parse, Assign, Name, Num, Str, \ | |
FunctionDef, arguments, arg, Return, Tuple, \ | |
If, Compare, NameConstant, BoolOp, And, Or, \ | |
Gt, GtE, Lt, LtE, Eq, NotEq, BinOp, Call, \ | |
Add, Sub, Expr | |
def py2scm(source): | |
parse_tree = parse(source) | |
body = parse_tree.body | |
# out = "(begin" | |
out = '' | |
for node in body: | |
out += parse_node(node) | |
# out += ")" | |
return out | |
def parse_node(node): | |
if isinstance(node, Assign): | |
return parse_Assign(node) | |
elif isinstance(node, Name): | |
return parse_Name(node) | |
elif isinstance(node, Num): | |
return parse_Num(node) | |
elif isinstance(node, Str): | |
return parse_Str(node) | |
elif isinstance(node, FunctionDef): | |
return parse_FunctionDef(node) | |
elif isinstance(node, arguments): | |
return parse_arguments(node) | |
elif isinstance(node, arg): | |
return parse_arg(node) | |
elif isinstance(node, Return): | |
return parse_Return(node) | |
elif isinstance(node, If): | |
return parse_If(node) | |
elif isinstance(node, Compare): | |
return parse_Compare(node) | |
elif isinstance(node, NameConstant): | |
return parse_NameConstant(node) | |
elif isinstance(node, BoolOp): | |
return parse_BoolOp(node) | |
elif isinstance(node, And): | |
return parse_And(node) | |
elif isinstance(node, Or): | |
return parse_Or(node) | |
elif isinstance(node, Gt): | |
return parse_Gt(node) | |
elif isinstance(node, GtE): | |
return parse_GtE(node) | |
elif isinstance(node, Lt): | |
return parse_Lt(node) | |
elif isinstance(node, LtE): | |
return parse_LtE(node) | |
elif isinstance(node, Eq): | |
return parse_Eq(node) | |
elif isinstance(node, NotEq): | |
return parse_NotEq(node) | |
elif isinstance(node, BinOp): | |
return parse_BinOp(node) | |
elif isinstance(node, Call): | |
return parse_Call(node) | |
elif isinstance(node, Add): | |
return parse_Add(node) | |
elif isinstance(node, Sub): | |
return parse_Sub(node) | |
elif isinstance(node, Expr): | |
return parse_Expr(node) | |
# elif isinstance(node, Tuple): | |
# return parse_Tuple(node) | |
def parse_Assign(node): | |
# value and targets can be tuples! | |
targets = node.targets | |
value = node.value | |
if len(targets) > 1: | |
raise Exception | |
def define(x, y): | |
return ' (define ' + x + " " + y + ')' | |
if isinstance(targets[0], Tuple): | |
target_elts = targets[0].elts | |
value_elts = value.elts | |
out = ' '.join([define(parse_node(target_elts[i]), parse_node(value_elts[i])) for i in range(len(target_elts))]) | |
else: | |
out = define(parse_node(targets[0]), parse_node(value)) | |
return out | |
# def parse_Tuple(node): | |
# elts = node.elts # array of Names | |
# # ctx = node.ctx | |
# out = ' '.join() | |
# return 0 | |
def parse_If(node): | |
test = parse_node(node.test) # Compare, BoolOp | |
body = ' '.join([parse_node(node) for node in node.body]) | |
orelse = node.orelse | |
out = " (if " + test + ' ' + body | |
if orelse != []: | |
out += ' '.join([parse_node(node) for node in orelse]) + ')' | |
else: | |
out += ')' | |
return out | |
def parse_BinOp(node): | |
def binop(op, l, r): | |
return parse_node(op) + ' ' + parse_node(l) + ' ' + parse_node(r) + ')' | |
left = node.left | |
op = node.op | |
right = node.right | |
return ' ' + binop(op, left, right) | |
def parse_Call(node): | |
func = parse_node(node.func) | |
args = ' '.join([parse_node(arg) for arg in node.args]) | |
keywords = node.keywords | |
if keywords != []: | |
# unsupported | |
raise Exception | |
return '(' + func + ' ' + args + ')' | |
def parse_Expr(node): | |
return parse_node(node.value) | |
def parse_Add(node): | |
return '(+' | |
def parse_Sub(node): | |
return '(-' | |
def parse_Gt(node): | |
return "(>" | |
def parse_GtE(node): | |
return "(>=" | |
def parse_Lt(node): | |
return "(<" | |
def parse_LtE(node): | |
return "(>=" | |
def parse_Eq(node): | |
return "(equal?" | |
def parse_NotEq(node): | |
return "(not (equal?" | |
def parse_Compare(node): | |
def compare(op, l, r): | |
out = parse_node(op) + ' ' + parse_node(l) + ' ' + parse_node(r) + ')' | |
if isinstance(op, NotEq): | |
out += ')' | |
return out | |
left = node.left | |
ops = node.ops | |
comparators = node.comparators | |
# there can be more than one comparator, in which case we 'and' | |
if len(ops) > 1: | |
out = '(and ' + \ | |
' '.join([compare(ops[i], left, comparators[i]) | |
for i in range(len(ops))]) + \ | |
')' | |
else: | |
out = compare(ops[0], left, comparators[0]) | |
return out | |
def parse_BoolOp(node): | |
op = node.op | |
values = node.values | |
return 0 | |
def parse_Or(node): | |
return 0 | |
def parse_And(node): | |
return 0 | |
def parse_NameConstant(node): | |
return str(node.value) | |
def parse_Num(node): | |
return str(node.n) | |
def parse_Name(node): | |
return node.id | |
def parse_Str(node): | |
out = '"' + node.s.replace('"', '\\"') + '"' | |
return out | |
def parse_FunctionDef(node): | |
args, kwarg = parse_arguments(node.args) | |
body = ' '.join([parse_node(node) for node in node.body]) | |
name = node.name | |
# returns = node.returns | |
# decorator_list = node.decorator_list | |
out = " (define " + name + " (lambda (" | |
out += args | |
out += ")" | |
out += ' ' + body | |
out += "))" | |
return out | |
def parse_arguments(node): | |
# ('args', 'vararg', 'kwonlyargs', 'kw_defaults', 'kwarg', 'defaults') | |
args = ' '.join([parse_arg(arg) for arg in node.args]) | |
kwarg = '' | |
return (args, kwarg) | |
def parse_arg(node): | |
arg = node.arg | |
# annotation = node.annotation | |
return arg | |
def parse_Return(node): | |
return parse_node(node.value) | |
def parse_file(f): | |
with open(f, 'r') as _f: | |
source = _f.read() | |
return py2scm(source) | |
def compile_file(py, scm=None): | |
if py[-3:] != '.py': | |
raise Exception | |
if scm is None: | |
scm = py[:-3] + '.scm' | |
# don't overwrite | |
# if os.path.exists(scm): | |
# raise Exception | |
scheme_code = parse_file(py) | |
with open(scm, 'w') as f: | |
print(scheme_code, file=f) |
This file contains 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
x = 1 | |
y = 2 | |
z = 3 | |
f, g = 0, 1 | |
q = "Hello, world!" | |
r = "Hello, \"world\"!" | |
s = 'Hello, \"world\"!' | |
t = 'Hello, \"world!' | |
u = 'Hello, \"\"\"world!' | |
def function_name(x, y, z): | |
return x | |
def myfun(x, y): | |
if x > y < 0: | |
return x | |
def fib(n): | |
if n == 1: | |
return 1 | |
elif n == 0: | |
return 0 | |
else: | |
return fib(n-1) + fib(n-2) |
This file contains 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
(define x 1) (define y 2) (define z 3) (define f 0) (define g 1) (define q "Hello, world!") (define r "Hello, \"world\"!") (define s "Hello, \"world\"!") (define t "Hello, \"world!") (define u "Hello, \"\"\"world!") (define function_name (lambda (x y z) x)) (define myfun (lambda (x y) (if (and (> x y) (< x 0)) x))) (define fib (lambda (n) (if (equal? n 1) 1 (if (equal? n 0) 0 (+ (fib (- n 1)) (fib (- n 2))))))) | |
;; (define x 1) | |
;; (define y 2) | |
;; (define z 3) | |
;; (define f 0) | |
;; (define g 1) | |
;; (define q "Hello, world!") | |
;; (define r "Hello, \"world\"!") | |
;; (define s "Hello, \"world\"!") | |
;; (define t "Hello, \"world!") | |
;; (define u "Hello, \"\"\"world!") | |
;; (define function_name | |
;; (lambda (x y z) x)) | |
;; (define myfun | |
;; (lambda (x y) | |
;; (if (and (> x y) (< x 0)) | |
;; x))) | |
;; (define fib | |
;; (lambda (n) | |
;; (if (equal? n 1) | |
;; 1 | |
;; (if (equal? n 0) | |
;; 0 | |
;; (+ (fib (- n 1)) (fib (- n 2))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment