Only a place has an address in the inspector, and a watched dyn value and string are pinned armed
This commit is contained in:
parent
377ada8d27
commit
cda939c8be
9
TODO.org
9
TODO.org
@ -1724,10 +1724,11 @@ with the selected frame's locals.
|
|||||||
** DONE Hex, binary and an address on a primitive in the inspector
|
** DONE Hex, binary and an address on a primitive in the inspector
|
||||||
CLOSED: [2026-09-25]
|
CLOSED: [2026-09-25]
|
||||||
Hex and binary were already drawn under every integer. The slot root's reply
|
Hex and binary were already drawn under every integer. The slot root's reply
|
||||||
now carries =:addr=, the address of the place it read (a field or element down
|
now carries =:addr=, the address of the place it read, a field, element or
|
||||||
a path included), and the inspector shows it as =at 0x…=. An expression root has
|
option payload down a path included, and the inspector shows it as =at 0x…=. A
|
||||||
no address, because its value is not stored anywhere. A stack address is not
|
data case's field and an expression root's value are not places and carry none,
|
||||||
offered to =flan-inspect-address=, since the registry does not follow one.
|
rather than the address of a copy. A stack address is not offered to
|
||||||
|
=flan-inspect-address=, since the registry does not follow one.
|
||||||
|
|
||||||
** DONE A defclass is not on the definitions list as a type, and a sum's cases are not drawn
|
** DONE A defclass is not on the definitions list as a type, and a sum's cases are not drawn
|
||||||
CLOSED: [2026-09-25]
|
CLOSED: [2026-09-25]
|
||||||
|
|||||||
@ -778,6 +778,7 @@ drawn from."
|
|||||||
(get-text-property pos 'flan-cnr-abort)
|
(get-text-property pos 'flan-cnr-abort)
|
||||||
(get-text-property pos 'flan-cnr-frame)
|
(get-text-property pos 'flan-cnr-frame)
|
||||||
(get-text-property pos 'flan-cnr-hidden)
|
(get-text-property pos 'flan-cnr-hidden)
|
||||||
|
(get-text-property pos 'flan-cnr-loc)
|
||||||
(get-text-property pos 'flan-cnr-inspect)))
|
(get-text-property pos 'flan-cnr-inspect)))
|
||||||
|
|
||||||
(defun flan-cnr-tab ()
|
(defun flan-cnr-tab ()
|
||||||
|
|||||||
@ -1681,28 +1681,33 @@ let render_slot ?(origin = "<inspect>") t ~frame ~(fn : Tast.fn) ~slot ~path
|
|||||||
(match Render.render c 0 v with
|
(match Render.render c 0 v with
|
||||||
| exception Loc.Error { Loc.dmsg = why; _ } -> Error (name ^ path_text path ^ ": " ^ why)
|
| exception Loc.Error { Loc.dmsg = why; _ } -> Error (name ^ path_text path ^ ": " ^ why)
|
||||||
| parts ->
|
| parts ->
|
||||||
(* Where the value lives, first and on a line of its own: [v] is
|
(* Where the value lives, first and on a line of its own, when [v]
|
||||||
a place in the stopped frame, so its address is the storage
|
is a place in the stopped frame: its address is then the
|
||||||
the listing is reading. The caller splits it off at the first
|
storage the listing is reading. A data case's field is not a
|
||||||
newline; a rendering has none, because [Render] quotes a
|
place — [AddrOf] on it would answer the address of a copy — so
|
||||||
|
it has no address line. The caller splits the line off at the
|
||||||
|
first newline; a rendering has none, because [Render] quotes a
|
||||||
string's. *)
|
string's. *)
|
||||||
let addr =
|
|
||||||
{ Tast.e =
|
|
||||||
Tast.Prim
|
|
||||||
(Tast.Cast (Types.Int Types.I64),
|
|
||||||
[ { Tast.e = Tast.Prim (Tast.AddrOf, [ v ]);
|
|
||||||
ty = Types.Ptr v.Tast.ty; loc } ]);
|
|
||||||
ty = Types.Int Types.I64; loc }
|
|
||||||
in
|
|
||||||
let newline =
|
|
||||||
{ Tast.e =
|
|
||||||
Tast.Prim
|
|
||||||
(Tast.Bytes, [ { Tast.e = Tast.Str "\n"; ty = Types.String; loc } ]);
|
|
||||||
ty = Types.Slice (Types.Int Types.U8); loc }
|
|
||||||
in
|
|
||||||
let parts =
|
let parts =
|
||||||
dev_emitter.Render.ei64 addr :: dev_emitter.Render.ebytes newline
|
if not (Emit.addr_is_place v) then parts
|
||||||
:: parts
|
else
|
||||||
|
let addr =
|
||||||
|
{ Tast.e =
|
||||||
|
Tast.Prim
|
||||||
|
(Tast.Cast (Types.Int Types.I64),
|
||||||
|
[ { Tast.e = Tast.Prim (Tast.AddrOf, [ v ]);
|
||||||
|
ty = Types.Ptr v.Tast.ty; loc } ]);
|
||||||
|
ty = Types.Int Types.I64; loc }
|
||||||
|
in
|
||||||
|
let newline =
|
||||||
|
{ Tast.e =
|
||||||
|
Tast.Prim
|
||||||
|
(Tast.Bytes,
|
||||||
|
[ { Tast.e = Tast.Str "\n"; ty = Types.String; loc } ]);
|
||||||
|
ty = Types.Slice (Types.Int Types.U8); loc }
|
||||||
|
in
|
||||||
|
dev_emitter.Render.ei64 addr :: dev_emitter.Render.ebytes newline
|
||||||
|
:: parts
|
||||||
in
|
in
|
||||||
let nullary n = { Tast.e = Tast.Call (n, []); ty = Types.Unit; loc } in
|
let nullary n = { Tast.e = Tast.Call (n, []); ty = Types.Unit; loc } in
|
||||||
t.thunks <- t.thunks + 1;
|
t.thunks <- t.thunks + 1;
|
||||||
|
|||||||
@ -41,6 +41,10 @@
|
|||||||
(watch "pos" (Pos {.x 3 .y 1.5}))
|
(watch "pos" (Pos {.x 3 .y 1.5}))
|
||||||
(watch "row" [1 2 3])
|
(watch "row" [1 2 3])
|
||||||
(watch "t2" (* ticks 2))
|
(watch "t2" (* ticks 2))
|
||||||
|
;; A dyn value renders through the dyn printer into the slot, and a string
|
||||||
|
;; through the form is quoted.
|
||||||
|
(watch "d" {:a 1})
|
||||||
|
(watch "s" "x")
|
||||||
;; A hot inner loop, and the value *varies* across it — which is what makes
|
;; A hot inner loop, and the value *varies* across it — which is what makes
|
||||||
;; the row a test of the accumulator rather than of the plumbing. A slot that
|
;; the row a test of the accumulator rather than of the plumbing. A slot that
|
||||||
;; only kept [last] would report 21 and no range; n, min and max are each
|
;; only kept [last] would report 21 and no range; n, min and max are each
|
||||||
|
|||||||
@ -1368,7 +1368,9 @@ let () =
|
|||||||
(* The site, on LLVM: an arith trap publishes its loc around the
|
(* The site, on LLVM: an arith trap publishes its loc around the
|
||||||
hook exactly as a bounds trap does. *)
|
hook exactly as a bounds trap does. *)
|
||||||
(match Wire.string_field (ask "(:op \"break\")") "site" with
|
(match Wire.string_field (ask "(:op \"break\")") "site" with
|
||||||
| Some site when contains_sub site "dev-break.flan:" -> ()
|
(* Absolute, because the break buffer opens the file it names and
|
||||||
|
an editor is not in this process's working directory. *)
|
||||||
|
| Some site when contains_sub site "dev-break.flan:" && site.[0] = '/' -> ()
|
||||||
| Some site -> fail "the arith site points at %s" site
|
| Some site -> fail "the arith site points at %s" site
|
||||||
| None -> fail "a division by zero carries no :site");
|
| None -> fail "a division by zero carries no :site");
|
||||||
let r = ask "(:op \"restart\" :name \"use-zero\")" in
|
let r = ask "(:op \"restart\" :name \"use-zero\")" in
|
||||||
@ -2385,6 +2387,29 @@ let () =
|
|||||||
if Int64.sub y x <> 4L then
|
if Int64.sub y x <> 4L then
|
||||||
fail "mark.y is %Ld bytes past mark.x, not 4" (Int64.sub y x)
|
fail "mark.y is %Ld bytes past mark.x, not 4" (Int64.sub y x)
|
||||||
| _ -> fail "inspect on a slot answered with no :addr"));
|
| _ -> fail "inspect on a slot answered with no :addr"));
|
||||||
|
(let addr name path =
|
||||||
|
match slot_of listing name with
|
||||||
|
| None -> None
|
||||||
|
| Some slot ->
|
||||||
|
(match Wire.field (inspect ~path slot) "addr" with
|
||||||
|
| Some { Form.v = Form.Int a; _ } -> Some a
|
||||||
|
| _ -> None)
|
||||||
|
in
|
||||||
|
(* An element is its index's worth of elements past the first. *)
|
||||||
|
(match addr "xs" "()", addr "xs" "(1)" with
|
||||||
|
| Some a, Some b when Int64.sub b a = 4L -> ()
|
||||||
|
| a, b ->
|
||||||
|
fail "xs[1] is not one i32 past xs: %s, %s"
|
||||||
|
(Option.fold ~none:"none" ~some:Int64.to_string a)
|
||||||
|
(Option.fold ~none:"none" ~some:Int64.to_string b));
|
||||||
|
(* An option's payload is inside the option's own storage. *)
|
||||||
|
(match addr "box" "()", addr "box" "(some)" with
|
||||||
|
| Some a, Some b when b > a && Int64.sub b a < 16L -> ()
|
||||||
|
| _ -> fail "box's payload is not inside box's storage");
|
||||||
|
(* A data case's field has no accessor place to take the address
|
||||||
|
of, and says nothing rather than a copy's address. *)
|
||||||
|
if addr "s" "(\"Shape.Rect.w\")" <> None then
|
||||||
|
fail "a data case's field answered with an address");
|
||||||
(* Emacs prints an empty list as `nil' and has no other spelling for
|
(* Emacs prints an empty list as `nil' and has no other spelling for
|
||||||
one, so a client in that language cannot send `()'. *)
|
one, so a client in that language cannot send `()'. *)
|
||||||
(match slot_of listing "mark" with
|
(match slot_of listing "mark" with
|
||||||
@ -3921,6 +3946,14 @@ let () =
|
|||||||
| Some v when int_of_string_opt v <> None -> ()
|
| Some v when int_of_string_opt v <> None -> ()
|
||||||
| Some v -> fail "watch rendered a computed i64 as %s" v
|
| Some v -> fail "watch rendered a computed i64 as %s" v
|
||||||
| None -> fail "the (watch ...) form never wrote a scalar");
|
| None -> fail "the (watch ...) form never wrote a scalar");
|
||||||
|
(match List.assoc_opt "d" t with
|
||||||
|
| Some "{ :a 1}" -> ()
|
||||||
|
| Some v -> fail "watch rendered a dyn map as %s" v
|
||||||
|
| None -> fail "the (watch ...) form never wrote a dyn value");
|
||||||
|
(match List.assoc_opt "s" t with
|
||||||
|
| Some "\"x\"" -> ()
|
||||||
|
| Some v -> fail "the (watch ...) form rendered a string as %s" v
|
||||||
|
| None -> fail "the (watch ...) form never wrote a string");
|
||||||
(* The accumulator, which is the other half of the watch and the
|
(* The accumulator, which is the other half of the watch and the
|
||||||
half a scalar row cannot stand in for. [loop-cells] samples "cell"
|
half a scalar row cannot stand in for. [loop-cells] samples "cell"
|
||||||
eight times per step at 0, 3, ... 21, so the row has to show a
|
eight times per step at 0, 3, ... 21, so the row has to show a
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user