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 4 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
1 change: 1 addition & 0 deletions doc/modules/language-guide/examples/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@

<imp> ::=
'import' <id>? '='? <text>
'import' '{' <list(<pat_field>, ';')> '}' '=' <text>
Copy link
Contributor

@crusso crusso Jan 27, 2022

Choose a reason for hiding this comment

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

why not just <pat> = text?

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed the syntax here ought to simply be <pat> (or <pat_nullary>).

Copy link
Contributor Author

@ggreif ggreif Jan 27, 2022

Choose a reason for hiding this comment

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

Doesn't that allow tuple patterns and all the other things (wildcard and literals)?
What would those even mean?
Or should we just delegate those to the type-checker (will error out) and accept _ as a NOP import?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

You could insist the pattern is irrefutable, I think, as with shared function args.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool, that's what I do. I have also added tests for it.

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.

@crusso the pattern matches arising from imports have this form

  (LetD (ObjP (cons (VarP cons)) (nil (VarP nil))) (VarE file$lib/ListM.mo))

but we have little control about the RHS (VarE file$lib/ListM.mo). What we could do is, when in check_ir, detect ids like file$* and run check (Ir_utils.is_irrefutable p) on the LHS pattern. Is this what you mean?

Well, we know a bit about the RHS, after all. It gets built in desugar.ml/transform_import and we can anticipate names. Would it be possible to have an IrrefutableLetD and insert that in transform_import?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@crusso what about 4c94e00?

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.

Okay now I reuse the coverage check from typing.ml but make it an error when its is happening in an error. PTAL! 2d9b797

Copy link
Contributor Author

Choose a reason for hiding this comment

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

JFTR, <pat> gives

      menhir mo_frontend/parser.{ml,mli} (exit 1)
(cd _build/default && /nix/store/ih98div9nccad7gjvksxwzhyl0jag1m7-ocaml4.12.0-menhir-20211012/bin/menhir --table --inspection -v --strict mo_frontend/parser.mly --base mo_frontend/parser)
Error: one state has shift/reduce conflicts.
Warning: one shift/reduce conflict was arbitrarily resolved.


<prog> ::=
<list(<imp>, ';')> <list(<dec>, ';')>
Expand Down
6 changes: 6 additions & 0 deletions src/mo_def/compUnit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ let comp_unit_of_prog as_lib (prog : prog) : comp_unit =
| {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 ({it = ObjP []; _}, _); _} :: ds' ->
go imports ds'
| ({it = LetD (({it = ObjP (f :: fs); _} as letd), ({it = ImportE (url, ri); _} as es)); _} as imp) :: ds' ->
(*let e = { it = DotE (es, f.label); at = es.at; note = e.note.note_typ } in*)
let i : import = { it = (f.it.id, url, ri); note = es.note.note_typ; at = es.at } in
go (imports @ [i]) ({it = LetD ({it = ObjP fs; at = letd.at; note = letd.note}, es); at = imp.at; note = imp.note} :: ds')

(* terminal expressions *)
| [{it = ExpD ({it = ObjBlockE ({it = Type.Module; _}, fields); _} as e); _}] when as_lib ->
Expand Down
2 changes: 2 additions & 0 deletions src/mo_frontend/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,8 @@ 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 LCURLY fps=seplist(pat_field, semicolon) RCURLY EQ f=TEXT
{ LetD(ObjP(fps) @! at $sloc, 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
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>());
5 changes: 5 additions & 0 deletions test/run/ok/import-module-explicit.comp.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Ill-typed intermediate code after Desugaring (use -v to see dumped IR):
import-module-explicit.mo:4.9-4.13: IR type error [M0000], subtype violation:
module {type List<T> = ?(T, List<T>); cons : <T>(T, List<T>) -> List<T>; nil : <T>() -> List<T>}
<T>(T, List<T>) -> List<T>

1 change: 1 addition & 0 deletions test/run/ok/import-module-explicit.comp.ret.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Return code 1
8 changes: 8 additions & 0 deletions test/run/ok/import-module-explicit.diff-ir.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
--- import-module-explicit.run
+++ import-module-explicit.run-ir
@@ -0,0 +1,5 @@
+Ill-typed intermediate code after Desugaring (use -v to see dumped IR):
+import-module-explicit.mo:4.9-4.13: IR type error [M0000], subtype violation:
+ module {type List<T> = ?(T, List<T>); cons : <T>(T, List<T>) -> List<T>; nil : <T>() -> List<T>}
+ <T>(T, List<T>) -> List<T>
+
8 changes: 8 additions & 0 deletions test/run/ok/import-module-explicit.diff-low.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
--- import-module-explicit.run
+++ import-module-explicit.run-low
@@ -0,0 +1,5 @@
+Ill-typed intermediate code after Desugaring (use -v to see dumped IR):
+import-module-explicit.mo:4.9-4.13: IR type error [M0000], subtype violation:
+ module {type List<T> = ?(T, List<T>); cons : <T>(T, List<T>) -> List<T>; nil : <T>() -> List<T>}
+ <T>(T, List<T>) -> List<T>
+
5 changes: 5 additions & 0 deletions test/run/ok/import-module-explicit.run-ir.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Ill-typed intermediate code after Desugaring (use -v to see dumped IR):
import-module-explicit.mo:4.9-4.13: IR type error [M0000], subtype violation:
module {type List<T> = ?(T, List<T>); cons : <T>(T, List<T>) -> List<T>; nil : <T>() -> List<T>}
<T>(T, List<T>) -> List<T>

1 change: 1 addition & 0 deletions test/run/ok/import-module-explicit.run-ir.ret.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Return code 1
5 changes: 5 additions & 0 deletions test/run/ok/import-module-explicit.run-low.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Ill-typed intermediate code after Desugaring (use -v to see dumped IR):
import-module-explicit.mo:4.9-4.13: IR type error [M0000], subtype violation:
module {type List<T> = ?(T, List<T>); cons : <T>(T, List<T>) -> List<T>; nil : <T>() -> List<T>}
<T>(T, List<T>) -> List<T>

1 change: 1 addition & 0 deletions test/run/ok/import-module-explicit.run-low.ret.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Return code 1