summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2017-11-13 23:20:17 -0500
committerOwen Jacobson <owen@grimoire.ca>2017-11-13 23:20:17 -0500
commit4bf7cea31d2c9bb123488099b11235ea05092ef4 (patch)
tree30b980f2158df0d0df60c42376ecb0c72795d3d2
parent9e48ca28fe335f07d00d4c4469255ecde8df7325 (diff)
`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.
-rw-r--r--actinide/core.py6
-rw-r--r--actinide/evaluator.py5
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))