forked from mozart/mozart2-compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPOTypes.oz
288 lines (253 loc) · 7.48 KB
/
POTypes.oz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
%%%
%%% Author:
%%% Martin Mueller <[email protected]>
%%%
%%% Copyright:
%%% Martin Mueller, 1997
%%%
%%% Last change:
%%% $Date$ by $Author$
%%% $Revision$
%%%
%%% This file is part of Mozart, an implementation of Oz 3:
%%% http://www.mozart-oz.org
%%%
%%% See the file "LICENSE" or
%%% http://www.mozart-oz.org/LICENSE.html
%%% for information on usage and redistribution
%%% of this file, and for a DISCLAIMER OF ALL
%%% WARRANTIES.
%%%
%%%
%%% when a new data type is added, edit
%%% OzTypes (definition of the partial order)
%%% OzValueToType
%%% define corresponding token classes in CoreLanguage.oz
%%% and edit the method valToSubst in StaticAnalysis.oz
%%% such that it uses the extended core language definition
%%%
local
%% add to list if no duplicate
fun {Add X Ys}
if {Member X Ys} then Ys else X|Ys end
end
%% get list of sort names mentioned
%% in Ord (no duplicates)
fun {GetNames Ord}
{FoldR Ord
fun {$ A#B I} {Add A {Add B I}} end
nil}
end
proc {PartialOrder Ord Def ?Name2Lists ?Name2Index}
Names = {GetNames Ord}
N = {Length Names}
%% define mapping names -> indexes
proc {IdxMapping N2I}
N2I = {FD.record n2i Names 1#N}
%% numbering must respect the partial order
{ForAll Ord
proc {$ A#B}
{FD.less N2I.B N2I.A}
end}
%% numbering must be one-one
{FD.distinct N2I}
%% go
{FD.distribute naive N2I}
end
% define mapping names -> bit arrays
proc {SetMapping ?N2S}
N2S = {Record.make n2s Names}
% for propagation purposes,
% each sort is encoded as a subset of {1..N}
% including the index of the sort (open world!)
{ForAll Names
proc {$ X}
SX = {FS.var.upperBound [1#N]}
in
N2S.X = SX
{FS.include Name2Index.X SX}
end}
% set encoding must respect partial ordering
{ForAll Ord
proc {$ A#B}
{FS.subset N2S.A N2S.B}
end}
% minimize set values after proPagation
{ForAll Names
proc {$ Nam}
S = N2S.Nam
in
{Space.waitStable}
S = {FS.value.make {FS.reflect.lowerBound S}}
end}
end
Name2Sets
in
% compute mapping (basic) names <-> indexes
Name2Index = {Search.base.one IdxMapping}.1
% compute mapping (basic) names <-> sets
Name2Sets = {Search.base.one SetMapping}.1
% compute mapping (basic) names <-> lists of integers
Name2Lists = {Record.map Name2Sets FS.monitorIn}
end
fun {MkPartialOrder Name2Lists Name2Index DefinedNames}
Names = {Arity Name2Lists}
N = {Width Name2Lists}
AllNames = {Append {Map DefinedNames fun {$ def(N _)} N end} Names}
% compute mapping index <-> sort name
Index2Name = {Tuple.make i2n {Width Name2Index}}
{ForAll Names
proc {$ Nam}
Index2Name.(Name2Index.Nam) = Nam
end}
% each sort (basic or not) is represented as bit array
Name2Bits = {Record.make n2b AllNames}
{Record.forAll Name2Bits
proc {$ B} B = {BitArray.new 1 N} end}
{ForAll Names
proc {$ Nam}
{For 1 N 1
proc {$ I}
if {Member I Name2Lists.Nam}
then {BitArray.set Name2Bits.Nam I}
else skip end
end}
end}
% encodes type: V Pos and not & Neg
proc {Constrain Pos Neg S}
if {IsAtom Pos}
then {BitArray.disj S Name2Bits.Pos}
else {ForAll Pos
proc {$ P}
if {HasFeature Name2Bits P}
then {BitArray.disj S Name2Bits.P}
else {Exception.raiseError compiler(internal constrain)}
end
end}
end
{ForAll Neg
proc {$ N}
if {HasFeature Name2Bits N}
then {BitArray.nimpl S Name2Bits.N}
else {Exception.raiseError compiler(internal contrain)} end
end}
end
proc {Encode Pos Neg ?S}
if Pos==nil
then {Exception.raiseError compiler(internal illegalType)}
else S = {BitArray.new 1 N} {Constrain Pos Neg S} end
end
% return best upper approximation of type
local
fun {DecodeAux S}
case {BitArray.toList S} % BitArray.min waere nett
of nil then nil
elseof I|_ then
N = Index2Name.I
in
{BitArray.nimpl S Name2Bits.N}
N | {DecodeAux S}
end
end
in
fun {Decode S}
if {IsFree S}
then [value]
else {DecodeAux {BitArray.clone S}}
end
end
end
in
% add defined names
{ForAll DefinedNames
proc {$ def(N Ns)}
if {Member N Names}
then {Exception.raiseError
compiler(internal illegalPartialOrderSpecification)}
else Name2Bits.N = {Constrain Ns nil}
end
end}
po(encode: Encode
decode: Decode
decl: fun {$} {BitArray.new 1 N} end
isMinimal: fun {$ T} {BitArray.card T} == 1 end
constrain: BitArray.conj
clash: BitArray.disjoint
clone: BitArray.clone
toList: fun {$ T}
{Map {BitArray.toList T} fun {$ I} Index2Name.I end}
end
)
end
% inclusion subtypes
OzInclusions
= ['thread' # value
space # value
chunk # value
cell # value
foreignPointer # value
fset # value
recordC# value
record # recordC
number # value
int # number
float # number
char # fdIntC
fdIntC # int
tuple # record
literal# tuple
atom # literal
name # literal
nilAtom# atom
cons # tuple
bool # name
'unit' # name
bitArray # chunk
array # chunk
dictionary # chunk
'class'# chunk
'object'# chunk
'lock' # chunk
port # chunk
'procedure/0' # value
'procedure/1' # value
'procedure/2' # value
'procedure/3' # value
'procedure/4' # value
'procedure/5' # value
'procedure/6' # value
'procedure/>6' # value
pair # tuple
bitString # value
byteString # value
]
% partitioned subtypes
OzDefinedNames
= [def(feature [int literal])
def(comparable [number atom])
def(recordOrChunk [record chunk])
def(recordCOrChunk [recordC chunk])
def(list [nilAtom cons])
def(string [nilAtom cons])
def(procedure ['procedure/0'
'procedure/1'
'procedure/2'
'procedure/3'
'procedure/4'
'procedure/5'
'procedure/6'
'procedure/>6'])
def(virtualString [number record byteString])
def(procedureOrObject [procedure object])
def(unaryProcOrObject ['procedure/1' object])
]
OzPartialOrderAsSets
OzName2Index
in
{PartialOrder OzInclusions OzDefinedNames
OzPartialOrderAsSets
OzName2Index}
fun {MkOzPartialOrder}
{MkPartialOrder OzPartialOrderAsSets OzName2Index OzDefinedNames}
end
end