aboutsummaryrefslogtreecommitdiff
path: root/python/core.py
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-04-02 22:23:37 -0500
committerJoel Martin <github@martintribe.org>2014-04-02 22:23:37 -0500
commitea81a8087bcd7953b083a2be9db447f75e7ebf56 (patch)
tree6cf47a2dbd55d42efc4a901eaabdec952f40ce89 /python/core.py
parent1617910ad342a55762f3ddabb975849d843cff85 (diff)
downloadmal-ea81a8087bcd7953b083a2be9db447f75e7ebf56.tar.gz
mal-ea81a8087bcd7953b083a2be9db447f75e7ebf56.zip
All: split types into types, env, printer, core.
- types: low-level mapping to the implementation language. - core: functions on types that are exposed directly to mal. - printer: implementation called by pr-str, str, prn, println. - env: the environment implementation - Also, unindent all TCO while loops so that the diff of step4 and step5 are minimized.
Diffstat (limited to 'python/core.py')
-rw-r--r--python/core.py159
1 files changed, 159 insertions, 0 deletions
diff --git a/python/core.py b/python/core.py
new file mode 100644
index 0000000..92ae3d9
--- /dev/null
+++ b/python/core.py
@@ -0,0 +1,159 @@
+import copy
+from itertools import chain
+
+import mal_types as types
+from mal_types import List, Vector
+import printer
+
+# Errors/Exceptions
+def throw(exc): raise Exception(exc)
+
+
+# String functions
+def pr_str(*args):
+ return " ".join(map(lambda exp: printer._pr_str(exp, True), args))
+
+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))
+ return None
+
+def println(*args):
+ line = " ".join(map(lambda exp: printer._pr_str(exp, False), args))
+ print line.replace('\\n', '\n')
+ return None
+
+
+# Hash map functions
+def assoc(src_hm, *key_vals):
+ hm = copy.copy(src_hm)
+ for i in range(0,len(key_vals),2): hm[key_vals[i]] = key_vals[i+1]
+ return hm
+
+def dissoc(src_hm, *keys):
+ hm = copy.copy(src_hm)
+ for key in keys: del hm[key]
+ return hm
+
+def get(hm, key):
+ if key in hm:
+ return hm[key]
+ else:
+ return None
+
+def contains_Q(hm, key): return key in hm
+
+def keys(hm): return types._list(*hm.keys())
+
+def vals(hm): return types._list(*hm.values())
+
+
+# Sequence functions
+def coll_Q(coll): return sequential_Q(coll) or hash_map_Q(coll)
+
+def cons(x, seq): return List([x]) + List(seq)
+
+def concat(*lsts): return List(chain(*lsts))
+
+def nth(lst, idx): return lst[idx]
+
+def first(lst): return lst[0]
+
+def rest(lst): return List(lst[1:])
+
+def empty_Q(lst): return len(lst) == 0
+
+def count(lst): return len(lst)
+
+# retains metadata
+def conj(lst, *args):
+ if types._list_Q(lst):
+ new_lst = List(list(reversed(list(args))) + lst)
+ else:
+ new_lst = Vector(lst + list(args))
+ if hasattr(lst, "__meta__"):
+ new_lst.__meta__ = lst.__meta__
+ return new_lst
+
+def apply(f, *args): return f(*(list(args[0:-1])+args[-1]))
+
+def mapf(f, lst): return List(map(f, lst))
+
+
+# Metadata functions
+def with_meta(obj, meta):
+ new_obj = copy.copy(obj)
+ new_obj.__meta__ = meta
+ return new_obj
+
+def meta(obj):
+ if hasattr(obj, "__meta__"): return obj.__meta__
+ else: return None
+
+
+# Atoms functions
+def deref(atm): return atm.val
+def reset_BANG(atm,val):
+ atm.val = val
+ return atm.val
+def swap_BANG(atm,f,*args):
+ atm.val = f(atm.val,*args)
+ return atm.val
+
+
+ns = {
+ '=': types._equal_Q,
+ 'throw': throw,
+ 'nil?': types._nil_Q,
+ 'true?': types._true_Q,
+ 'false?': types._false_Q,
+ 'symbol': types._symbol,
+ 'symbol?': types._symbol_Q,
+ 'pr-str': pr_str,
+ 'str': do_str,
+ 'prn': prn,
+ 'println': println,
+ '<': lambda a,b: a<b,
+ '<=': lambda a,b: a<=b,
+ '>': lambda a,b: a>b,
+ '>=': lambda a,b: a>=b,
+ '+': lambda a,b: a+b,
+ '-': lambda a,b: a-b,
+ '*': lambda a,b: a*b,
+ '/': lambda a,b: a/b,
+
+ 'list': types._list,
+ 'list?': types._list_Q,
+ 'vector': types._vector,
+ 'vector?': types._vector_Q,
+ 'hash-map': types._hash_map,
+ 'map?': types._hash_map_Q,
+ 'assoc': assoc,
+ 'dissoc': dissoc,
+ 'get': get,
+ 'contains?': contains_Q,
+ 'keys': keys,
+ 'vals': vals,
+
+ 'sequential?': types._sequential_Q,
+ 'cons': cons,
+ 'concat': concat,
+ 'nth': nth,
+ 'first': first,
+ 'rest': rest,
+ 'empty?': empty_Q,
+ 'count': count,
+ 'conj': conj,
+ 'apply': apply,
+ 'map': mapf,
+
+ 'with-meta': with_meta,
+ 'meta': meta,
+ 'atom': types._atom,
+ 'atom?': types._atom_Q,
+ 'deref': deref,
+ 'reset!': reset_BANG,
+ 'swap!': swap_BANG}
+