-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
re-orgnize type definition before normalizing
- Loading branch information
1 parent
455d785
commit f844f06
Showing
5 changed files
with
160 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
module P = Syntax.Parsetree | ||
|
||
(** Two invariant must hold: | ||
1. A new type definition can be correctly normalize | ||
when its componnet type expressionss can be correctly | ||
normalized | ||
2. A type expression that indicate a type alias, | ||
can be correctly normalized when the normalized alias | ||
definition already added in environment. | ||
*) | ||
let reorg_ty_defs (defs : P.ty_def list) = | ||
(* analyze alias dependency *) | ||
let analyze_deps defs = | ||
List.fold_left | ||
(fun acc def -> | ||
match def with | ||
| P.TDAlias (_, P.TCons (alias, _)) -> ( | ||
match | ||
List.find_opt | ||
(fun def -> | ||
match def with | ||
| P.TDAdt (name', _, _) | ||
| P.TDRecord (name', _, _) | ||
| P.TDAlias (name', _) -> | ||
alias = name') | ||
defs | ||
with | ||
| Some def' -> (def, def') :: acc | ||
| None -> acc) | ||
| _ -> acc) | ||
[] defs | ||
|> List.rev | ||
in | ||
let graph = analyze_deps defs in | ||
let alias_defs, no_alias_defs = | ||
List.fold_left | ||
(fun (ads, nads) def -> | ||
match def with | ||
| P.TDAlias _ -> (def :: ads, nads) | ||
| _ -> (ads, def :: nads)) | ||
([], []) defs | ||
in | ||
let no_alias_defs = List.rev no_alias_defs in | ||
let visited = ref [] in | ||
let rec dfs graph cluster node = | ||
if not (List.memq node !visited) then ( | ||
let cluster = node :: cluster in | ||
visited := node :: !visited; | ||
match List.assoc_opt node graph with | ||
| Some neighber when List.memq neighber alias_defs -> | ||
dfs graph cluster neighber | ||
| _ -> cluster) | ||
else cluster | ||
in | ||
let clusters = | ||
List.fold_left (fun acc def -> dfs graph [] def :: acc) [] alias_defs | ||
in | ||
List.flatten (List.rev clusters) @ no_alias_defs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
open Syntax.Parsing | ||
open Typing | ||
module U = Util | ||
module P = Syntax.Parsetree | ||
|
||
let print_sexp s = | ||
Printf.printf "%s\n" (Sexplib.Sexp.to_string_hum ?indent:(Some 2) s) | ||
|
||
let%expect_test "Test: type def reorg" = | ||
let print_ty_defs_reorgnized str = | ||
Ident.refresh (); | ||
let prog = parse_string_program str in | ||
let[@warning "-8"] (Some defs) = | ||
List.find_map | ||
(fun top -> | ||
match top with | ||
| P.TopTypeDef defs -> Some defs | ||
| _ -> None) | ||
prog | ||
in | ||
defs |> U.reorg_ty_defs |> P.sexp_of_ty_def_group |> print_sexp | ||
in | ||
print_ty_defs_reorgnized {| | ||
type z = y | ||
|
||
and y = x | ||
|
||
and x = int | ||
|}; | ||
[%expect | ||
{| | ||
((TDAlias z (TCons y ())) (TDAlias y (TCons x ())) | ||
(TDAlias x (TCons int ()))) | ||
|}]; | ||
|
||
print_ty_defs_reorgnized | ||
{| | ||
type z = y | ||
|
||
and y = x | ||
|
||
and x = int | ||
|
||
and a = x | ||
|
||
and b = a | ||
and c = b | ||
|}; | ||
[%expect {| | ||
((TDAlias z (TCons y ())) (TDAlias y (TCons x ())) (TDAlias c (TCons b ())) | ||
(TDAlias b (TCons a ())) (TDAlias a (TCons x ())) | ||
(TDAlias x (TCons int ()))) | ||
|}] |