Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 2017-2018 Matthew Fluet. |
2 | * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * Copyright (C) 1997-2000 NEC Research Institute. | |
5 | * | |
6 | * MLton is released under a BSD-style license. | |
7 | * See the file MLton-LICENSE for details. | |
8 | *) | |
9 | ||
10 | functor AstMLBs (S: AST_MLBS_STRUCTS): AST_MLBS = | |
11 | struct | |
12 | ||
13 | open S | |
14 | ||
15 | structure AstPrograms = AstPrograms (S) | |
16 | ||
17 | open AstPrograms Layout | |
18 | ||
19 | fun mkCtxt (x, lay) () = | |
20 | seq [str "in: ", lay x] | |
21 | ||
22 | val layouts = List.map | |
23 | structure Wrap = Region.Wrap | |
24 | val node = Wrap.node | |
25 | ||
26 | (*---------------------------------------------------*) | |
27 | (* Basdecs and Basexps *) | |
28 | (*---------------------------------------------------*) | |
29 | ||
30 | datatype basexpNode = | |
31 | Bas of basdec | |
32 | | Let of basdec * basexp | |
33 | | Var of Basid.t | |
34 | and basdecNode = | |
35 | Ann of string * Region.t * basdec | |
36 | | Basis of {name: Basid.t, def: basexp} vector | |
37 | | Defs of ModIdBind.t | |
38 | | Local of basdec * basdec | |
39 | | MLB of {fileAbs: File.t, fileUse: File.t} * basdec Promise.t | |
40 | | Open of Basid.t vector | |
41 | | Prim | |
42 | | Prog of {fileAbs: File.t, fileUse: File.t} * Program.t Promise.t | |
43 | | Seq of basdec list | |
44 | withtype basexp = basexpNode Wrap.t | |
45 | and basdec = basdecNode Wrap.t | |
46 | ||
47 | fun layoutBasexp exp = | |
48 | case node exp of | |
49 | Bas dec => align [str "bas", indent (layoutBasdec dec, 3), str "end"] | |
50 | | Let (dec, exp) => Pretty.lett (layoutBasdec dec, layoutBasexp exp) | |
51 | | Var basid => Basid.layout basid | |
52 | and layoutBasdec dec = | |
53 | case node dec of | |
54 | Ann (anns,_, dec) => | |
55 | align [str "ann", | |
56 | indent (seq [str String.dquote, str anns, str String.dquote], 3), | |
57 | str "in", | |
58 | indent (layoutBasdec dec, 3), | |
59 | str "end"] | |
60 | | Basis basbnds => | |
61 | layoutAndsBind | |
62 | ("basis", "=", basbnds, fn {name, def} => | |
63 | (case node def of Var _ => OneLine | _ => Split 3, | |
64 | Basid.layout name, layoutBasexp def)) | |
65 | | Defs def => ModIdBind.layout def | |
66 | | Local (dec1, dec2) => Pretty.locall (layoutBasdec dec1, layoutBasdec dec2) | |
67 | | MLB ({fileUse, ...}, _) => File.layout fileUse | |
68 | | Open bs => seq [str "open ", | |
69 | seq (separate (Vector.toListMap (bs, Basid.layout), | |
70 | " "))] | |
71 | | Prim => str "_prim" | |
72 | | Prog ({fileUse, ...}, _) => File.layout fileUse | |
73 | | Seq decs => align (layoutBasdecs decs) | |
74 | and layoutBasdecs decs = layouts (decs, layoutBasdec) | |
75 | ||
76 | fun checkSyntaxBasexp (e: basexp): unit = | |
77 | case node e of | |
78 | Bas dec => checkSyntaxBasdec dec | |
79 | | Let (dec, exp) => (checkSyntaxBasdec dec | |
80 | ; checkSyntaxBasexp exp) | |
81 | | Var _ => () | |
82 | and checkSyntaxBasdec (d: basdec): unit = | |
83 | case node d of | |
84 | Ann (_, _, dec) => checkSyntaxBasdec dec | |
85 | | Basis basbnds => | |
86 | reportDuplicates | |
87 | (basbnds, {ctxt = mkCtxt (d, layoutBasdec), | |
88 | equals = (fn ({name = id, ...}, {name = id', ...}) => | |
89 | Basid.equals (id, id')), | |
90 | layout = Basid.layout o #name, | |
91 | name = "basis definition", | |
92 | region = Basid.region o #name}) | |
93 | | Defs def => ModIdBind.checkSyntax def | |
94 | | Local (dec1, dec2) => | |
95 | (checkSyntaxBasdec dec1 | |
96 | ; checkSyntaxBasdec dec2) | |
97 | | MLB _ => () | |
98 | | Open _ => () | |
99 | | Prim => () | |
100 | | Prog _ => () | |
101 | | Seq decs => List.foreach (decs, checkSyntaxBasdec) | |
102 | ||
103 | fun sourceFiles (d: basdec): File.t vector = | |
104 | let | |
105 | val sourceFiles : File.t Buffer.t = | |
106 | Buffer.new {dummy = "<dummy>"} | |
107 | val psi : File.t -> bool ref = | |
108 | String.memoize (fn _ => ref false) | |
109 | ||
110 | fun sourceFilesBasexp (e: basexp): unit = | |
111 | case node e of | |
112 | Bas dec => sourceFilesBasdec dec | |
113 | | Let (dec, exp) => (sourceFilesBasdec dec | |
114 | ; sourceFilesBasexp exp) | |
115 | | Var _ => () | |
116 | and sourceFilesBasdec (d: basdec): unit = | |
117 | case node d of | |
118 | Ann (_, _, dec) => sourceFilesBasdec dec | |
119 | | Basis basbnds => | |
120 | Vector.foreach | |
121 | (basbnds, fn {def, ...} => | |
122 | sourceFilesBasexp def) | |
123 | | Defs _ => () | |
124 | | Local (dec1, dec2) => (sourceFilesBasdec dec1 | |
125 | ; sourceFilesBasdec dec2) | |
126 | | MLB ({fileAbs, fileUse, ...}, dec) => | |
127 | let | |
128 | val b = psi fileAbs | |
129 | in | |
130 | if !b | |
131 | then () | |
132 | else let | |
133 | val () = b := true | |
134 | in | |
135 | Buffer.add (sourceFiles, fileUse) | |
136 | ; sourceFilesBasdec (Promise.force dec) | |
137 | end | |
138 | end | |
139 | | Open _ => () | |
140 | | Prim => () | |
141 | | Prog ({fileUse, ...}, _) => Buffer.add (sourceFiles, fileUse) | |
142 | | Seq decs => List.foreach (decs, sourceFilesBasdec) | |
143 | val () = sourceFilesBasdec d | |
144 | in | |
145 | Buffer.toVector sourceFiles | |
146 | end | |
147 | val sourceFiles = | |
148 | Trace.trace | |
149 | ("AstMLBs.sourceFiles", Layout.ignore, Vector.layout File.layout) | |
150 | sourceFiles | |
151 | ||
152 | ||
153 | structure Basexp = | |
154 | struct | |
155 | open Wrap | |
156 | type basdec = basdec | |
157 | type t = basexp | |
158 | datatype node = datatype basexpNode | |
159 | type node' = node | |
160 | type obj = t | |
161 | ||
162 | val layout = layoutBasexp | |
163 | end | |
164 | ||
165 | structure Basdec = | |
166 | struct | |
167 | open Wrap | |
168 | type t = basdec | |
169 | datatype node = datatype basdecNode | |
170 | type node' = node | |
171 | type obj = t | |
172 | ||
173 | fun make n = makeRegion (n, Region.bogus) | |
174 | val seq = make o Seq | |
175 | val empty = seq [] | |
176 | val checkSyntax = checkSyntaxBasdec | |
177 | val layout = layoutBasdec | |
178 | val sourceFiles = sourceFiles | |
179 | end | |
180 | end |