Skip to content

Instantly share code, notes, and snippets.

@belmarca
Created May 8, 2020 12:07
Show Gist options
  • Save belmarca/551fce9c487d79f3fe670f450ab42504 to your computer and use it in GitHub Desktop.
Save belmarca/551fce9c487d79f3fe670f450ab42504 to your computer and use it in GitHub Desktop.
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)
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)
(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