diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/core.py | 10 | ||||
| -rw-r--r-- | python/mal_types.py | 7 | ||||
| -rw-r--r-- | python/printer.py | 4 | ||||
| -rw-r--r-- | python/reader.py | 3 | ||||
| -rw-r--r-- | python/step3_env.py | 8 | ||||
| -rw-r--r-- | python/step4_if_fn_do.py | 2 | ||||
| -rw-r--r-- | python/step5_tco.py | 2 | ||||
| -rw-r--r-- | python/step6_file.py | 6 | ||||
| -rw-r--r-- | python/step7_quote.py | 6 | ||||
| -rw-r--r-- | python/step8_macros.py | 6 | ||||
| -rw-r--r-- | python/step9_try.py | 8 | ||||
| -rw-r--r-- | python/stepA_interop.py | 6 |
12 files changed, 41 insertions, 27 deletions
diff --git a/python/core.py b/python/core.py index d10047d..4a64594 100644 --- a/python/core.py +++ b/python/core.py @@ -60,7 +60,9 @@ def cons(x, seq): return List([x]) + List(seq) def concat(*lsts): return List(chain(*lsts)) -def nth(lst, idx): return lst[idx] +def nth(lst, idx): + if idx < len(lst): return lst[idx] + else: throw("nth: index out of range") def first(lst): return lst[0] @@ -68,7 +70,9 @@ def rest(lst): return List(lst[1:]) def empty_Q(lst): return len(lst) == 0 -def count(lst): return len(lst) +def count(lst): + if types._nil_Q(lst): return 0 + else: return len(lst) # retains metadata def conj(lst, *args): @@ -114,6 +118,8 @@ ns = { 'false?': types._false_Q, 'symbol': types._symbol, 'symbol?': types._symbol_Q, + 'keyword': types._keyword, + 'keyword?': types._keyword_Q, 'pr-str': pr_str, 'str': do_str, diff --git a/python/mal_types.py b/python/mal_types.py index e6bd70d..5fb9bba 100644 --- a/python/mal_types.py +++ b/python/mal_types.py @@ -58,6 +58,13 @@ class Symbol(str): pass def _symbol(str): return Symbol(str) def _symbol_Q(exp): return type(exp) == Symbol +# Keywords +# A specially prefixed string +def _keyword(str): + if str[0] == u"\u029e": return str + else: return u"\u029e" + str +def _keyword_Q(exp): return _string_Q(exp) and exp[0] == u"\u029e" + # Functions def _function(Eval, Env, ast, env, params): def fn(*args): diff --git a/python/printer.py b/python/printer.py index 65bf256..78a2fcf 100644 --- a/python/printer.py +++ b/python/printer.py @@ -12,7 +12,9 @@ def _pr_str(obj, print_readably=True): ret.extend((_pr_str(k), _pr_str(obj[k],_r))) return "{" + " ".join(ret) + "}" elif types._string_Q(obj): - if print_readably: + if len(obj) > 0 and obj[0] == u'\u029e': + return ':' + obj[1:] + elif print_readably: return '"' + obj.encode('unicode_escape').decode('latin1').replace('"', '\\"') + '"' else: return obj diff --git a/python/reader.py b/python/reader.py index 13b1f7b..71ad3d6 100644 --- a/python/reader.py +++ b/python/reader.py @@ -1,5 +1,5 @@ import re -from mal_types import (_symbol, _list, _vector, _hash_map) +from mal_types import (_symbol, _keyword, _list, _vector, _hash_map) class Blank(Exception): pass @@ -29,6 +29,7 @@ def read_atom(reader): if re.match(int_re, token): return int(token) elif re.match(float_re, token): return int(token) elif token[0] == '"': return token[1:-1].replace('\\"', '"') + elif token[0] == ':': return _keyword(token[1:]) elif token == "nil": return None elif token == "true": return True elif token == "false": return False diff --git a/python/step3_env.py b/python/step3_env.py index 4565011..86dc176 100644 --- a/python/step3_env.py +++ b/python/step3_env.py @@ -58,10 +58,10 @@ repl_env = Env() def REP(str): return PRINT(EVAL(READ(str), repl_env)) -repl_env.set('+', lambda a,b: a+b) -repl_env.set('-', lambda a,b: a-b) -repl_env.set('*', lambda a,b: a*b) -repl_env.set('/', lambda a,b: int(a/b)) +repl_env.set(types._symbol('+'), lambda a,b: a+b) +repl_env.set(types._symbol('-'), lambda a,b: a-b) +repl_env.set(types._symbol('*'), lambda a,b: a*b) +repl_env.set(types._symbol('/'), lambda a,b: int(a/b)) # repl loop while True: diff --git a/python/step4_if_fn_do.py b/python/step4_if_fn_do.py index e99cfcf..39b9dd6 100644 --- a/python/step4_if_fn_do.py +++ b/python/step4_if_fn_do.py @@ -74,7 +74,7 @@ def REP(str): return PRINT(EVAL(READ(str), repl_env)) # core.py: defined using python -for k, v in core.ns.items(): repl_env.set(k, v) +for k, v in core.ns.items(): repl_env.set(types._symbol(k), v) # core.mal: defined using the language itself REP("(def! not (fn* (a) (if a false true)))") diff --git a/python/step5_tco.py b/python/step5_tco.py index cbb92c9..da338d4 100644 --- a/python/step5_tco.py +++ b/python/step5_tco.py @@ -83,7 +83,7 @@ def REP(str): return PRINT(EVAL(READ(str), repl_env)) # core.py: defined using python -for k, v in core.ns.items(): repl_env.set(k, v) +for k, v in core.ns.items(): repl_env.set(types._symbol(k), v) # core.mal: defined using the language itself REP("(def! not (fn* (a) (if a false true)))") diff --git a/python/step6_file.py b/python/step6_file.py index 9d84d1f..5d10b46 100644 --- a/python/step6_file.py +++ b/python/step6_file.py @@ -83,9 +83,9 @@ def REP(str): return PRINT(EVAL(READ(str), repl_env)) # core.py: defined using python -for k, v in core.ns.items(): repl_env.set(k, v) -repl_env.set('eval', lambda ast: EVAL(ast, repl_env)) -repl_env.set('*ARGV*', types._list(*sys.argv[2:])) +for k, v in core.ns.items(): repl_env.set(types._symbol(k), v) +repl_env.set(types._symbol('eval'), lambda ast: EVAL(ast, repl_env)) +repl_env.set(types._symbol('*ARGV*'), types._list(*sys.argv[2:])) # core.mal: defined using the language itself REP("(def! not (fn* (a) (if a false true)))") diff --git a/python/step7_quote.py b/python/step7_quote.py index de19c6d..7c97c23 100644 --- a/python/step7_quote.py +++ b/python/step7_quote.py @@ -106,9 +106,9 @@ def REP(str): return PRINT(EVAL(READ(str), repl_env)) # core.py: defined using python -for k, v in core.ns.items(): repl_env.set(k, v) -repl_env.set('eval', lambda ast: EVAL(ast, repl_env)) -repl_env.set('*ARGV*', types._list(*sys.argv[2:])) +for k, v in core.ns.items(): repl_env.set(types._symbol(k), v) +repl_env.set(types._symbol('eval'), lambda ast: EVAL(ast, repl_env)) +repl_env.set(types._symbol('*ARGV*'), types._list(*sys.argv[2:])) # core.mal: defined using the language itself REP("(def! not (fn* (a) (if a false true)))") diff --git a/python/step8_macros.py b/python/step8_macros.py index 80ca239..da863c1 100644 --- a/python/step8_macros.py +++ b/python/step8_macros.py @@ -126,9 +126,9 @@ def REP(str): return PRINT(EVAL(READ(str), repl_env)) # core.py: defined using python -for k, v in core.ns.items(): repl_env.set(k, v) -repl_env.set('eval', lambda ast: EVAL(ast, repl_env)) -repl_env.set('*ARGV*', types._list(*sys.argv[2:])) +for k, v in core.ns.items(): repl_env.set(types._symbol(k), v) +repl_env.set(types._symbol('eval'), lambda ast: EVAL(ast, repl_env)) +repl_env.set(types._symbol('*ARGV*'), types._list(*sys.argv[2:])) # core.mal: defined using the language itself REP("(def! not (fn* (a) (if a false true)))") diff --git a/python/step9_try.py b/python/step9_try.py index 65da08c..e01f42c 100644 --- a/python/step9_try.py +++ b/python/step9_try.py @@ -143,12 +143,11 @@ def REP(str): return PRINT(EVAL(READ(str), repl_env)) # core.py: defined using python -for k, v in core.ns.items(): repl_env.set(k, v) -repl_env.set('eval', lambda ast: EVAL(ast, repl_env)) -repl_env.set('*ARGV*', types._list(*sys.argv[2:])) +for k, v in core.ns.items(): repl_env.set(types._symbol(k), v) +repl_env.set(types._symbol('eval'), lambda ast: EVAL(ast, repl_env)) +repl_env.set(types._symbol('*ARGV*'), types._list(*sys.argv[2:])) # core.mal: defined using the language itself -REP("(def! *host-language* \"python\")") REP("(def! not (fn* (a) (if a false true)))") REP("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))") REP("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))") @@ -159,7 +158,6 @@ if len(sys.argv) >= 2: sys.exit(0) # repl loop -REP("(println (str \"Mal [\" *host-language* \"]\"))") while True: try: line = mal_readline.readline("user> ") diff --git a/python/stepA_interop.py b/python/stepA_interop.py index 723f0ed..93cdb2e 100644 --- a/python/stepA_interop.py +++ b/python/stepA_interop.py @@ -149,9 +149,9 @@ def REP(str): return PRINT(EVAL(READ(str), repl_env)) # core.py: defined using python -for k, v in core.ns.items(): repl_env.set(k, v) -repl_env.set('eval', lambda ast: EVAL(ast, repl_env)) -repl_env.set('*ARGV*', types._list(*sys.argv[2:])) +for k, v in core.ns.items(): repl_env.set(types._symbol(k), v) +repl_env.set(types._symbol('eval'), lambda ast: EVAL(ast, repl_env)) +repl_env.set(types._symbol('*ARGV*'), types._list(*sys.argv[2:])) # core.mal: defined using the language itself REP("(def! *host-language* \"python\")") |
