From 4bf7cea31d2c9bb123488099b11235ea05092ef4 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Mon, 13 Nov 2017 23:20:17 -0500 Subject: `begin` is now a special form. Two reasons: 1. Making it a builtin defeats tail call optimization, as builtins do not participate in TCO. 2. The `begin` form is occasionally generated by the macro expander, and should not rely on library support. --- actinide/core.py | 6 ------ actinide/evaluator.py | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/actinide/core.py b/actinide/core.py index 1b4c800..467f04f 100644 --- a/actinide/core.py +++ b/actinide/core.py @@ -3,12 +3,6 @@ from .builtin import make_registry ACTINIDE_BINDINGS, ACTINIDE_VOIDS, ACTINIDE_FNS, ACTINIDE_BUILTINS, bind, void, fn, builtin = make_registry() -@fn -def begin(*args): - if args: - return args[-1] - return None - @builtin def values(*args): return args diff --git a/actinide/evaluator.py b/actinide/evaluator.py index af25908..fe2e4c2 100644 --- a/actinide/evaluator.py +++ b/actinide/evaluator.py @@ -101,6 +101,9 @@ def branch(on_true, on_false): def append(args, continuation): return lambda environment, *tail: (continuation, environment, *args, *tail) +def begin(continuation): + return lambda environment, *args: (continuation, environment, *(args[-1:] if args else ())) + # Transforms a continuation which should receive function results into a # function call continuation. A function call continuation receives a function # and a sequence of arguments. If the function is a primitive function, the @@ -171,6 +174,8 @@ def eval(value, symbols, continuation): return define(t.tail(value), symbols, continuation) if t.head(value) == symbols['lambda']: return lambda_(t.tail(value), symbols, continuation) + if t.head(value) == symbols['begin']: + return apply(t.tail(value), symbols, begin(continuation)) # Ran out of alternatives, must be a function application return apply(value, symbols, invoke(continuation)) -- cgit v1.2.3