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: generalized imports supporting pattern matching and selective field import #3076

Merged
merged 56 commits into from
Jan 28, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
b46e72a
first shot at #2354
ggreif Jan 27, 2022
e6e9915
add test
ggreif Jan 27, 2022
67500bf
improve a bit
ggreif Jan 27, 2022
2d40582
unit grooming
ggreif Jan 27, 2022
1556274
cleaner
ggreif Jan 27, 2022
3b120ee
resolve the type error at the access site
ggreif Jan 27, 2022
bcf3fcb
resolve the module vs. field of module ambiguity
ggreif Jan 27, 2022
59efd68
thread the module note through
ggreif Jan 27, 2022
957f912
clean up
ggreif Jan 27, 2022
a1ee29c
get the module `VarE`'s type right
ggreif Jan 27, 2022
91c3708
cleanup
ggreif Jan 27, 2022
8d7fb3c
make it `'import' <pat_nullary> '='? <text>`
ggreif Jan 27, 2022
8fe6866
pointless
ggreif Jan 27, 2022
ddcef0f
also pointless
ggreif Jan 27, 2022
f581947
Update src/mo_frontend/parser.mly
ggreif Jan 27, 2022
0eff5af
capture the entire pattern
ggreif Jan 27, 2022
999d654
cleanups
ggreif Jan 27, 2022
c32448f
make `comp_unit_of_prog` linear-time
ggreif Jan 27, 2022
58c629c
Revert "pointless"
ggreif Jan 27, 2022
ad314b7
Revert "also pointless"
ggreif Jan 27, 2022
2e9df25
use modern syntax
ggreif Jan 27, 2022
7293902
fix repl tests
ggreif Jan 27, 2022
93dcc88
a few dodgy imports
ggreif Jan 28, 2022
1a0a069
accept
ggreif Jan 28, 2022
e72ce22
more failure modes
ggreif Jan 28, 2022
d43c7ab
ignore explicit imports for now
ggreif Jan 28, 2022
3669465
ocamlformat
ggreif Jan 28, 2022
6efb5f6
mention explicit imports
ggreif Jan 28, 2022
b109d6d
typo
ggreif Jan 28, 2022
4c94e00
teach IR typechecker to reject refutable import patterns
ggreif Jan 28, 2022
1eef8dc
document the new syntax for imports
ggreif Jan 28, 2022
e3ee5f1
show how specific bindings can be imported
ggreif Jan 28, 2022
968cadc
demonstrate renaming on import
ggreif Jan 28, 2022
9c911ca
it is `<pat>` now
ggreif Jan 28, 2022
2c3f4aa
Update doc/modules/language-guide/pages/overview.adoc
ggreif Jan 28, 2022
2503343
DRY
ggreif Jan 28, 2022
0e0b65a
Update src/docs/extract.ml
ggreif Jan 28, 2022
656b48c
Update doc/modules/language-guide/pages/language-manual.adoc
ggreif Jan 28, 2022
9dc287a
Update doc/modules/language-guide/pages/language-manual.adoc
ggreif Jan 28, 2022
c59e85a
Update doc/modules/language-guide/pages/language-manual.adoc
ggreif Jan 28, 2022
a2aeae4
Update src/ir_def/check_ir.ml
ggreif Jan 28, 2022
d0dff31
remove cruft
ggreif Jan 28, 2022
2d9b797
use the coverage checker to reject refutable import patterns
ggreif Jan 28, 2022
37b2838
Update doc/modules/language-guide/pages/language-manual.adoc
ggreif Jan 28, 2022
c763ff8
Update src/ir_def/check_ir.ml
ggreif Jan 28, 2022
feec77b
back
ggreif Jan 28, 2022
988c27f
forgotten
ggreif Jan 28, 2022
c98c798
add example
ggreif Jan 28, 2022
a3ac786
ooops
ggreif Jan 28, 2022
2ae3cbb
Update doc/modules/language-guide/pages/language-manual.adoc
ggreif Jan 28, 2022
3e8226c
Update language-manual.adoc
ggreif Jan 28, 2022
b5ed7d0
reindent
ggreif Jan 28, 2022
1ddcf93
tweak again
ggreif Jan 28, 2022
95a93a8
Merge branch 'master' into gabor/deconstruct-import
ggreif Jan 28, 2022
ca01c14
move an item
ggreif Jan 28, 2022
af6941a
demonstrate that actor methods cannot be imported explicitly
ggreif Jan 28, 2022
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
2 changes: 1 addition & 1 deletion doc/modules/language-guide/examples/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@
<obj_body>

<imp> ::=
'import' <id>? '='? <text>
'import' <pat_nullary> '='? <text>
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason this isn't just <pat> as for let?

Copy link
Contributor Author

@ggreif ggreif Jan 28, 2022

Choose a reason for hiding this comment

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

We don't want (?(#foo)) here, do we? <pat> just doesn't have any sensible use-case in this place.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, but I don't think we should enforce typing properties using the grammar.
Also, it keeps the grammar closer to the informal language reference.
Plus, you might want a type annotation on the pattern without having to parenthesize it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can I do this tomorrow in a new PR? I am totally burnt out, sorry.

