The spec's unwritten operators say so by name
error, find-restart and compute-restarts are named in spec-conditions.md and had no case in parse.ml, so each fell through to Call and came back as unknown name - the very shape the house rule exists to prevent, and the one that makes a missing feature look like a typo. Three message strings from the previous commit had their line continuations collapsed into runs of spaces. Rewrapped; no change to what they say.
This commit is contained in:
parent
ef712e3089
commit
ec0d845822
4
NEXT.md
4
NEXT.md
@ -25,7 +25,9 @@ already has the stack they would walk.
|
||||
Still open from §3, and each refused by name today: **restarts with
|
||||
parameters** (argument marshalling plus the runtime arity check), and
|
||||
`handler-case`, which §"What this does not settle" leaves open as possibly a
|
||||
macro over `handler-bind` plus a transfer.
|
||||
macro over `handler-bind` plus a transfer. `error`, `find-restart` and
|
||||
`compute-restarts` now refuse by name too — they used to fall through to a call
|
||||
and come back as *unknown name*, which is the house rule's own class of bug.
|
||||
|
||||
Read SBCL for what restarts should *mean* and ignore how it moves control: it
|
||||
transfers with `block`/`return-from`, which §6 rules out.
|
||||
|
||||
16
lib/parse.ml
16
lib/parse.ml
@ -237,7 +237,9 @@ and form f mk (head : Form.t) (args : Form.t list) : Ast.expr =
|
||||
when cbody <> [] ->
|
||||
if ps <> [] then
|
||||
fail c
|
||||
"a restart takes no parameters yet — spec-conditions.md §3 has them, and they need argument marshalling and a runtime arity check that this version does not do";
|
||||
"a restart takes no parameters yet — spec-conditions.md §3 has \
|
||||
them, and they need argument marshalling and a runtime arity \
|
||||
check that this version does not do";
|
||||
{ Ast.rname = n; rbody = List.map expr cbody; rloc = c.Form.loc }
|
||||
| _ -> fail c "a restart-case clause is (name [] body ...)"
|
||||
in
|
||||
@ -252,14 +254,22 @@ and form f mk (head : Form.t) (args : Form.t list) : Ast.expr =
|
||||
mk (Ast.InvokeRestart n)
|
||||
| [ _ ] ->
|
||||
fail f
|
||||
"invoke-restart takes a quoted restart name, as in (invoke-restart 'use-placeholder)"
|
||||
"invoke-restart takes a quoted restart name, as in \
|
||||
(invoke-restart 'use-placeholder)"
|
||||
| _ ->
|
||||
fail f
|
||||
"a restart takes no arguments yet — spec-conditions.md §3 has them, and they need argument marshalling and a runtime arity check that this version does not do")
|
||||
"a restart takes no arguments yet — spec-conditions.md §3 has them, \
|
||||
and they need argument marshalling and a runtime arity check that \
|
||||
this version does not do")
|
||||
|
||||
(* Recognised, deliberately unimplemented. Rejected rather than left to fall
|
||||
through to Call, where they would parse and mean nothing. *)
|
||||
| Sym ("handler-case"
|
||||
(* Named in the spec and not written yet, so each says so rather than
|
||||
falling through to Call and coming back as an unknown name: [error]
|
||||
is §2's diverging signal, and [find-restart] and [compute-restarts]
|
||||
are §4's two ways to look at the stack without committing. *)
|
||||
| "error" | "find-restart" | "compute-restarts"
|
||||
| "errdefer" | "with-allocator" | "loop" | "recur"
|
||||
| "defmacro" | "await" as name) ->
|
||||
fail f "%s is not implemented yet (see the build sequence in plan.org)" name
|
||||
|
||||
@ -691,9 +691,17 @@ let () =
|
||||
rejects_check "invoke-restart inside a defer"
|
||||
"(defn f [] i32 (defer (invoke-restart 'skip)) 0)"
|
||||
~needle:"not allowed inside a defer";
|
||||
(* Still unimplemented, and still says so by name. *)
|
||||
rejects_check "handler-case is still unimplemented"
|
||||
"(defn f [] (handler-case 1))" ~needle:"not implemented yet";
|
||||
(* Still unimplemented, and still says so by name — which is the point: an
|
||||
operator the spec names and the compiler lacks must not fall through to a
|
||||
call and come back as an unknown name. *)
|
||||
List.iter
|
||||
(fun (name, src) ->
|
||||
rejects_check (name ^ " is still unimplemented") src
|
||||
~needle:"not implemented yet")
|
||||
[ "handler-case", "(defn f [] (handler-case 1))";
|
||||
"error", "(defn f [] (error 1))";
|
||||
"find-restart", "(defn f [] (find-restart 'skip))";
|
||||
"compute-restarts", "(defn f [] (compute-restarts))" ];
|
||||
|
||||
(* ── The acceptance program checks end to end ──────────────────── *)
|
||||
accepts "calc-me.flan type checks"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user