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

feat: parenthetical syntax for cycles, timeout etc. #4608

Draft
wants to merge 193 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
193 commits
Select commit Hold shift + click to select a range
d4811e2
WIP: surface syntax for parentheticals
ggreif Jul 10, 2024
b6d32ec
WIP: first AST modifications
ggreif Jul 10, 2024
d3b9415
WIP: augment IR too
ggreif Jul 10, 2024
3f57777
Update src/mo_frontend/definedness.ml
ggreif Jul 10, 2024
7e23ac8
WIP: fill the parenthetical
ggreif Jul 10, 2024
b0516b0
tweaks
ggreif Jul 10, 2024
dc5a72f
define and use `tupVarsP` helper
ggreif Jul 10, 2024
8f7df27
teach about `SystemCyclesAddPrim`
ggreif Jul 10, 2024
e5f3ca9
examine all exprs
ggreif Jul 10, 2024
5eb79a3
WIP: doing naughty stuff
ggreif Jul 10, 2024
9672a96
WIP: this starts working
ggreif Jul 10, 2024
00b2507
accept
ggreif Jul 10, 2024
3d4bb5a
cleanup
ggreif Jul 10, 2024
d989397
compress
ggreif Jul 10, 2024
892ea54
WIP: prepare `ICCallPrim` to carry setup code
ggreif Jul 11, 2024
42a0471
WIP: compile the setup code
ggreif Jul 11, 2024
e43b1cc
elim a FIXME
ggreif Jul 11, 2024
43e816c
minor refactor
ggreif Jul 11, 2024
272870b
Merge branch 'master' into gabor/parentheticals
ggreif Jul 11, 2024
2f22db2
explain more cycles
ggreif Jul 11, 2024
b6ee8dd
remove because redundant
ggreif Jul 11, 2024
812d78d
fix IR renaming
ggreif Jul 11, 2024
e7f13f6
cleanup
ggreif Jul 11, 2024
ccd03db
tweaks
ggreif Jul 11, 2024
dbe054d
tweak
ggreif Jul 14, 2024
835502c
generate less lambdas on the fly
ggreif Jul 14, 2024
b104f85
integrate also the invocation of the `unary_async`
ggreif Jul 14, 2024
0542367
Merge branch 'master' into gabor/parentheticals
ggreif Jul 17, 2024
eaa577d
merge corrections
ggreif Jul 17, 2024
4f77084
WIP: start defining prims
ggreif Jul 17, 2024
38dfd70
WIP: `CPSAsync`
ggreif Jul 17, 2024
1f61bb5
WIP: begin fleshing out receiving
ggreif Jul 18, 2024
4d0d263
WIP: draft codegen for `ICCyclesPrim`
ggreif Jul 18, 2024
d472f53
WIP: yes, it expodes!
ggreif Jul 18, 2024
48096cb
actually send the parenthetical
ggreif Jul 18, 2024
ff217f3
tweak
ggreif Jul 19, 2024
29110d3
interpret `ICCallerPrim` as non-informative
ggreif Jul 19, 2024
463f12a
Merge branch 'master' into gabor/parentheticals
ggreif Jul 27, 2024
4abc9e8
WIP: pass a pair
ggreif Jul 30, 2024
261ae02
simplify
ggreif Aug 5, 2024
2e5b787
restrict pair creation
ggreif Aug 5, 2024
8c05650
futures only
ggreif Aug 5, 2024
f9abea4
simplifying folds
ggreif Aug 5, 2024
998f689
WIP: prepare `ICCyclesPrim` for all possibilities
ggreif Aug 5, 2024
6873747
tweak
ggreif Aug 5, 2024
3f4c1de
tweak
ggreif Aug 5, 2024
009f05d
tweak
ggreif Aug 5, 2024
2bbe8d5
WIP: this ccompiles
ggreif Aug 6, 2024
391fedd
fix
ggreif Aug 6, 2024
275e952
wip
ggreif Aug 6, 2024
56d79fe
impl. type-checking
ggreif Aug 6, 2024
4009982
WIP: pass cycles
ggreif Aug 6, 2024
8628695
WIP: crash is fixed
ggreif Aug 6, 2024
016ac58
fix up `ICCyclesPrim`'s type
ggreif Aug 6, 2024
9c611a9
remove legacy `Cycles.add`
ggreif Aug 6, 2024
ee4e2c9
WIP: allow decorations on `AsyncE`
ggreif Aug 7, 2024
4279b96
arrange parenthetical
ggreif Aug 7, 2024
0f35682
WIP: compiles
ggreif Aug 7, 2024
5a9e300
Merge branch 'master' into gabor/parentheticals
ggreif Aug 9, 2024
3d5cdc7
Merge branch 'master' into gabor/parentheticals
ggreif Aug 12, 2024
e080bcb
wip
ggreif Aug 8, 2024
3120931
merge fix
ggreif Aug 12, 2024
cf7cfa4
fix up test, but legacy should still work
ggreif Aug 12, 2024
84e42e1
infer parenthetical
ggreif Aug 12, 2024
b3ea1c2
WIP: test
ggreif Aug 12, 2024
6b0d54a
handle stacked parenthetials
ggreif Aug 12, 2024
ebc89b4
WIP: make it an option
ggreif Aug 13, 2024
82f2049
WIP: thread parentheticals through for `async`
ggreif Aug 13, 2024
a7d2874
make sure that the record has a `cycles` field
ggreif Aug 13, 2024
b482532
maybe we should rule this out
ggreif Aug 14, 2024
13b46f6
remove FIXMEs
ggreif Aug 14, 2024
b5f98a9
elim FIXMEs
ggreif Aug 14, 2024
19e8058
elim FIXMEs
ggreif Aug 14, 2024
a0e321d
elim FIXMEs
ggreif Aug 14, 2024
d147896
elim FIXMEs
ggreif Aug 14, 2024
a23f97a
elim FIXMEs
ggreif Aug 14, 2024
c475dc7
tweak
ggreif Aug 14, 2024
58c81b9
elim FIXMEs
ggreif Aug 14, 2024
498dd9b
elim FIXMEs
ggreif Aug 14, 2024
41186f3
merge `master`
ggreif Oct 21, 2024
65013fa
add `M0200`
ggreif Oct 22, 2024
2f179ec
start with a coarse warning
ggreif Oct 22, 2024
2f938cb
say what attribute is it
ggreif Oct 23, 2024
38fb28c
check `cycles` attribute type
ggreif Oct 23, 2024
031c375
cleanup
ggreif Oct 23, 2024
ac6928c
validate `async` exprs too
ggreif Oct 23, 2024
b9b3c17
accept
ggreif Oct 23, 2024
fbaf8b4
exercise `M0200` too
ggreif Oct 23, 2024
599fe2d
WIP: fire&forget doesn't work yet
ggreif Oct 24, 2024
30dbe01
apply parenthetical to one-shot sends
ggreif Nov 14, 2024
5be4240
start with tests for `call_raw`
ggreif Nov 14, 2024
a5b0984
tweaks
ggreif Nov 15, 2024
137ab9a
WIP: fix problem with `Cycles.add` not sticking
ggreif Nov 15, 2024
2b27bf9
eliminate a warning
ggreif Nov 29, 2024
92976f8
remove warnings
ggreif Nov 29, 2024
336de0b
simplify
ggreif Nov 29, 2024
8a7c490
WIP: try to warn on non-send calls
ggreif Nov 29, 2024
05eb145
fix M0202
ggreif Nov 29, 2024
0a9f6c0
fix warnings
ggreif Nov 29, 2024
fb97b74
warn empty notes
ggreif Nov 30, 2024
fe6107e
tweaks
ggreif Nov 30, 2024
277789a
what did I think here?
ggreif Dec 2, 2024
2a2b19a
Apply suggestions from code review
ggreif Dec 2, 2024
85075eb
don't arrange trivial parentheticals
ggreif Dec 2, 2024
1982b48
put the parenthetical in front
ggreif Dec 2, 2024
a93b8e1
Update src/ir_def/arrange_ir.ml
ggreif Dec 2, 2024
5a4d21f
Merge branch 'master' into gabor/parentheticals
ggreif Dec 2, 2024
9ae719b
Merge branch 'master' into gabor/parentheticals
ggreif Dec 3, 2024
f0f9436
test both old and new style
ggreif Dec 3, 2024
21ce382
accept
ggreif Dec 3, 2024
fff0aca
disable `drun-eop-*` for now
ggreif Dec 3, 2024
df56dcc
tidy up
ggreif Dec 3, 2024
b7aab76
be more explicit with `AsyncE()`
ggreif Dec 3, 2024
4ba0df1
simplify
ggreif Dec 3, 2024
8384150
function-body `CPSAsync(Fut)` should ignore the cycle send note on it
ggreif Dec 3, 2024
360974a
tweaks
ggreif Dec 3, 2024
309a231
fix `cps_asyncE` for the `AsyncE` (freestanding) case
ggreif Dec 3, 2024
64696a1
explicitly zero `cycles` when user doesn't specify any
ggreif Dec 3, 2024
339a98e
Merge branch 'master' into gabor/parentheticals
ggreif Dec 6, 2024
a0d475a
add new API
ggreif Dec 6, 2024
c9bd84f
WIP: prepare for `timeout`
ggreif Dec 6, 2024
3bed728
WIP: `replyDeadline` is still 0
ggreif Dec 6, 2024
cbfacdf
check for `timeout` type error
ggreif Dec 6, 2024
f1cc907
intro `nat32`
ggreif Dec 6, 2024
2edbcd9
WIP: begin checking `timeout`
ggreif Dec 6, 2024
83e70ab
WIP: invoke `call_with_best_effort_response`
ggreif Dec 7, 2024
0878d90
access at the correct type
ggreif Dec 7, 2024
ec31258
break out `infer_check_bases_fields` and use it to check just a few s…
ggreif Dec 10, 2024
ca66302
some errors are now emitted in a centralised fashion
ggreif Dec 10, 2024
4c37385
tweaks
ggreif Dec 10, 2024
e79c48d
intro and use `SystemTimeoutPrim`
ggreif Dec 10, 2024
b5eb704
accept
ggreif Dec 10, 2024
f80ffa8
fix warning
ggreif Dec 10, 2024
2e58517
unfake, but beware of the duplication!
ggreif Dec 10, 2024
7cb6cf0
WIP: `timeout` for one-shot calls
ggreif Dec 10, 2024
dc37044
`oneshot` tests actually work!
ggreif Dec 10, 2024
72900db
Merge branch 'master' into gabor/parentheticals
ggreif Dec 23, 2024
01e1ba6
tweaks
ggreif Dec 11, 2024
6498fe3
Merge branch 'master' into gabor/parentheticals
ggreif Jan 13, 2025
f1e37a1
WIP: visit object hashes
ggreif Jan 13, 2025
ccff46a
Merge branch 'master' into gabor/parentheticals
ggreif Jan 23, 2025
df50c8c
simplify
ggreif Jan 13, 2025
54794a6
WIP!
ggreif Jan 14, 2025
7877986
WIP: walk fields dynamically
ggreif Jan 23, 2025
76eadcd
fix types
ggreif Jan 23, 2025
8a67b0b
fix
ggreif Jan 23, 2025
afb2c14
tweaks
ggreif Jan 24, 2025
a850539
experiment: delegate cycles in `@call_raw`
ggreif Jan 24, 2025
4ad010f
yay, parentheticals work for raw calls!
ggreif Jan 24, 2025
ff5c16e
be sure to always reset the imperative store for parenthetical-style
ggreif Jan 24, 2025
1974e7d
iterate
ggreif Jan 24, 2025
395b2e7
feat: passing cycles to `call_raw`
ggreif Jan 27, 2025
316fd27
feat: passing cycles to `call_raw`
ggreif Jan 27, 2025
76198c0
Merge branch 'master' into gabor/parentheticals
ggreif Jan 27, 2025
9b3764d
Merge remote-tracking branch 'origin/master' into gabor/parentheticals
ggreif Jan 27, 2025
f2671da
fix freevars and renaming
ggreif Jan 27, 2025
5831aaf
test new way for parenthetical cycles
ggreif Jan 27, 2025
afa8805
better grammar for parentheticals (#4869)
ggreif Jan 27, 2025
b9ff9b9
accept
ggreif Jan 27, 2025
152d7a3
typecheck: enforce `NullCap` for parentheticals
ggreif Jan 27, 2025
bbf2f24
renumber errors
ggreif Jan 27, 2025
92e194c
rename IR prim
ggreif Jan 28, 2025
cb17a6e
complete `check_ir.ml`
ggreif Jan 28, 2025
aa505ae
spell out `#system_unknown`
ggreif Jan 28, 2025
39438b3
test `#system_unknown`
ggreif Jan 28, 2025
fc49209
cleanups
ggreif Jan 28, 2025
4326440
accept
ggreif Jan 28, 2025
cfc0180
this works now
ggreif Jan 28, 2025
f1c153d
synching up `#system_unknown`
ggreif Jan 28, 2025
5ba40d1
accept
ggreif Jan 28, 2025
d6dc3b0
wording
ggreif Jan 28, 2025
ae41e7b
Update src/ir_interpreter/interpret_ir.ml
ggreif Jan 28, 2025
1fc897e
`AsyncE` checking mode: validate the parenthetical
ggreif Jan 29, 2025
3bbf8d5
cleanup
ggreif Jan 29, 2025
c65092e
detect constants in `AsyncE` parentheticals
ggreif Jan 29, 2025
fa9dfc6
test CallE checking mode
ggreif Jan 29, 2025
8d8ccbe
good
ggreif Jan 29, 2025
9bf649a
avoid duplicated warnings
ggreif Jan 29, 2025
5cebc01
`async*` can have no parenthetical, a.t.m.
ggreif Jan 29, 2025
e540954
test effect order
ggreif Jan 30, 2025
d064586
better tests
ggreif Jan 30, 2025
90627c8
accept with `AsyncE` correct
ggreif Jan 30, 2025
0284e96
implement parentheticals in `CallE` and `SelfCallE`
ggreif Jan 30, 2025
6c85d13
implement `CallPrim` with parenthetical
ggreif Jan 30, 2025
d188121
oneway looks good
ggreif Jan 30, 2025
a0b08c1
implement missing IR interpreter pieces
ggreif Jan 30, 2025
ef1f8d1
WIP: defaulter/suppressor feature
ggreif Jan 30, 2025
1eb1cd5
WIP: exclude notes on public
ggreif Jan 31, 2025
94a5bf2
add a proper error code
ggreif Jan 31, 2025
98e6348
tweaks
ggreif Jan 31, 2025
ae6d506
`ICCallPrim` has an `(exp :: Obj _) option`
ggreif Jan 31, 2025
868c96c
fix the defaulting
ggreif Jan 31, 2025
7235e0a
accept
ggreif Jan 31, 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 doc/md/examples/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@
'break' <id> <exp_nullary>?
'continue' <id>
'debug' <exp_nest>
'(' <exp_post>? 'with' <list(<exp_field>, ';')> ')' <exp_nest>
Copy link
Contributor

@rvanasa rvanasa Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on using , here in place of ; for consistency with other parenthesized expressions? The formatter uses this invariant (commas in parentheses, semicolons in square brackets and curly braces) to automatically replace commas with semicolons and vice versa whenever there is otherwise a syntax error that makes the AST unparseable. I can add an exception, but it seems nice to keep this pattern so that it's easier for people to remember which delimiter to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for missing this comment for some time... Yeah, it is a nice consistency argument. I was stealing the syntax from the record field separators, but I guess comma works as well. Will try and report back. @crusso any gut feelings about this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd stick with ; since these are more like fields. Would be even nicer if they just were fields...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they are fields, but where is it written that they cannot be separated by commas? ;-) Just playing the devil's advocate.

Anyway, I have started a branch to get a feeling for the suggestion: #4782. I am not married to either way.

'if' <exp_nullary> <exp_nest>
'if' <exp_nullary> <exp_nest> 'else' <exp_nest>
'try' <exp_nest> <catch>
Expand Down
2 changes: 1 addition & 1 deletion src/ir_def/arrange_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ and args = function
and arg a = Atom a.it

and prim = function
| CallPrim ts -> "CallPrim" $$ List.map typ ts
| CallPrim (ts, _FIXME) -> "CallPrim" $$ List.map typ ts @ [exp _FIXME]
| UnPrim (t, uo) -> "UnPrim" $$ [typ t; Arrange_ops.unop uo]
| BinPrim (t, bo) -> "BinPrim" $$ [typ t; Arrange_ops.binop bo]
| RelPrim (t, ro) -> "RelPrim" $$ [typ t; Arrange_ops.relop ro]
Expand Down
2 changes: 1 addition & 1 deletion src/ir_def/check_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ let rec check_exp env (exp:Ir.exp) : unit =
| PrimE (p, es) ->
List.iter (check_exp env) es;
begin match p, es with
| CallPrim insts, [exp1; exp2] ->
| CallPrim (insts, _FIXMEpars), [exp1; exp2] ->
begin match T.promote (typ exp1) with
| T.Func (sort, control, tbs, arg_tys, ret_tys) ->
check_inst_bounds env tbs insts exp.at;
Expand Down
8 changes: 6 additions & 2 deletions src/ir_def/construct.ml
Original file line number Diff line number Diff line change
Expand Up @@ -312,14 +312,16 @@ let funcE name sort ctrl typ_binds args typs exp =
note = Note.{ def with typ; eff = T.Triv };
}

