Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live Projectors #1420

Open
wants to merge 157 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
157 commits
Select commit Hold shift + click to select a range
881a086
projectors live init: an attempt at extracing vals for projectors: in…
disconcision Nov 20, 2024
1d07174
clarify live projector statics
disconcision Nov 20, 2024
08c21d1
live projectors view layer. minimal poc complete
disconcision Nov 20, 2024
535ec65
merge
disconcision Nov 25, 2024
dfbd034
rename Dynamics
disconcision Nov 25, 2024
376f411
dynamics probes for live projectors. experiment with ExpToSegment
disconcision Nov 25, 2024
09d08e9
projector probes have access to values and reference environments
disconcision Nov 30, 2024
4ce84f1
surface projector probe reference environment display on hover
disconcision Dec 4, 2024
323338f
typo
disconcision Dec 6, 2024
34b27e4
Merge branch 'editor-output' of github.com:hazelgrove/hazel into proj…
disconcision Dec 6, 2024
48ee429
basic value abbreviator
disconcision Dec 7, 2024
ce355ab
drag to resize value abbreviations
disconcision Dec 9, 2024
4415b81
simple persistent closure cursor
disconcision Dec 10, 2024
5e93bc6
closureenv cleanup. probe style tweaks
disconcision Dec 10, 2024
18c4751
live projectors cleanup
disconcision Dec 10, 2024
2f94e7a
live projectors view cleanup
disconcision Dec 11, 2024
0ee836b
live projectors in exercises mode
disconcision Dec 11, 2024
0af9929
alt/option-v to toggle probes. partial fix to projector panel desync bug
disconcision Dec 11, 2024
8dd2f78
probe projectors: better logic for closure co-inhabitation. better style
disconcision Dec 13, 2024
fffd013
clean up live projectors maketerm
disconcision Dec 16, 2024
dc8ebfe
projectors live cleanup
disconcision Dec 16, 2024
d64e739
projectors live cleanup
disconcision Dec 16, 2024
18ceb80
accidentally a dir
disconcision Dec 16, 2024
1ea2ac4
live projectors cleanup
disconcision Dec 16, 2024
31c8e72
merge fix
disconcision Dec 16, 2024
953e4a2
truncate probe projector closures lists after 30 items, controls to s…
disconcision Dec 19, 2024
6da6244
probe projectors on patterns
disconcision Dec 22, 2024
bfe13af
fixed bug with wrong env being passed to live projectors on function …
disconcision Dec 22, 2024
8ea387e
better styling for live pat probe
disconcision Dec 22, 2024
6fb7a52
probe projector ap descent indication
disconcision Dec 28, 2024
8640845
probe projector ap indication in patterns. css cleanup
disconcision Dec 28, 2024
9ce7709
style deeper stack ap indications differently than first degree
disconcision Dec 29, 2024
10c3a35
projector API flag for dynamics collection
disconcision Dec 29, 2024
527d392
all probe cells now individually resizable
disconcision Dec 29, 2024
b4ddee2
fix binding not found bug
disconcision Jan 2, 2025
d6d4b20
telescope (ap) probes style
disconcision Jan 6, 2025
4ae4695
fix issue with projector metrics being misaligned in stepper. fix pro…
disconcision Jan 13, 2025
d5125cf
merge fix
disconcision Jan 13, 2025
04c9fbc
rename Parens to Wrap, which includes as sub-cases both Parens and Probe
disconcision Jan 14, 2025
6fc30f3
upgrade projector shape API
disconcision Jan 14, 2025
9243224
cleanup
disconcision Jan 14, 2025
69fb87e
cleanup
disconcision Jan 14, 2025
2bda1f7
incorporate probe projector offside view into projectors API
disconcision Jan 14, 2025
4b84511
give projectors access to maketerm through utility
disconcision Jan 14, 2025
e843e6b
indicate the 'outer ap' a closure was created by
disconcision Jan 14, 2025
639d0b5
projector probe state refactor
disconcision Jan 14, 2025
28fb563
fixed ap tracking bug. added probe doc slide
disconcision Jan 14, 2025
2c211dd
better probe doc slide
disconcision Jan 15, 2025
65cc47a
merge dev
disconcision Jan 15, 2025
71cf598
group probe cells according to call
disconcision Jan 15, 2025
474fe84
cleanup
disconcision Jan 15, 2025
3925e0a
probe css cleanup
disconcision Jan 15, 2025
0325d22
pin aps for probe projector
disconcision Jan 15, 2025
9d4852f
clicking on probe projector now selects first cell. improved nav arro…
disconcision Jan 16, 2025
63b8368
dev merge
disconcision Jan 16, 2025
e592948
projector update functions now have access to the semantic info pack
disconcision Jan 16, 2025
c2668c9
add icon license readme. probe cleanup
disconcision Jan 16, 2025
4c48765
projector api addition: overlay view (view which is rendered above th…
disconcision Jan 17, 2025
de876b5
added optional underlay view to projectors API
disconcision Jan 17, 2025
620fcff
equals sign for projectors. fix pin deco somewhat. better value abbre…
disconcision Jan 17, 2025
60e980d
probe style tweaks
disconcision Jan 17, 2025
127f6f1
refactor projector view data flow
disconcision Jan 17, 2025
b603c56
cleanup
disconcision Jan 17, 2025
30fde8c
projector style. fixed hover z-index bug
disconcision Jan 18, 2025
0ccd82c
better dynamic cursor logic
disconcision Jan 18, 2025
4db6b5f
refactored brittle dyn_stack into proper call stack. cell decos now m…
disconcision Jan 18, 2025
310223b
clarified probe logic for related value decorations
disconcision Jan 18, 2025
4e61482
fix last (commented out wrong expr)
disconcision Jan 18, 2025
8a0dd12
clean up probe value deco css
disconcision Jan 18, 2025
6669623
probe fiddling
disconcision Jan 18, 2025
9ed4d72
probe fiddling
disconcision Jan 19, 2025
54301ac
better abbreviate logic
disconcision Jan 19, 2025
f092898
fix FontMetrics cleanup issue
disconcision Jan 19, 2025
8caacbf
convert type projector to offside view
disconcision Jan 19, 2025
72f0e58
give projectors access to a utlity fn to lift term=>term fns to synta…
disconcision Jan 19, 2025
212c3bb
update projectors slide with updated type projector and probe
disconcision Jan 19, 2025
27dfc26
refactor projector system dependencies
disconcision Jan 20, 2025
1d7eb29
reorganize projector files
disconcision Jan 20, 2025
b8c16e5
refactor textare, checkbox and slider projectors to use new syntax he…
disconcision Jan 20, 2025
a0ad7e9
cleanup
disconcision Jan 20, 2025
1def6fc
fix #1396
disconcision Jan 20, 2025
e798827
simplified smart selection logic. refactored maketerm.any to support …
disconcision Jan 20, 2025
a344f30
add/toggle projector actions now selection-based
disconcision Jan 20, 2025
7d5df36
can project infix/prefix/postfix things
disconcision Jan 21, 2025
ffaf327
synchronized projector panel with relaxed projection restrictions. ad…
disconcision Jan 21, 2025
723c0b8
clipboard cache system to retain projectors on in-editor cut/copy/pas…
disconcision Jan 21, 2025
dcd06b2
amend previous to only support cut/single-paste for now (to avoid UUI…
disconcision Jan 21, 2025
d891c08
reinstate clipboard cache for multiple pastes; now replaces all ids i…
disconcision Jan 21, 2025
38a71d7
mostly fix #1436
disconcision Jan 21, 2025
3aa2877
inline grout rendering to code text; unused file cleanup
disconcision Jan 22, 2025
ac9a823
fixed bug with caller cursor not showing up on certain aps
disconcision Jan 22, 2025
86ddd79
fix ap pinning
disconcision Jan 23, 2025
0a1304e
clean up probe dynamics
disconcision Jan 24, 2025
16fbf3c
clarify dynamic data collection api
disconcision Jan 24, 2025
45424d4
more precise css class scheme for relative cell position decorations
disconcision Jan 24, 2025
071a867
fix finnicky probe cell resize
disconcision Jan 24, 2025
769b5a2
fold projectors show contents on hover
disconcision Jan 24, 2025
08c7e6d
remove mousedown overlay; using pointer capture API for selection dra…
disconcision Jan 25, 2025
0f07d06
clean up and document new click behavior
disconcision Jan 25, 2025
e97851a
replaced brittle editor click/drag logic with state machine
disconcision Jan 25, 2025
d97f8c0
reinstated pointer capture
disconcision Jan 25, 2025
177d27d
simplify mouse state machine
disconcision Jan 25, 2025
ff56149
accidentally a file for last
disconcision Jan 25, 2025
44fe876
rm holes from syntax cache
disconcision Jan 25, 2025
493b6c7
decoration cleanup. split PieceDec into ShardDec and IndicationDec. e…
disconcision Jan 25, 2025
bab036c
fix issue with drag select being triggered on projector interaction
disconcision Jan 25, 2025
71a39df
fix issue with cell cursor indication set not firing
disconcision Jan 25, 2025
f41e0d4
new Pointer module abstracting mouse and pointer events. fixed issue …
disconcision Jan 25, 2025
d0fd6d6
merge fix
disconcision Jan 26, 2025
6378c0f
better probe arrow behavior with large numbers of cells. prohibit fol…
disconcision Jan 26, 2025
5f359f8
switched autocompletion buffer to unmolded; plays nicer with surround…
disconcision Jan 26, 2025
06717ea
fix stepper decorations. quiet skel printerr
disconcision Jan 26, 2025
0a2ebf4
experimental probe cell styling using third dimension to indicate rel…
disconcision Jan 27, 2025
1bf3489
fix drag-select triggering from outside-editor-focus clicks
disconcision Jan 27, 2025
6a927bf
probe cell style
disconcision Jan 27, 2025
a82ce77
improve unprojection logic (leave non-convex terms selected so you ca…
disconcision Jan 28, 2025
f2adc46
optional fancy background for projector view_seg
disconcision Jan 28, 2025
ddbdf22
make projector ids unique and not duplicates of the piece id. this li…
disconcision Jan 29, 2025
1df7501
probe cleanup. probe style tweaks.
disconcision Jan 30, 2025
3d3bcb0
projector clients now recieve segments instead of pieces
disconcision Jan 30, 2025
5faac6e
trying to project on case rule now projects case instead of failing s…
disconcision Jan 30, 2025
e0558df
fix #1489
disconcision Jan 30, 2025
c7c894a
can_project now operates on term only. rn Paren to Parens. lingering …
disconcision Jan 31, 2025
f79f3a0
drag select edge case fix
disconcision Jan 31, 2025
f3e79c3
probe window experiment
disconcision Feb 1, 2025
9e7d132
simplify projector panel logic
disconcision Feb 1, 2025
681602d
further simplify projector panel
disconcision Feb 1, 2025
a4ff248
restore projector error deco. split off all projector css files
disconcision Feb 1, 2025
82d6bb3
fix two issues with the click/drag state machine selection behavior. …
disconcision Feb 1, 2025
e17c893
disable TyDi suggestion of :: for now since : is more common
disconcision Feb 1, 2025
9813bd8
Merge branch 'dev' of github.com:hazelgrove/hazel into projectors-live
disconcision Feb 2, 2025
5d0cdfd
update probe slide. probe style tweaks
disconcision Feb 2, 2025
d175ad8
clean up syntax helpers
disconcision Feb 2, 2025
a2acfe8
allow probing expression holes. allow folding types and tpats again. …
disconcision Feb 2, 2025
f187506
projectors cleanup
disconcision Feb 3, 2025
454b0b6
clean up dynamics data passthrough. fix closure cursor arrows
disconcision Feb 3, 2025
adb677b
probes exercise mode fixes
disconcision Feb 3, 2025
a563a4e
probe cell hover scale effect now gradually falls off for longer cell…
disconcision Feb 3, 2025
8ffe4fc
probe value display now supports (many) indefinite forms. still not a…
disconcision Feb 4, 2025
05421a7
more cases in abbreviate
disconcision Feb 4, 2025
f7606cc
memoize Probe.syntax_str for perf with lots of probes open
disconcision Feb 4, 2025
1530c3a
turn shape_of_proj function passed to Measured into a map, cached at …
disconcision Feb 4, 2025
d857c66
distinct deco for probe cells that aren't values
disconcision Feb 4, 2025
f1b2b3f
less angry indets. below-call deco now receeds properly
disconcision Feb 5, 2025
64241b4
disable different deco for pattern vs exp probe cells
disconcision Feb 6, 2025
0a63615
missed a style from last
disconcision Feb 6, 2025
a9986d2
z-index adjustment for projectors
disconcision Feb 6, 2025
c6c9255
factor projector view fns more clearly
disconcision Feb 6, 2025
65195e0
clean up projectorView
disconcision Feb 6, 2025
243a793
fix click-click-drag and dblclick-dblclick issues. made show one vers…
disconcision Feb 6, 2025
483ecf0
pry apart probes and parens for matt
disconcision Feb 6, 2025
29475d3
encapsulate state for PatternMatch probe instrumentation
disconcision Feb 6, 2025
72547d9
merge fix
disconcision Feb 6, 2025
a8bbc07
attempted fix for mousewheel scroll
disconcision Feb 6, 2025
e1e39eb
attempted fix for mousewheel scroll x2
disconcision Feb 6, 2025
1b674d5
fix bug with probe cell display window being the wrong size when swit…
disconcision Feb 6, 2025
4acb18d
fix but with pasting not trimming leading whitespace
disconcision Feb 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions licenses/Icons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The icons used in Hazel, including the Hazel icon, are from The Noun Project (https://thenounproject.com/) under the Icon Pro license (https://thenounproject.com/legal/terms-of-use/#icon-licenses).
33 changes: 33 additions & 0 deletions src/haz3lcore/ClipboardCache.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* In order to retain projectors on cut/copy/paste, and to speed
* up pasting after in-editor copy/cut, we maintain a cached of
* the last copied selection segment and do segment insertion
* instead of reparsing if the clipboard text contents are the
* same as text serialization of the cached segment */

let cache: ref(option((string, Segment.t))) = ref(None);

let set = (seg: option(Segment.t), str: string): unit =>
switch (seg) {
| Some(seg) when Segment.deep_tile_complete(seg) =>
/* This check makes sure we won't create backpack orphans */
cache := Some((str, seg))
| _ => ()
};

let intersection = (ids1: list(Id.t), ids2: list(Id.t)): list(Id.t) =>
List.filter(id => List.mem(id, ids2), ids1);

let get = (pasted: string): Action.t => {
/* Note the trimming of leading whitespace on each line */
let trim = Util.StringUtil.trim_leading;
let trimmed_pasted = trim(pasted);
switch (cache^) {
| None => Paste(String(trimmed_pasted))
| Some((cached, segment)) =>
/* Note that we must replace unique ids here if we want to
* support copying and/or multiples pastes for a copy */
trim(cached) == trimmed_pasted
? Paste(Segment(Segment.IDs.replace(segment)))
: Paste(String(trimmed_pasted))
};
};
48 changes: 32 additions & 16 deletions src/haz3lcore/Measured.re
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ type t = {
secondary: Id.Map.t(measurement),
projectors: Id.Map.t(measurement),
rows: Rows.t,
linebreaks: Id.Map.t(rel_indent),
};

let empty = {
Expand All @@ -65,7 +64,6 @@ let empty = {
secondary: Id.Map.empty,
projectors: Id.Map.empty,
rows: Rows.empty,
linebreaks: Id.Map.empty,
};

let add_s = (id: Id.t, i: int, m, map) => {
Expand Down Expand Up @@ -131,11 +129,6 @@ let rec add_n_rows = (origin: Point.t, row_indent, n: abs_indent, map: t): t =>
|> add_row(origin.row + n - 1, {indent: row_indent, max_col: origin.col})
};

let add_lb = (id, indent, map) => {
...map,
linebreaks: Id.Map.add(id, indent, map.linebreaks),
};

let singleton_w = (w, m) => empty |> add_w(w, m);
let singleton_g = (g, m) => empty |> add_g(g, m);
let singleton_s = (id, shard, m) => empty |> add_s(id, shard, m);
Expand All @@ -147,8 +140,6 @@ let find_shards = (~msg="", t: Tile.t, map) =>
| _ => failwith("find_shards: " ++ msg)
};

let find_opt_lb = (id, map) => Id.Map.find_opt(id, map.linebreaks);

let find_shards' = (id: Id.t, map) =>
switch (Id.Map.find_opt(id, map.tiles)) {
| None => []
Expand Down Expand Up @@ -282,7 +273,8 @@ let last_of_token = (token: string, origin: Point.t): Point.t =>
row: origin.row + StringUtil.num_linebreaks(token),
};

let of_segment = (seg: Segment.t, info_map: Statics.Map.t): t => {
let of_segment =
(seg: Segment.t, shape_map: Id.Map.t(ProjectorCore.Shape.t)): t => {
let is_indented = is_indented_map(seg);

// recursive across seg's bidelimited containers
Expand Down Expand Up @@ -340,7 +332,7 @@ let of_segment = (seg: Segment.t, info_map: Statics.Map.t): t => {
origin.row,
{indent: row_indent, max_col: origin.col},
)
|> add_lb(w.id, indent);
|> add_n_rows(origin, row_indent, 1);
(indent, last, map);
| Secondary(w) =>
let wspace_length =
Expand All @@ -353,11 +345,25 @@ let of_segment = (seg: Segment.t, info_map: Statics.Map.t): t => {
let map = map |> add_g(g, {origin, last});
(contained_indent, last, map);
| Projector(p) =>
let token =
Projector.placeholder(p, Id.Map.find_opt(p.id, info_map));
let last = last_of_token(token, origin);
let map = extra_rows(token, origin, map);
let map = add_pr(p, {origin, last}, map);
let row_indent = container_indent + contained_indent;
let shape = ProjectorCore.Shape.Map.lookup(p.id, shape_map);
let num_extra_rows =
switch (shape.vertical) {
| Inline => 0
| Block(num_lbs) => num_lbs
};
let last = {
col: origin.col + shape.horizontal,
row:
switch (shape.vertical) {
| Inline => origin.row
| Block(num_lb) => origin.row + num_lb
},
};
let map =
map
|> add_n_rows(origin, row_indent, num_extra_rows)
|> add_pr(p, {origin, last});
(contained_indent, last, map);
| Tile(t) =>
let add_shard = (origin, shard, map) => {
Expand Down Expand Up @@ -392,6 +398,9 @@ let of_segment = (seg: Segment.t, info_map: Statics.Map.t): t => {
snd(go_nested(~map=empty, seg));
};

/* Memoized for perf */
let of_segment = Core.Memo.general(of_segment);

let length = (seg: Segment.t, map: t): int =>
switch (seg) {
| [] => 0
Expand All @@ -403,3 +412,10 @@ let length = (seg: Segment.t, map: t): int =>
let last = find_p(ListUtil.last(tl), map);
last.last.col - first.origin.col;
};

/* Width in characters of row at measurement.origin */
let start_row_width = (measurement: measurement, measured: t): int =>
switch (IntMap.find_opt(measurement.origin.row, measured.rows)) {
| None => 0
| Some(row) => row.max_col
};
2 changes: 1 addition & 1 deletion src/haz3lcore/assistant/AssistantForms.re
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module Typ = {
let of_infix_delim: list((Token.t, Typ.term)) = [
//("|>", Unknown(Internal)), /* annoying during case rules */
(",", Prod([unk, unk])), /* NOTE: Current approach doesn't work for this, but irrelevant as 1-char */
("::", List(unk)), /* annoying in patterns */
//("::", List(unk)), /* annoying in patterns. TODO: add codepath to show only if Ana(List(_)) */
("@", List(unk)),
(";", Unknown(Internal)),
("&&", Bool),
Expand Down
15 changes: 4 additions & 11 deletions src/haz3lcore/assistant/TyDi.re
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,8 @@ let token_to_left = (z: Zipper.t): option(string) =>
/* The selection buffer used by TyDi is currently unstructured; it simply
* holds an unparsed string, which is parsed via the same mechanism as
* Paste only when a suggestion is accepted. */
let mk_unparsed_buffer =
(~sort: Sort.t, sibs: Siblings.t, t: Token.t): Segment.t => {
let mold = Siblings.mold_fitting_between(sort, Precedence.max, sibs);
[Tile({id: Id.mk(), label: [t], shards: [0], children: [], mold})];
let mk_unparsed_buffer = (t: Token.t): Segment.t => {
[Secondary({id: Id.mk(), content: Comment(t)})];
};

/* If 'current' is a proper prefix of 'candidate', return the
Expand All @@ -70,7 +68,7 @@ let suffix_of = (candidate: Token.t, current: Token.t): option(Token.t) => {
/* Returns the text content of the suggestion buffer */
let get_buffer = (z: Zipper.t): option(Token.t) =>
switch (z.selection.mode, z.selection.content) {
| (Buffer(Unparsed), [Tile({label: [completion], _})]) =>
| (Buffer(Unparsed), [Secondary({content: Comment(completion), _})]) =>
Some(completion)
| _ => None
};
Expand All @@ -96,12 +94,7 @@ let set_buffer = (~info_map: Statics.Map.t, z: Zipper.t): option(Zipper.t) => {
);
let* top_suggestion = suggestions |> Util.ListUtil.hd_opt;
let* suggestion_suffix = suffix_of(top_suggestion.content, tok_to_left);
let content =
mk_unparsed_buffer(
~sort=Info.sort_of(ci),
z.relatives.siblings,
suggestion_suffix,
);
let content = mk_unparsed_buffer(suggestion_suffix);
let z = Zipper.set_buffer(z, ~content, ~mode=Unparsed);
Some(z);
};
2 changes: 2 additions & 0 deletions src/haz3lcore/dynamics/DHExp.re
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ let rec strip_casts =
| BinOp(_)
| Match(_)
| Parens(_)
| Probe(_)
| EmptyHole
| Invalid(_)
| Var(_)
Expand Down Expand Up @@ -162,6 +163,7 @@ let ty_subst = (s: Typ.t, tpat: TPat.t, exp: t): t => {
| TyAlias(_)
| DeferredAp(_)
| Parens(_)
| Probe(_)
| UnOp(_) => continue(exp)
},
exp,
Expand Down
8 changes: 8 additions & 0 deletions src/haz3lcore/dynamics/EvalCtx.re
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type term =
| BinOp2(Operators.op_bin, DHExp.t, t)
| Tuple(t, (list(DHExp.t), list(DHExp.t)))
| Test(t)
| Parens(t)
| Probe(t, Probe.t)
| ListLit(t, (list(DHExp.t), list(DHExp.t)))
| MultiHole(t, (list(Any.t), list(Any.t)))
| Cons1(t, DHExp.t)
Expand Down Expand Up @@ -88,6 +90,12 @@ let rec compose = (ctx: t, d: DHExp.t): DHExp.t => {
| Test(ctx) =>
let d1 = compose(ctx, d);
Test(d1) |> wrap;
| Parens(ctx) =>
let d1 = compose(ctx, d);
Parens(d1) |> wrap;
| Probe(ctx, p) =>
let d1 = compose(ctx, d);
Probe(d1, p) |> wrap;
| UnOp(op, ctx) =>
let d1 = compose(ctx, d);
UnOp(op, d1) |> wrap;
Expand Down
3 changes: 3 additions & 0 deletions src/haz3lcore/dynamics/Evaluator.re
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ module EvaluatorEVMode: {
let update_test = (state, id, v) =>
state := EvaluatorState.add_test(state^, id, v);

let update_probe = (state, closure: Dynamics.Probe.Closure.t) =>
state := EvaluatorState.add_closure(state^, closure);

let req_final = (f, _, x) => {
let.trampoline x' = Next(() => f(x));
Trampoline.return(x' |> snd);
Expand Down
14 changes: 12 additions & 2 deletions src/haz3lcore/dynamics/EvaluatorState.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
type t = {
stats: EvaluatorStats.t,
tests: TestMap.t,
probes: Dynamics.Probe.Map.t,
};

let init = {stats: EvaluatorStats.initial, tests: TestMap.empty};
let init = {
stats: EvaluatorStats.initial,
tests: TestMap.empty,
probes: Dynamics.Probe.Map.empty,
};

let take_step = ({stats, _} as es) => {
...es,
Expand All @@ -22,4 +27,9 @@ let add_test = ({tests, _} as es, id, report) => {

let get_tests = ({tests, _}) => tests;

let put_tests = (tests, es) => {...es, tests};
let add_closure = ({probes, _} as es, closure: Dynamics.Probe.Closure.t) => {
...es,
probes: Dynamics.Probe.Map.extend(closure.syntax_id, closure, probes),
};

let get_probes = ({probes, _}) => probes;
4 changes: 3 additions & 1 deletion src/haz3lcore/dynamics/EvaluatorState.rei
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ let add_test: (t, Id.t, TestMap.instance_report) => t;

let get_tests: t => TestMap.t;

let put_tests: (TestMap.t, t) => t;
let add_closure: (t, Dynamics.Probe.Closure.t) => t;

let get_probes: t => Dynamics.Probe.Map.t;
11 changes: 11 additions & 0 deletions src/haz3lcore/dynamics/EvaluatorStep.re
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ let rec matches =
| Test(ctx) =>
let+ ctx = matches(env, flt, ctx, exp, act, idx);
Test(ctx) |> rewrap;
| Parens(ctx) =>
let+ ctx = matches(env, flt, ctx, exp, act, idx);
Parens(ctx) |> rewrap;
| Probe(ctx, pr) =>
let+ ctx = matches(env, flt, ctx, exp, act, idx);
Probe(ctx, pr) |> rewrap;
| ListLit(ctx, ds) =>
let+ ctx = matches(env, flt, ctx, exp, act, idx);
ListLit(ctx, ds) |> rewrap;
Expand Down Expand Up @@ -298,6 +304,8 @@ module Decompose = {
let otherwise = (env, o) => (o, Result.BoxedValue, env, ());
let update_test = (state, id, v) =>
state := EvaluatorState.add_test(state^, id, v);
let update_probe = (state, closure: Dynamics.Probe.Closure.t) =>
state := EvaluatorState.add_closure(state^, closure);
};

module Decomp = Transition(DecomposeEVMode);
Expand Down Expand Up @@ -339,6 +347,9 @@ module TakeStep = {

let update_test = (state, id, v) =>
state := EvaluatorState.add_test(state^, id, v);

let update_probe = (state, closure: Dynamics.Probe.Closure.t) =>
state := EvaluatorState.add_closure(state^, closure);
};

module TakeStepEV = Transition(TakeStepEVMode);
Expand Down
13 changes: 3 additions & 10 deletions src/haz3lcore/dynamics/FilterMatcher.re
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
let evaluate_extend_env =
(new_bindings: Environment.t, to_extend: ClosureEnvironment.t)
: ClosureEnvironment.t => {
to_extend
|> ClosureEnvironment.map_of
|> Environment.union(new_bindings)
|> ClosureEnvironment.of_environment;
};
let evaluate_extend_env = ClosureEnvironment.extend_eval(~call_stack=[]);

let evaluate_extend_env_with_pat =
(
Expand Down Expand Up @@ -104,8 +97,8 @@ let rec matches_exp =
true;
} else {
switch (d |> DHExp.term_of, f |> DHExp.term_of) {
| (Parens(d), _) => matches_exp(d, f)
| (_, Parens(f)) => matches_exp(d, f)
| (Parens(d) | Probe(d, _), _) => matches_exp(d, f)
| (_, Parens(f) | Probe(f, _)) => matches_exp(d, f)

| (Constructor("$e", _), _) => failwith("$e in matched expression")
| (Constructor("$v", _), _) => failwith("$v in matched expression")
Expand Down
35 changes: 34 additions & 1 deletion src/haz3lcore/dynamics/PatternMatch.re
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ let combine_result = (r1: match_result, r2: match_result): match_result =>
Matches(Environment.union(env1, env2))
};

let rec matches = (dp: Pat.t, d: DHExp.t): match_result =>
let rec matches = (capture, dp: Pat.t, d: DHExp.t): match_result => {
let matches = matches(capture);
switch (DHPat.term_of(dp)) {
| Invalid(_)
| EmptyHole
Expand Down Expand Up @@ -56,6 +57,38 @@ let rec matches = (dp: Pat.t, d: DHExp.t): match_result =>
List.map2(matches, ps, ds)
|> List.fold_left(combine_result, Matches(Environment.empty));
| Parens(p) => matches(p, d)
| Probe(p, pr) =>
let inner_match = matches(p, d);
capture(pr, dp, d, inner_match);
inner_match;
| Cast(p, t1, t2) =>
matches(p, Cast(d, t2, t1) |> DHExp.fresh |> Casts.transition_multiple)
};
};

type closure_closures = list(Probe.call_stack => Dynamics.Probe.Closure.t);

type matches_and_closures = {
matches: match_result,
closures: closure_closures,
};

let matches = (dp: Pat.t, d: DHExp.t): matches_and_closures => {
/* Closure capture for Probe instrumentation */
let closure_closures: ref(closure_closures) = ref([]);
let capture =
(pr: Probe.t, dp: Term.Pat.t, d: DHExp.t, inner_match: match_result)
: unit =>
switch (inner_match) {
| DoesNotMatch => ()
| IndetMatch => ()
| Matches(env) =>
closure_closures :=
List.cons(
Dynamics.Probe.Closure.mk(Term.Pat.rep_id(dp), d, env, _, pr),
closure_closures^,
)
};
let res = matches(capture, dp, d);
{matches: res, closures: closure_closures^};
};
21 changes: 21 additions & 0 deletions src/haz3lcore/dynamics/Probe.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
open Util;

/* A syntax probe is inserted into syntax to capture
* information during evaluation. The tag type below,
* for the probe case, is used to collect binding ids
* which are used to faciltate capturing intermediate
* dynamic data such as environment variables and
* callstack state. Probes are created during maketerm
* and can be intercepted duting elaboration to add
* static information to inform dynamic information
* capture (such as as restricting environment variable
* capture to variables actually referenced. */

[@deriving (show({with_path: false}), sexp, yojson)]
type t = {refs: Binding.s};

/* A call at stack represented by function ap ids */
[@deriving (show({with_path: false}), sexp, yojson)]
type call_stack = list(Id.t);

let empty: t = {refs: []};
Loading