1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-11 13:55:55 +03:00

guide clarifications, but order for step5 tests.

This commit is contained in:
Joel Martin 2015-03-14 17:34:49 -05:00
parent dbac60df00
commit 4e7296f90a
2 changed files with 23 additions and 20 deletions

View File

@ -770,8 +770,8 @@ diff -urp ../process/step4_if_fn_do.txt ../process/step5_tco.txt
`EVAL`) to be the second `ast` argument. Continue at the beginning
of the loop (no return).
* `do`: change the `eval_ast` call to evaluate all the parameters
the except for the last (2nd list element up to but not
including last). Set `ast` to the last element of `ast`. Continue
except for the last (2nd list element up to but not including
last). Set `ast` to the last element of `ast`. Continue
at the beginning of the loop (`env` stays unchanged).
* `if`: the condition continues to be evaluated, however, rather
than evaluating the true or false branch, `ast` is set to the
@ -781,21 +781,21 @@ diff -urp ../process/step4_if_fn_do.txt ../process/step5_tco.txt
* The return value from the `fn*` special form will now become an
object/structure with attributes that allow the default invoke case
of `EVAL` to do TCO on mal functions. Those attributes are:
* `fn`: the original function value return in step 4 (this is
actually deferrable until step 9 when it is needed for the `map`
and `apply` core functions).
* `ast`: the second `ast` argument (third list element) representing
the body of the function.
* `params`: the first `ast` argument (second list element)
representing the parameter names of the function.
* `env`: the current value of the `env` parameter of `EVAL`.
* `fn`: the original function value (i.e. what was return by `fn*`
in step 4). Note that this is deferrable until step 9 when it is
needed for the `map` and `apply` core functions).
* The default "apply"/invoke case of `EVAL` must now be changed to
account for the new object/structure returned by the `fn*` form.
Continue to call `eval_ast` on `ast`. The first element is `f`.
Switch on the type of `f`:
* regular function (not one defined by `fn*`): apply/invoke it as
* before (in step 4).
before (in step 4).
* a `fn*` value: set `ast` to the `ast` attribute of `f`. Generate
a new environment using the `env` and `params` attributes of `f`
as the `outer` and `binds` arguments and rest `ast` arguments

View File

@ -1,17 +1,3 @@
;; Test recursive non-tail call function
(def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1))))))
(sum-to 10)
;=>55
;;; no try* yet, so test completion of side-effects
(def! res1 nil)
;=>nil
(def! res1 (sum-to 10000))
res1
;=>nil
;; Testing recursive tail-call function
(def! sum2 (fn* (n acc) (if (= n 0) acc (sum2 (- n 1) (+ n acc)))))
@ -25,3 +11,20 @@ res1
res2
;=>50005000
;; Test recursive non-tail call function
(def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1))))))
(sum-to 10)
;=>55
;;; no try* yet, so test completion of side-effects
(def! res1 nil)
;=>nil
;;; For implementations without their own TCO this should fail and
;;; leave res1 unchanged
(def! res1 (sum-to 10000))
res1
;=>nil