Copy link
Contributor

Choose a reason for hiding this comment

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

Of course.

Copy link
Contributor

Choose a reason for hiding this comment

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

Tomorrow is saturday. Monday!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't work: #3076 (comment)


<prog> ::=
<list(<imp>, ';')> <list(<dec>, ';')>
Expand Down
2 changes: 1 addition & 1 deletion src/docs/extract.ml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ let un_prog prog =
let imports =
List.map
(fun i ->
let alias, path, _ = i.it in
let Syntax.{ it = VarP alias; _ }, path, _ = i.it in
(alias.it, path))
imports
in
Expand Down
4 changes: 2 additions & 2 deletions src/lowering/desugar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ let link_declarations imports (cu, flavor) =


let transform_import (i : S.import) : import_declaration =
let (id, f, ir) = i.it in
let (p, f, ir) = i.it in
let t = i.note in
assert (t <> T.Pre);
let rhs = match !ir with
Expand All @@ -869,7 +869,7 @@ let transform_import (i : S.import) : import_declaration =
varE (var (id_of_full_path "@prim") t)
| S.IDLPath (fp, canister_id) ->
primE (I.ActorOfIdBlob t) [blobE canister_id]
in [ letD (var id.it t) rhs ]
in [ letP (pat p) rhs ]

let transform_unit_body (u : S.comp_unit_body) : Ir.comp_unit =
match u.it with
Expand Down
26 changes: 14 additions & 12 deletions src/mo_def/compUnit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ let comp_unit_of_prog as_lib (prog : prog) : comp_unit =
let open Source in
let f = prog.note in

let finish imports u = { it = { imports; body = u }; note = f; at = no_region } in
let finish imports u =
{ it = { imports = List.rev imports; body = u }; note = f; at = no_region } in
let prog_typ_note = { empty_typ_note with note_typ = Type.unit } in

let rec go imports ds : comp_unit =
match ds with
(* imports *)
| {it = LetD ({it = VarP n; _}, ({it = ImportE (url, ri); _} as e)); _} :: ds' ->
let i : import = { it = (n, url, ri); note = e.note.note_typ; at = e.at } in
go (imports @ [i]) ds'
| {it = LetD (p, ({it = ImportE (url, ri); _} as e)); _} :: ds' ->
let i : import = { it = (p, url, ri); note = e.note.note_typ; at = e.at } in
go (i :: imports) ds'

(* terminal expressions *)
| [{it = ExpD ({it = ObjBlockE ({it = Type.Module; _}, fields); _} as e); _}] when as_lib ->
Expand Down Expand Up @@ -88,14 +89,15 @@ let obj_decs obj_sort at note id_opt fields =
let decs_of_lib (cu : comp_unit) =
let open Source in
let { imports; body = cub; _ } = cu.it in
let import_decs = List.map (fun { it = (id, fp, ri); at; note} ->
{ it = LetD (
{ it = VarP id; at; note; },
{ it = ImportE (fp, ri);
at;
note = { note_typ = note; note_eff = Type.Triv} });
at;
note = { note_typ = note; note_eff = Type.Triv } }) imports
let import_decs =
List.map (fun { it = (pat, fp, ri); at; note} ->
{ it = LetD (pat,
{ it = ImportE (fp, ri);
at;
note = { note_typ = note; note_eff = Type.Triv} });
at;
note = { note_typ = note; note_eff = Type.Triv } }
) imports
Copy link
Contributor

Choose a reason for hiding this comment

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

Use the identation style on the left - I think that's what Andreas was advocating... (at least my understanding of it).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is what emacs gave me, will change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in
import_decs,
match cub.it with
Expand Down
2 changes: 1 addition & 1 deletion src/mo_def/syntax.ml
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ and stab_sig' = (dec list * typ_field list) (* type declarations & stable a
(* Compilation units *)

type import = (import', Type.typ) Source.annotated_phrase
and import' = id * string * resolved_import ref
and import' = pat * string * resolved_import ref

type comp_unit_body = (comp_unit_body', typ_note) Source.annotated_phrase
and comp_unit_body' =
Expand Down
5 changes: 2 additions & 3 deletions src/mo_frontend/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -871,9 +871,8 @@ class_body :
(* Programs *)

imp :
| IMPORT xf=id_opt EQ? f=TEXT
{ let _, x = xf "import" $sloc in
let_or_exp true x (ImportE (f, ref Unresolved)) (at $sloc) }
| IMPORT p=pat_nullary EQ? f=TEXT
{ LetD(p, ImportE(f, ref Unresolved) @? at $sloc) @? at $sloc }

start : (* dummy non-terminal to satisfy ErrorReporting.ml, that requires a non-empty parse stack *)
| (* empty *) { () }
Expand Down
1 change: 0 additions & 1 deletion test/fail/not-static.mo

This file was deleted.

1 change: 0 additions & 1 deletion test/fail/self-import.mo

This file was deleted.

5 changes: 5 additions & 0 deletions test/run/import-module-explicit.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { cons; nil } = "lib/ListM";

//type stack = List<Int>;
let s = cons(1, nil());
let u = cons<Int>(2, nil<Int>());