let recordE' = ref (fun _ -> nullE ()) (* gets correctly filled below *)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use and to allow mutual recursion


let callE exp1 typs exp2 =
let typ = match T.promote (typ exp1) with
| T.Func (_sort, control, _, _, ret_tys) ->
T.codom control (fun () -> List.hd typs) (List.map (T.open_ typs) ret_tys)
| T.Non -> T.Non
| _ -> raise (Invalid_argument "callE expect a function")
in
let p = CallPrim typs in
let p = CallPrim (typs, !recordE' []) in
let es = [exp1; exp2] in
{ it = PrimE (p, es);
at = no_region;
Expand Down Expand Up @@ -351,7 +353,7 @@ let orE : Ir.exp -> Ir.exp -> Ir.exp = fun e1 e2 ->
let impliesE : Ir.exp -> Ir.exp -> Ir.exp = fun e1 e2 ->
orE (notE e1) e2
let oldE : Ir.exp -> Ir.exp = fun e ->
{ it = (primE (CallPrim [typ e]) [e]).it;
{ it = (primE (CallPrim ([typ e], !recordE' [])) [e]).it;
at = no_region;
note = Note.{ def with
typ = typ e;
Expand Down Expand Up @@ -771,6 +773,8 @@ let objE sort typ_flds flds =

let recordE flds = objE T.Object [] flds

let _ = recordE' := recordE

let check_call_perform_status success mk_failure =
ifE
(callE
Expand Down
4 changes: 2 additions & 2 deletions src/ir_def/ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ and lexp' =
all call-by-value. Many passes can treat them uniformly, so they are unified
using the PrimE node. *)
and prim =
| CallPrim of Type.typ list (* function call *)
| CallPrim of Type.typ list * exp (* function call *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I makes me nervous that prim now as subexpressions since we might miss them in traversals. For example, is closure conversion in the backend considering these? It might be safer to put these arguments in the prim argument list.

| UnPrim of Type.typ * unop (* unary operator *)
| BinPrim of Type.typ * binop (* binary operator *)
| RelPrim of Type.typ * relop (* relational operator *)
Expand Down Expand Up @@ -257,7 +257,7 @@ let replace_obj_pat pfs pats =

let map_prim t_typ t_id p =
match p with
| CallPrim ts -> CallPrim (List.map t_typ ts)
| CallPrim (ts, _FIXME) -> CallPrim (List.map t_typ ts, _FIXME)
| UnPrim (ot, op) -> UnPrim (t_typ ot, op)
| BinPrim (ot, op) -> BinPrim (t_typ ot, op)
| RelPrim (ot, op) -> RelPrim (t_typ ot, op)
Expand Down
2 changes: 1 addition & 1 deletion src/ir_interpreter/interpret_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ and interpret_exp_mut env exp (k : V.value V.cont) =
| PrimE (p, es) ->
interpret_exps env es [] (fun vs ->
match p, vs with
| CallPrim typs, [v1; v2] ->
| CallPrim (typs, _), [v1; v2] ->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this ignores the side-effects therein!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, needs fixing

let call_conv, f = V.as_func v1 in
check_call_conv (List.hd es) call_conv;
check_call_conv_arg env exp v2 call_conv;
Expand Down
2 changes: 1 addition & 1 deletion src/ir_passes/async.ml
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ let transform prog =
let v_ret = fresh_var "v" t_ret in
let v_fail = fresh_var "e" t_fail in
([v_ret; v_fail] -->* (callE (t_exp exp1) [t0] (tupE [varE v_ret; varE v_fail]))).it
| PrimE (CallPrim typs, [exp1; exp2]) when is_awaitable_func exp1 ->
| PrimE (CallPrim (typs, _FIXME), [exp1; exp2]) when is_awaitable_func exp1 ->
let ts1,ts2 =
match typ exp1 with
| T.Func (T.Shared _, T.Promises, tbs, ts1, ts2) ->
Expand Down
4 changes: 2 additions & 2 deletions src/ir_passes/tailcall.ml
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ and assignEs vars exp : dec list =
and exp' env e : exp' = match e.it with
| VarE _ | LitE _ -> e.it
| AssignE (e1, e2) -> AssignE (lexp env e1, exp env e2)
| PrimE (CallPrim insts, [e1; e2]) ->
| PrimE (CallPrim (insts, pars), [e1; e2]) ->
begin match e1.it, env with
| VarE f1, { tail_pos = true;
info = Some { func; typ_binds; temps; label; tail_called } }
when f1 = func && are_generic_insts typ_binds insts ->
tail_called := true;
(blockE (assignEs temps (exp env e2)) (breakE label (unitE ()))).it
| _,_-> PrimE (CallPrim insts, [exp env e1; exp env e2])
| _,_-> PrimE (CallPrim (insts, pars), [exp env e1; exp env e2])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| _,_-> PrimE (CallPrim (insts, pars), [exp env e1; exp env e2])
| _,_-> PrimE (CallPrim (insts, exp env pars), [exp env e1; exp env e2])

end
| BlockE (ds, e) -> BlockE (block env ds e)
| IfE (e1, e2, e3) -> IfE (exp env e1, tailexp env e2, tailexp env e3)
Expand Down
48 changes: 24 additions & 24 deletions src/lowering/desugar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ and exp' at note = function
let tys = List.map (T.open_ vars) res_tys in
I.FuncE (name, s, control, tbs', args, tys, wrap (exp e))
(* Primitive functions in the prelude have particular shapes *)
| S.CallE ({it=S.AnnotE ({it=S.PrimE p;_}, _);note;_}, _, e)
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE p;_}, _);note;_}, _, e)
when Lib.String.chop_prefix "num_conv" p <> None ->
begin match String.split_on_char '_' p with
| ["num"; "conv"; s1; s2] ->
Expand All @@ -132,7 +132,7 @@ and exp' at note = function
I.PrimE (I.NumConvTrapPrim (p1, p2), [exp e])
| _ -> assert false
end
| S.CallE ({it=S.AnnotE ({it=S.PrimE p;_}, _);note;_}, _, e)
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE p;_}, _);note;_}, _, e)
when Lib.String.chop_prefix "num_wrap" p <> None ->
begin match String.split_on_char '_' p with
| ["num"; "wrap"; s1; s2] ->
Expand All @@ -141,71 +141,71 @@ and exp' at note = function
I.PrimE (I.NumConvWrapPrim (p1, p2), [exp e])
| _ -> assert false
end
| S.CallE ({it=S.AnnotE ({it=S.PrimE "decodeUtf8";_},_);_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "decodeUtf8";_},_);_}, _, e) ->
I.PrimE (I.DecodeUtf8, [exp e])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "encodeUtf8";_},_);_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "encodeUtf8";_},_);_}, _, e) ->
I.PrimE (I.EncodeUtf8, [exp e])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "cast";_}, _);note;_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "cast";_}, _);note;_}, _, e) ->
begin match note.S.note_typ with
| T.Func (T.Local, T.Returns, [], ts1, ts2) ->
I.PrimE (I.CastPrim (T.seq ts1, T.seq ts2), [exp e])
| _ -> assert false
end
| S.CallE ({it=S.AnnotE ({it=S.PrimE "serialize";_}, _);note;_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "serialize";_}, _);note;_}, _, e) ->
begin match note.S.note_typ with
| T.Func (T.Local, T.Returns, [], ts1, ts2) ->
I.PrimE (I.SerializePrim ts1, [exp e])
| _ -> assert false
end
| S.CallE ({it=S.AnnotE ({it=S.PrimE "deserialize";_}, _);note;_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "deserialize";_}, _);note;_}, _, e) ->
begin match note.S.note_typ with
| T.Func (T.Local, T.Returns, [], ts1, ts2) ->
I.PrimE (I.DeserializePrim ts2, [exp e])
| _ -> assert false
end
| S.CallE ({it=S.AnnotE ({it=S.PrimE "caller";_},_);_}, _, {it=S.TupE es;_}) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "caller";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.ICCallerPrim, [])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "time";_},_);_}, _, {it=S.TupE es;_}) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "time";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.SystemTimePrim, [])
(* Cycles *)
| S.CallE ({it=S.AnnotE ({it=S.PrimE "cyclesBalance";_},_);_}, _, {it=S.TupE es;_}) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "cyclesBalance";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.SystemCyclesBalancePrim, [])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "cyclesAvailable";_},_);_}, _, {it=S.TupE es;_}) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "cyclesAvailable";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.SystemCyclesAvailablePrim, [])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "cyclesRefunded";_},_);_}, _, {it=S.TupE es;_}) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "cyclesRefunded";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.SystemCyclesRefundedPrim, [])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "cyclesAccept";_},_);_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "cyclesAccept";_},_);_}, _, e) ->
I.PrimE (I.SystemCyclesAcceptPrim, [exp e])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "cyclesAdd";_},_);_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "cyclesAdd";_},_);_}, _, e) ->
I.PrimE (I.SystemCyclesAddPrim, [exp e])
(* Certified data *)
| S.CallE ({it=S.AnnotE ({it=S.PrimE "setCertifiedData";_},_);_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "setCertifiedData";_},_);_}, _, e) ->
I.PrimE (I.SetCertifiedData, [exp e])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "getCertificate";_},_);_}, _, {it=S.TupE es;_}) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE "getCertificate";_},_);_}, _, {it=S.TupE es;_}) ->
I.PrimE (I.GetCertificate, [])
(* Other *)
| S.CallE ({it=S.AnnotE ({it=S.PrimE p;_},_);_}, _, {it=S.TupE es;_}) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE p;_},_);_}, _, {it=S.TupE es;_}) ->
I.PrimE (I.OtherPrim p, exps es)
| S.CallE ({it=S.AnnotE ({it=S.PrimE p;_},_);_}, _, e) ->
| S.CallE (None, {it=S.AnnotE ({it=S.PrimE p;_},_);_}, _, e) ->
I.PrimE (I.OtherPrim p, [exp e])
(* Optimizing array.size() *)
| S.CallE ({it=S.DotE (e1, proj); _}, _, {it=S.TupE [];_})
| S.CallE (None, {it=S.DotE (e1, proj); _}, _, {it=S.TupE [];_})
when T.is_array e1.note.S.note_typ && proj.it = "size" ->
I.PrimE (I.OtherPrim "array_len", [exp e1])
| S.CallE ({it=S.DotE (e1, proj); _}, _, {it=S.TupE [];_})
| S.CallE (None, {it=S.DotE (e1, proj); _}, _, {it=S.TupE [];_})
when T.(is_prim Text) e1.note.S.note_typ && proj.it = "size" ->
I.PrimE (I.OtherPrim "text_len", [exp e1])
| S.CallE ({it=S.DotE (e1, proj); _}, _, {it=S.TupE [];_})
| S.CallE (None, {it=S.DotE (e1, proj); _}, _, {it=S.TupE [];_})
when T.(is_prim Blob) e1.note.S.note_typ && proj.it = "size" ->
I.PrimE (I.OtherPrim "blob_size", [exp e1])
(* Normal call *)
| S.CallE (e1, inst, e2) ->
I.PrimE (I.CallPrim inst.note, [exp e1; exp e2])
| S.CallE (_FIXME, e1, inst, e2) ->
I.PrimE (I.CallPrim (inst.note, Option.(value ~default:(recordE []) (map exp _FIXME))), [exp e1; exp e2])
| S.BlockE [] -> (unitE ()).it
| S.BlockE [{it = S.ExpD e; _}] -> (exp e).it
| S.BlockE ds -> I.BlockE (block (T.is_unit note.Note.typ) ds)
Expand All @@ -220,7 +220,7 @@ and exp' at note = function
| S.WhileE (e1, e2) -> (whileE (exp e1) (exp e2)).it
| S.LoopE (e1, None) -> I.LoopE (exp e1)
| S.LoopE (e1, Some e2) -> (loopWhileE (exp e1) (exp e2)).it
| S.ForE (p, {it=S.CallE ({it=S.DotE (arr, proj); _}, _, e1); _}, e2)
| S.ForE (p, {it=S.CallE (None, {it=S.DotE (arr, proj); _}, _, e1); _}, e2)
when T.is_array arr.note.S.note_typ && (proj.it = "vals" || proj.it = "keys")
-> (transform_for_to_while p arr proj e1 e2).it
| S.ForE (p, e1, e2) -> (forE (pat p) (exp e1) (exp e2)).it
Expand Down
2 changes: 1 addition & 1 deletion src/mo_def/arrange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module Make (Cfg : Config) = struct
Atom (if sugar then "" else "=");
exp e'
]
| CallE (e1, ts, e2) -> "CallE" $$ [exp e1] @ inst ts @ [exp e2]
| CallE (_FIXME, e1, ts, e2) -> "CallE" $$ [exp e1] @ inst ts @ [exp e2]
| BlockE ds -> "BlockE" $$ List.map dec ds
| NotE e -> "NotE" $$ [exp e]
| AndE (e1, e2) -> "AndE" $$ [exp e1; exp e2]
Expand Down
4 changes: 2 additions & 2 deletions src/mo_def/syntax.ml
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ and exp' =
| ArrayE of mut * exp list (* array *)
| IdxE of exp * exp (* array indexing *)
| FuncE of string * sort_pat * typ_bind list * pat * typ option * sugar * exp (* function *)
| CallE of exp * inst * exp (* function call *)
| BlockE of dec list (* block (with type after avoidance)*)
| CallE of exp option * exp * inst * exp (* function call *)
| BlockE of dec list (* block (with type after avoidance) *)
| NotE of exp (* negation *)
| AndE of exp * exp (* conjunction *)
| OrE of exp * exp (* disjunction *)
Expand Down
2 changes: 1 addition & 1 deletion src/mo_frontend/definedness.ml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ let rec exp msgs e : f = match e.it with
(* Eager uses are either first-class uses of a variable: *)
| VarE i -> M.singleton i.it Eager
(* Or anything that is occurring in a call (as this may call a closure): *)
| CallE (e1, ts, e2) -> eagerify (exps msgs [e1; e2])
| CallE (_FIXME, e1, ts, e2) -> eagerify (exps msgs [e1; e2])
ggreif marked this conversation as resolved.
Show resolved Hide resolved
(* And break, return, throw can be thought of as calling a continuation: *)
| BreakE (i, e) -> eagerify (exp msgs e)
| RetE e -> eagerify (exp msgs e)
Expand Down
4 changes: 2 additions & 2 deletions src/mo_frontend/effect.ml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ let effect_exp (exp:Syntax.exp) : T.eff = eff exp
(* infer the effect of an expression, assuming all sub-expressions are correctly effect-annotated es *)
let rec infer_effect_exp (exp:Syntax.exp) : T.eff =
match exp.it with
| CallE (exp1, inst, exp2) when is_async_call exp1 inst exp2 ->
| CallE (_FIXME, exp1, inst, exp2) when is_async_call exp1 inst exp2 ->
T.Await
| PrimE _
| VarE _
Expand Down Expand Up @@ -81,7 +81,7 @@ let rec infer_effect_exp (exp:Syntax.exp) : T.eff =
| IdxE (exp1, exp2)
| RelE (_, exp1, _, exp2)
| AssignE (exp1, exp2)
| CallE (exp1, _, exp2)
| CallE (_(*FIXME*), exp1, _, exp2)
| AndE (exp1, exp2)
| OrE (exp1, exp2)
| ImpliesE (exp1, exp2)
Expand Down
8 changes: 7 additions & 1 deletion src/mo_frontend/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ exp_post(B) :
| e=exp_post(B) DOT x=id
{ DotE(e, x) @? at $sloc }
| e1=exp_post(B) inst=inst e2=exp_nullary(ob)
{ CallE(e1, inst, e2) @? at $sloc }
{ CallE(None, e1, inst, e2) @? at $sloc }
| e1=exp_post(B) BANG
{ BangE(e1) @? at $sloc }
| LPAR SYSTEM e1=exp_post(B) DOT x=id RPAR
Expand Down Expand Up @@ -703,6 +703,12 @@ exp_un(B) :
BreakE(x', TupE([]) @? no_region) @? at $sloc }
| DEBUG e=exp_nest
{ DebugE(e) @? at $sloc }
| LPAR base=exp_post(ob)? WITH fs=seplist(exp_field, semicolon) RPAR e=exp_nest (* parentheticals to qualify message sends *)
{ match e.it with
| CallE _
| AsyncE (Type.Fut, _, _) -> e
| _ -> { e with it = ObjE(Option.to_list base, fs) }
}
| IF b=exp_nullary(ob) e1=exp_nest %prec IF_NO_ELSE
{ IfE(b, e1, TupE([]) @? at $sloc) @? at $sloc }
| IF b=exp_nullary(ob) e1=exp_nest ELSE e2=exp_nest
Expand Down
4 changes: 2 additions & 2 deletions src/mo_frontend/traversals.ml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ let rec over_exp (f : exp -> exp) (exp : exp) : exp = match exp.it with
f { exp with it = RelE (x, over_exp f exp1, y, over_exp f exp2) }
| AssignE (exp1, exp2) ->
f { exp with it = AssignE (over_exp f exp1, over_exp f exp2) }
| CallE (exp1, x, exp2) ->
f { exp with it = CallE (over_exp f exp1, x, over_exp f exp2) }
| CallE (par_opt, exp1, x, exp2) ->
f { exp with it = CallE (Option.map (over_exp f) par_opt, over_exp f exp1, x, over_exp f exp2) }
| AndE (exp1, exp2) ->
f { exp with it = AndE (over_exp f exp1, over_exp f exp2) }
| OrE (exp1, exp2) ->
Expand Down
6 changes: 3 additions & 3 deletions src/mo_frontend/typing.ml
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ let rec is_explicit_exp e =
true
| LitE l -> is_explicit_lit !l
| UnE (_, _, e1) | OptE e1 | DoOptE e1
| ProjE (e1, _) | DotE (e1, _) | BangE e1 | IdxE (e1, _) | CallE (e1, _, _)
| ProjE (e1, _) | DotE (e1, _) | BangE e1 | IdxE (e1, _) | CallE (_(*FIXME: correct?*), e1, _, _)
| LabelE (_, _, e1) | AsyncE (_, _, e1) | AwaitE (_, e1) ->
is_explicit_exp e1
| BinE (_, e1, _, e2) | IfE (_, e1, e2) ->
Expand Down Expand Up @@ -1483,7 +1483,7 @@ and infer_exp'' env exp : T.typ =
end;
let ts1 = match pat.it with TupP _ -> T.seq_of_tup t1 | _ -> [t1] in
T.Func (sort, c, T.close_binds cs tbs, List.map (T.close cs) ts1, List.map (T.close cs) ts2)
| CallE (exp1, inst, exp2) ->
| CallE (_FIXME, exp1, inst, exp2) ->
infer_call env exp1 inst exp2 exp.at None
| BlockE decs ->
let t, _ = infer_block env decs exp.at false in
Expand Down Expand Up @@ -1868,7 +1868,7 @@ and check_exp' env0 t exp : T.typ =
in
check_exp_strong (adjoin_vals env' ve2) t2 exp;
t
| CallE (exp1, inst, exp2), _ ->
| CallE (_FIXME, exp1, inst, exp2), _ ->
let t' = infer_call env exp1 inst exp2 exp.at (Some t) in
if not (T.sub t' t) then
local_error env0 exp.at "M0096"
Expand Down
2 changes: 1 addition & 1 deletion src/mo_interpreter/interpret.ml
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ and interpret_exp_mut env exp (k : V.value V.cont) =
| T.Shared _ -> make_message env name exp.note.note_typ v
| T.Local -> v
in k v'
| CallE (exp1, typs, exp2) ->
| CallE (_FIXME, exp1, typs, exp2) ->
interpret_exp env exp1 (fun v1 ->
interpret_exp env exp2 (fun v2 ->
let call_conv, f = V.as_func v1 in
Expand Down
2 changes: 1 addition & 1 deletion src/viper/trans.ml
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ and stmt ctxt (s : M.exp) : seqn =
| M.AssertE (M.Runtime, e) ->
!!([],
[ !!(AssumeS (exp ctxt e)) ])
| M.(CallE({it = VarE m; _}, inst, {it = TupE args; _})) ->
| M.(CallE(_, {it = VarE m; _}, inst, {it = TupE args; _})) ->
!!([],
[ !!(MethodCallS ([], id m,
let self_var = self ctxt m.at in
Expand Down
4 changes: 2 additions & 2 deletions test/run-drun/clone.mo
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ actor Cloner {
// passing itself as first argument, using available funds
public shared func makeCloneable(init : Nat): async Lib.Cloneable {
let accepted = Cycles.accept<system>(Cycles.available());
Cycles.add<system>(accepted);
await Lib.Cloneable(makeCloneable, init);
Cycles.add<system>(accepted); // FIXME: remove
await (with cycles = accepted) Lib.Cloneable(makeCloneable, init);
};

public shared func test() : async () {
Expand Down
Loading