A recur from an arm of a match over an enum is in tail position, and a session's blind spot for macros an expansion defines is recorded
This commit is contained in:
parent
e9e151e1a4
commit
60ef7b2e06
6
TODO.org
6
TODO.org
@ -90,6 +90,12 @@ expansion that defines a macro re-runs the expander. =~~@x= is refused. There is
|
||||
no =,',x=, since =quote= takes a symbol, and a macro defined by an expansion is
|
||||
not exported from a package. docs/BUILT.md, "Quasiquote runs before the walk".
|
||||
|
||||
** TODO A session does not remember a macro that an expansion defined
|
||||
=Session.own_macros= reads =defmacro= heads off the forms as sent, so after
|
||||
=(defsquare sq)= is evaluated the session's next form cannot call =sq=. A build
|
||||
sees the whole file and can. The fix is collecting from the expanded forms,
|
||||
which =Load.program= does not hand back.
|
||||
|
||||
** DONE until and cond are prelude macros; when and dotimes stay special forms
|
||||
CLOSED: [2026-09-25]
|
||||
=cond= builds its chain through the prelude function =cond-chain= and refuses
|
||||
|
||||
@ -601,10 +601,10 @@ let loaded_for (forms : Form.t list) : loaded option =
|
||||
List.filter (fun (n, _) -> Hashtbl.mem taken n) mine
|
||||
in
|
||||
let all = prelude @ List.map fst mine in
|
||||
(* The common case by a wide margin, and the reason a build that uses no
|
||||
macro pays nothing: a file that calls none costs one scan and no
|
||||
compiler. Without it every build in the suite would link a macro module
|
||||
for the prelude's macros and pay a clang driver to answer nothing. *)
|
||||
(* A file that calls no macro costs one scan and no module. Few do, since
|
||||
cond is a macro; for a file with no macros of its own the module is the
|
||||
prelude's alone, one cached .so shared by every such file, so the usual
|
||||
cost is a stat and a dlopen. *)
|
||||
if all = [] || not (List.exists (names_macro all) forms) then None
|
||||
else begin
|
||||
let extra = rounds ~prelude mine in
|
||||
|
||||
@ -25,7 +25,15 @@
|
||||
(calls)
|
||||
:west)
|
||||
|
||||
;; recur from inside an arm: the arm is the loop's tail.
|
||||
(defn steps-to-west [from Dir] i32
|
||||
(loop [d from n 0]
|
||||
(match d
|
||||
:west n
|
||||
_ (recur (turn d) (+ n 1)))))
|
||||
|
||||
(defn main [] i32
|
||||
(print (steps-to-west :north)) (println "")
|
||||
(println (name :north))
|
||||
(println (name (turn :north)))
|
||||
(println (name (turn (turn :north))))
|
||||
|
||||
@ -423,7 +423,7 @@ let () =
|
||||
(* match over an enum lowers to a chain of [=] over one temporary, so
|
||||
"(called) " printed once is the scrutinee evaluated once. *)
|
||||
let match_enum_out =
|
||||
"north\nsideways\nsouth\n(called) sideways\nback to north\n"
|
||||
"3\nnorth\nsideways\nsouth\n(called) sideways\nback to north\n"
|
||||
in
|
||||
outputs "match over an enum" "programs/match-enum.flan" match_enum_out;
|
||||
outputs ~opt:"-O0" "match over an enum, -O0" "programs/match-enum.flan"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user