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
|
-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
-- All rights reserved.
-- Copyright (C) 2007-2008, Gabriel Dos Reis.
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are
-- met:
--
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
-- names of its contributors may be used to endorse or promote products
-- derived from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import '"compiler"
)package "BOOT"
compAtomWithModemap: (%Form,%Mode,%Env,%Thing) -> %Triple
compAtomWithModemap(x,m,e,v) ==
Tl :=
[[transImplementation(x,map,fn),target,e]
for map in v | map is [[.,target],[.,fn]]] =>
--accept only monadic operators
T:= or/[t for (t:= [.,target,.]) in Tl | modeEqual(m,target)] => T
1=#(Tl:= [y for t in Tl | (y:= convert(t,m))]) => first Tl
0<#Tl and m=$NoValueMode => first Tl
nil
transImplementation: (%Form,%Modemap,%Thing) -> %Code
transImplementation(op,map,fn) ==
fn := genDeltaEntry [op,:map]
fn is ["XLAM",:.] => [fn]
["call",fn]
compApply: (%List,%List,%Thing,%List,%Mode,%Env) -> %Triple
compApply(sig,varl,body,argl,m,e) ==
argTl:= [[.,.,e]:= comp(x,$EmptyMode,e) for x in argl]
contour:=
[Pair(x,[["mode",m'],["value",removeEnv comp(a,m',e)]])
for x in varl for m' in sig.source for a in argl]
code:= [["LAMBDA",varl,body'],:[T.expr for T in argTl]]
m':= resolve(m,sig.target)
body':= (comp(body,m',addContour(contour,e))).expr
[code,m',e]
compToApply: (%Form,%List,%Mode,%Env) -> %Triple
compToApply(op,argl,m,e) ==
T:= compNoStacking(op,$EmptyMode,e) or return nil
m1:= T.mode
T.expr is ["QUOTE", =m1] => nil
compApplication(op,argl,m,T.env,T)
compApplication: (%Form,%List,%Mode,%Env,%Triple) -> %Triple
compApplication(op,argl,m,e,T) ==
T.mode is ['Mapping, retm, :argml] =>
#argl ^= #argml => nil
retm := resolve(m, retm)
retm = $Category or isCategoryForm(retm,e) => nil -- not handled
argTl := [[.,.,e] := comp(x,m,e) or return "failed"
for x in argl for m in argml]
argTl = "failed" => nil
form:=
not (member(op,$formalArgList) or member(T.expr,$formalArgList)) and ATOM T.expr =>
nprefix := $prefix or
-- following needed for referencing local funs at capsule level
getAbbreviation($op,#rest $form)
[op',:[a.expr for a in argTl],"$"] where
op':= INTERN STRCONC(encodeItem nprefix,";",encodeItem T.expr)
['call, ['applyFun, T.expr], :[a.expr for a in argTl]]
coerce([form, retm, e],resolve(retm,m))
op = 'elt => nil
eltForm := ['elt, op, :argl]
comp(eltForm, m, e)
compFormWithModemap: (%Form,%Mode,%Env,%Modemap) -> %Triple
compFormWithModemap(form is [op,:argl],m,e,modemap) ==
[map:= [.,target,:.],[pred,impl]]:= modemap
-- this fails if the subsuming modemap is conditional
--impl is ['Subsumed,:.] => nil
if isCategoryForm(target,e) and isFunctor op then
[modemap,e]:= substituteIntoFunctorModemap(argl,modemap,e) or return nil
[map:= [.,target,:.],:cexpr]:= modemap
sv:=listOfSharpVars map
if sv then
-- SAY [ "compiling ", op, " in compFormWithModemap,
-- mode= ",map," sharp vars=",sv]
for x in argl for ss in $FormalMapVariableList repeat
if ss in sv then
[map:= [.,target,:.],:cexpr]:= modemap :=SUBST(x,ss,modemap)
-- SAY ["new map is",map]
not (target':= coerceable(target,m,e)) => nil
map:= [target',:rest map]
[f,Tl,sl]:= compApplyModemap(form,modemap,e,nil) or return nil
--generate code; return
T:=
[x',m',e'] where
m':= SUBLIS(sl,map.(1))
x':=
form':= [f,:[t.expr for t in Tl]]
m'=$Category or isCategoryForm(m',e) => form'
-- try to deal with new-style Unions where we know the conditions
op = "elt" and f is ['XLAM,:.] and IDENTP(z:=CAR argl) and
(c:=get(z,'condition,e)) and
c is [["case",=z,c1]] and
(c1 is [":",=(CADR argl),=m] or EQ(c1,CADR argl) ) =>
-- first is a full tag, as placed by getInverseEnvironment
-- second is what getSuccessEnvironment will place there
["CDR",z]
["call",:form']
e':=
Tl => (LAST Tl).env
e
convert(T,m)
-- This version tends to give problems with #1 and categories
-- applyMapping([op,:argl],m,e,ml) ==
-- #argl^=#ml-1 => nil
-- mappingHasCategoryTarget :=
-- isCategoryForm(first ml,e) => --is op a functor?
-- form:= [op,:argl']
-- pairlis:= [[v,:a] for a in argl for v in $FormalMapVariableList]
-- ml:= SUBLIS(pairlis,ml)
-- true
-- false
-- argl':=
-- [T.expr for x in argl for m' in rest ml] where
-- T() == [.,.,e]:= comp(x,m',e) or return "failed"
-- if argl'="failed" then return nil
-- mappingHasCategoryTarget => convert([form,first ml,e],m)
-- form:=
-- not member(op,$formalArgList) and ATOM op =>
-- [op',:argl',"$"] where
-- op':= INTERN STRCONC(STRINGIMAGE $prefix,";",STRINGIMAGE op)
-- ["call",["applyFun",op],:argl']
-- pairlis:= [[v,:a] for a in argl' for v in $FormalMapVariableList]
-- convert([form,SUBLIS(pairlis,first ml),e],m)
applyMapping: (%Form,%Mode,%Env,%List) -> %Triple
applyMapping([op,:argl],m,e,ml) ==
#argl^=#ml-1 => nil
isCategoryForm(first ml,e) =>
--is op a functor?
pairlis:= [[v,:a] for a in argl for v in $FormalMapVariableList]
ml' := SUBLIS(pairlis, ml)
argl':=
[T.expr for x in argl for m' in rest ml'] where
T() == [.,.,e]:= comp(x,m',e) or return "failed"
if argl'="failed" then return nil
form:= [op,:argl']
convert([form,first ml',e],m)
argl':=
[T.expr for x in argl for m' in rest ml] where
T() == [.,.,e]:= comp(x,m',e) or return "failed"
if argl'="failed" then return nil
form:=
not member(op,$formalArgList) and ATOM op and not get(op,'value,e) =>
nprefix := $prefix or
-- following needed for referencing local funs at capsule level
getAbbreviation($op,#rest $form)
[op',:argl',"$"] where
op':= INTERN STRCONC(encodeItem nprefix,";",encodeItem op)
['call,['applyFun,op],:argl']
pairlis:= [[v,:a] for a in argl' for v in $FormalMapVariableList]
convert([form,SUBLIS(pairlis,first ml),e],m)
--% APPLY MODEMAPS
compApplyModemap: (%Form,%Modemap,%Env,%List) -> %Triple
compApplyModemap(form,modemap,$e,sl) ==
[op,:argl] := form --form to be compiled
[[mc,mr,:margl],:fnsel] := modemap --modemap we are testing
-- $e is the current environment
-- sl substitution list, nil means bottom-up, otherwise top-down
-- 0. fail immediately if #argl=#margl
if #argl^=#margl then return nil
-- 1. use modemap to evaluate arguments, returning failed if
-- not possible
lt:=
[[.,m',$e]:=
comp(y,g,$e) or return "failed" where
g:= SUBLIS(sl,m) where
sl:= pmatchWithSl(m',m,sl) for y in argl for m in margl]
lt="failed" => return nil
-- 2. coerce each argument to final domain, returning failed
-- if not possible
lt':= [coerce(y,d) or return "failed"
for y in lt for d in SUBLIS(sl,margl)]
lt'="failed" => return nil
-- 3. obtain domain-specific function, if possible, and return
--$bindings is bound by compMapCond
[f,$bindings]:= compMapCond(op,mc,sl,fnsel) or return nil
--+ can no longer trust what the modemap says for a reference into
--+ an exterior domain (it is calculating the displacement based on view
--+ information which is no longer valid; thus ignore this index and
--+ store the signature instead.
f is [op1,d,.] and member(op1,'(ELT CONST Subsumed)) =>
[genDeltaEntry [op,:modemap],lt',$bindings]
[f,lt',$bindings]
compMapCond: (%Symbol,%Mode,%Env,%List) -> %Code
compMapCond(op,mc,$bindings,fnsel) ==
or/[compMapCond'(u,op,mc,$bindings) for u in fnsel]
compMapCond': (%List,%Symbol,%Mode,%Env) -> %Code
compMapCond'([cexpr,fnexpr],op,dc,bindings) ==
compMapCond''(cexpr,dc) => compMapCondFun(fnexpr,op,dc,bindings)
stackMessage ["not known that",'%b,dc,'%d,"has",'%b,cexpr,'%d]
compMapCond'': (%Thing,%Mode) -> %Boolean
compMapCond''(cexpr,dc) ==
cexpr=true => true
--cexpr = "true" => true
cexpr is ["AND",:l] => and/[compMapCond''(u,dc) for u in l]
cexpr is ["OR",:l] => or/[compMapCond''(u,dc) for u in l]
cexpr is ["not",u] => not compMapCond''(u,dc)
cexpr is ["has",name,cat] => (knownInfo cexpr => true; false)
--for the time being we'll stop here - shouldn't happen so far
--$disregardConditionIfTrue => true
--stackSemanticError(("not known that",'%b,name,
-- '%d,"has",'%b,cat,'%d),nil)
--now it must be an attribute
member(["ATTRIBUTE",dc,cexpr],get("$Information","special",$e)) => true
--for the time being we'll stop here - shouldn't happen so far
stackMessage ["not known that",'%b,dc,'%d,"has",'%b,cexpr,'%d]
false
compMapCondFun: (%Thing,%Symbol,%Mode,%Env) -> %Code
compMapCondFun(fnexpr,op,dc,bindings) ==
[fnexpr,bindings]
|