mirror of
https://github.com/kanaka/mal.git
synced 2024-09-11 13:55:55 +03:00
Python: metadata on builtin funcs. Support python3.
This commit is contained in:
parent
b3402a82d3
commit
a05f7822b1
4
Makefile
4
Makefile
@ -4,6 +4,8 @@
|
||||
|
||||
MAL_IMPL = js
|
||||
|
||||
PYTHON = python
|
||||
|
||||
#
|
||||
# Settings
|
||||
#
|
||||
@ -54,7 +56,7 @@ make_RUNTEST = ../runtest.py $(4) ../$(1) -- make -f ../$(2) $(5)
|
||||
mal_RUNTEST = $(call $(MAL_IMPL)_RUNTEST,$(1),$(call $(MAL_IMPL)_STEP_TO_PROG,stepA),stepA,--start-timeout 30 --test-timeout 120,../$(2))
|
||||
php_RUNTEST = ../runtest.py $(4) ../$(1) -- php ../$(2) $(5)
|
||||
ps_RUNTEST = ../runtest.py $(4) ../$(1) -- "gs -q -dNODISPLAY -- ../$(2) $(5)"
|
||||
python_RUNTEST = ../runtest.py $(4) ../$(1) -- python ../$(2) $(5)
|
||||
python_RUNTEST = ../runtest.py $(4) ../$(1) -- $(PYTHON) ../$(2) $(5)
|
||||
ruby_RUNTEST = ../runtest.py $(4) ../$(1) -- ruby ../$(2) $(5)
|
||||
|
||||
|
||||
|
@ -135,7 +135,7 @@ cd ps
|
||||
gs -q -dNODISPLAY stepX_YYY.ps
|
||||
```
|
||||
|
||||
### Python 2.X
|
||||
### Python (2 or 3)
|
||||
|
||||
```
|
||||
cd python
|
||||
|
@ -17,12 +17,12 @@ def do_str(*args):
|
||||
return "".join(map(lambda exp: printer._pr_str(exp, False), args))
|
||||
|
||||
def prn(*args):
|
||||
print " ".join(map(lambda exp: printer._pr_str(exp, True), args))
|
||||
print(" ".join(map(lambda exp: printer._pr_str(exp, True), args)))
|
||||
return None
|
||||
|
||||
def println(*args):
|
||||
line = " ".join(map(lambda exp: printer._pr_str(exp, False), args))
|
||||
print line.replace('\\n', '\n')
|
||||
print(line.replace('\\n', '\n'))
|
||||
return None
|
||||
|
||||
|
||||
@ -85,10 +85,7 @@ def mapf(f, lst): return List(map(f, lst))
|
||||
|
||||
# Metadata functions
|
||||
def with_meta(obj, meta):
|
||||
if type(obj) == type(lambda x:x):
|
||||
new_obj = obj.__copy__()
|
||||
else:
|
||||
new_obj = copy.copy(obj)
|
||||
new_obj = types._clone(obj)
|
||||
new_obj.__meta__ = meta
|
||||
return new_obj
|
||||
|
||||
@ -126,7 +123,7 @@ ns = {
|
||||
'+': lambda a,b: a+b,
|
||||
'-': lambda a,b: a-b,
|
||||
'*': lambda a,b: a*b,
|
||||
'/': lambda a,b: a/b,
|
||||
'/': lambda a,b: int(a/b),
|
||||
|
||||
'list': types._list,
|
||||
'list?': types._list_Q,
|
||||
|
@ -1,7 +1,11 @@
|
||||
import os, readline as pyreadline
|
||||
import os, sys, readline as pyreadline
|
||||
|
||||
history_loaded = False
|
||||
histfile = os.path.expanduser("~/.mal-history")
|
||||
if sys.version_info[0] >= 3:
|
||||
rl = input
|
||||
else:
|
||||
rl = raw_input
|
||||
|
||||
def readline(prompt="user> "):
|
||||
if not history_loaded:
|
||||
@ -15,7 +19,7 @@ def readline(prompt="user> "):
|
||||
pass
|
||||
|
||||
try:
|
||||
line = raw_input(prompt)
|
||||
line = rl(prompt)
|
||||
pyreadline.add_history(line)
|
||||
with open(histfile, "a") as hf:
|
||||
hf.write(line + "\n")
|
||||
|
@ -1,3 +1,9 @@
|
||||
import sys, copy, types as pytypes
|
||||
if sys.version_info[0] >= 3:
|
||||
str_types = [str]
|
||||
else:
|
||||
str_types = [str, unicode]
|
||||
|
||||
# General functions
|
||||
|
||||
def _equal_Q(a, b):
|
||||
@ -26,11 +32,26 @@ def _equal_Q(a, b):
|
||||
|
||||
def _sequential_Q(seq): return _list_Q(seq) or _vector_Q(seq)
|
||||
|
||||
def _clone(obj):
|
||||
#if type(obj) == type(lambda x:x):
|
||||
if type(obj) == pytypes.FunctionType:
|
||||
if obj.__code__:
|
||||
return pytypes.FunctionType(
|
||||
obj.__code__, obj.__globals__, name = obj.__name__,
|
||||
argdefs = obj.__defaults__, closure = obj.__closure__)
|
||||
else:
|
||||
return pytypes.FunctionType(
|
||||
obj.func_code, obj.func_globals, name = obj.func_name,
|
||||
argdefs = obj.func_defaults, closure = obj.func_closure)
|
||||
else:
|
||||
return copy.copy(obj)
|
||||
|
||||
|
||||
# Scalars
|
||||
def _nil_Q(exp): return exp is None
|
||||
def _true_Q(exp): return exp is True
|
||||
def _false_Q(exp): return exp is False
|
||||
def _string_Q(exp): return type(exp) in [str, unicode]
|
||||
def _string_Q(exp): return type(exp) in str_types
|
||||
|
||||
# Symbols
|
||||
class Symbol(str): pass
|
||||
@ -39,15 +60,12 @@ def _symbol_Q(exp): return type(exp) == Symbol
|
||||
|
||||
# Functions
|
||||
def _function(Eval, Env, ast, env, params):
|
||||
def gen_fn():
|
||||
def fn(*args):
|
||||
return Eval(ast, Env(env, params, args))
|
||||
fn.__meta__ = None
|
||||
fn.__ast__ = ast
|
||||
fn.__gen_env__ = lambda args: Env(env, params, args)
|
||||
fn.__copy__ = gen_fn
|
||||
return fn
|
||||
return gen_fn()
|
||||
def fn(*args):
|
||||
return Eval(ast, Env(env, params, args))
|
||||
fn.__meta__ = None
|
||||
fn.__ast__ = ast
|
||||
fn.__gen_env__ = lambda args: Env(env, params, args)
|
||||
return fn
|
||||
def _function_Q(f): return type(f) == type(function_Q)
|
||||
|
||||
# lists
|
||||
|
@ -13,7 +13,7 @@ def _pr_str(obj, print_readably=True):
|
||||
return "{" + " ".join(ret) + "}"
|
||||
elif types._string_Q(obj):
|
||||
if print_readably:
|
||||
return '"' + obj.encode('unicode_escape').replace('"', '\\"') + '"'
|
||||
return '"' + obj.encode('unicode_escape').decode('latin1').replace('"', '\\"') + '"'
|
||||
else:
|
||||
return obj
|
||||
elif types._nil_Q(obj):
|
||||
|
@ -27,4 +27,4 @@ while True:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -48,7 +48,7 @@ def REP(str):
|
||||
repl_env['+'] = lambda a,b: a+b
|
||||
repl_env['-'] = lambda a,b: a-b
|
||||
repl_env['*'] = lambda a,b: a*b
|
||||
repl_env['/'] = lambda a,b: a/b
|
||||
repl_env['/'] = lambda a,b: int(a/b)
|
||||
|
||||
while True:
|
||||
try:
|
||||
@ -58,4 +58,4 @@ while True:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -62,7 +62,7 @@ def _ref(k,v): repl_env.set(k, v)
|
||||
_ref('+', lambda a,b: a+b)
|
||||
_ref('-', lambda a,b: a-b)
|
||||
_ref('*', lambda a,b: a*b)
|
||||
_ref('/', lambda a,b: a/b)
|
||||
_ref('/', lambda a,b: int(a/b))
|
||||
|
||||
while True:
|
||||
try:
|
||||
@ -72,4 +72,4 @@ while True:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -88,4 +88,4 @@ while True:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -95,4 +95,4 @@ while True:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -103,4 +103,4 @@ else:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -125,4 +125,4 @@ else:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -145,4 +145,4 @@ else:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -154,4 +154,4 @@ else:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -89,7 +89,10 @@ def EVAL(ast, env):
|
||||
elif 'macroexpand' == a0:
|
||||
return macroexpand(ast[1], env)
|
||||
elif "py!*" == a0:
|
||||
exec compile(ast[1], '', 'single') in globals()
|
||||
if sys.version_info[0] >= 3:
|
||||
exec(compile(ast[1], '', 'single'), globals())
|
||||
else:
|
||||
exec(compile(ast[1], '', 'single') in globals())
|
||||
return None
|
||||
elif "py*" == a0:
|
||||
return eval(ast[1])
|
||||
@ -103,7 +106,7 @@ def EVAL(ast, env):
|
||||
try:
|
||||
return EVAL(a1, env);
|
||||
except Exception as exc:
|
||||
exc = exc.message
|
||||
exc = exc.args[0]
|
||||
catch_env = Env(env, [a2[1]], [exc])
|
||||
return EVAL(a2[2], catch_env)
|
||||
else:
|
||||
@ -168,4 +171,4 @@ else:
|
||||
print(REP(line))
|
||||
except reader.Blank: continue
|
||||
except Exception as e:
|
||||
print "".join(traceback.format_exception(*sys.exc_info()))
|
||||
print("".join(traceback.format_exception(*sys.exc_info())))
|
||||
|
@ -209,7 +209,7 @@
|
||||
(meta l-wm)
|
||||
;=>{"b" 2}
|
||||
|
||||
|
||||
;; Testing metadata on functions
|
||||
(def! f-wm (with-meta (fn* [a] (+ 1 a)) {"abc" 1}))
|
||||
(meta f-wm)
|
||||
;=>{"abc" 1}
|
||||
@ -224,6 +224,15 @@
|
||||
(meta f-wm2)
|
||||
;=>{"abc" 1}
|
||||
|
||||
;; Testing metadata on builtin functions
|
||||
(meta +)
|
||||
;=>nil
|
||||
(def! f-wm3 ^{"def" 2} +)
|
||||
(meta f-wm3)
|
||||
;=>{"def" 2}
|
||||
(meta +)
|
||||
;=>nil
|
||||
|
||||
;;
|
||||
;; Make sure closures and metadata co-exist
|
||||
(def! gen-plusX (fn* (x) (with-meta (fn* (b) (+ x b)) {"meta" 1})))
|
||||
|
Loading…
Reference in New Issue
Block a user