From c75b5923cb35d83910e45f13e9d15c981ea25387 Mon Sep 17 00:00:00 2001 From: dos-reis Date: Thu, 20 Sep 2007 04:57:39 +0000 Subject: remove pamphlets - part 7 --- src/interp/wi1.boot | 1261 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1261 insertions(+) create mode 100644 src/interp/wi1.boot (limited to 'src/interp/wi1.boot') diff --git a/src/interp/wi1.boot b/src/interp/wi1.boot new file mode 100644 index 00000000..e6eb3ef2 --- /dev/null +++ b/src/interp/wi1.boot @@ -0,0 +1,1261 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- 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. + + +)package "BOOT" + +-- !! do not delete the next function ! + +spad2AsTranslatorAutoloadOnceTrigger() == nil + +pairList(u,v) == [[x,:y] for x in u for y in v] + +--====================================================================== +-- Temporary definitions---for tracing and debugging +--====================================================================== +tr fn == + $convertingSpadFile : local := true + $options: local := nil + sfn := STRINGIMAGE fn + newname := STRCONC(sfn,'".as") + $outStream :local := MAKE_-OUTSTREAM newname + markSay '"#pile" + markSay('"#include _"axiom.as_"") + markTerpri() + CATCH("SPAD__READER",compiler [INTERN sfn]) + SHUT $outStream + +stackMessage msg == +--if msg isnt ["cannot coerce: ",:.] then foobum msg + $compErrorMessageStack:= [msg,:$compErrorMessageStack] + nil + +ppFull x == + _*PRINT_-LEVEL_* : local := nil + _*PRINT_-DEPTH_* : local := nil + _*PRINT_-LENGTH_* : local := nil + pp x + +put(x,prop,val,e) == +--if prop = 'mode and CONTAINED('PART,val) then foobar val + $InteractiveMode and not EQ(e,$CategoryFrame) => + putIntSymTab(x,prop,val,e) + --e must never be $CapsuleModemapFrame + null atom x => put(first x,prop,val,e) + newProplist:= augProplistOf(x,prop,val,e) + prop="modemap" and $insideCapsuleFunctionIfTrue=true => + SAY ["**** modemap PUT on CapsuleModemapFrame: ",val] + $CapsuleModemapFrame:= + addBinding(x,augProplistOf(x,"modemap",val,$CapsuleModemapFrame), + $CapsuleModemapFrame) + e + addBinding(x,newProplist,e) + +addBinding(var,proplist,e is [[curContour,:tailContour],:tailEnv]) == +--if CONTAINED('PART,proplist) then foobar proplist + EQ(proplist,getProplist(var,e)) => e + $InteractiveMode => addBindingInteractive(var,proplist,e) + if curContour is [[ =var,:.],:.] then curContour:= rest curContour + --Previous line should save some space + [[[lx,:curContour],:tailContour],:tailEnv] where lx:= [var,:proplist] + +--====================================================================== +-- From define.boot +--====================================================================== +compJoin(["Join",:argl],m,e) == + catList:= [(compForMode(x,$Category,e) or return 'failed).expr for x in argl] + catList='failed => stackSemanticError(["cannot form Join of: ",argl],nil) + catList':= + [extract for x in catList] where + extract() == + x := markKillAll x + isCategoryForm(x,e) => + parameters:= + union("append"/[getParms(y,e) for y in rest x],parameters) + where getParms(y,e) == + atom y => + isDomainForm(y,e) => LIST y + nil + y is ['LENGTH,y'] => [y,y'] + LIST y + x + x is ["DomainSubstitutionMacro",pl,body] => + (parameters:= union(pl,parameters); body) + x is ["mkCategory",:.] => x + atom x and getmode(x,e)=$Category => x + stackSemanticError(["invalid argument to Join: ",x],nil) + x + T:= [wrapDomainSub(parameters,["Join",:catList']),$Category,e] + convert(T,m) + + +compDefineFunctor(dfOriginal,m,e,prefix,fal) == + df := markInsertParts dfOriginal + $domainShell: local -- holds the category of the object being compiled + $profileCompiler: local := true + $profileAlist: local := nil + $LISPLIB => compDefineLisplib(df,m,e,prefix,fal,'compDefineFunctor1) + compDefineFunctor1(df,m,e,prefix,fal) + +compDefineLisplib(df,m,e,prefix,fal,fn) == + ["DEF",[op,:.],:.] := df + --fn= compDefineCategory OR compDefineFunctor + sayMSG fillerSpaces(72,'"-") + $LISPLIB: local := 'T + $op: local := op + $lisplibAttributes: local := NIL + $lisplibPredicates: local := NIL -- set by makePredicateBitVector + $lisplibCategoriesExtended: local := NIL -- this is always nil. why? (tpd) + $lisplibForm: local := NIL + $lisplibKind: local := NIL + $lisplibModemap: local := NIL + $lisplibModemapAlist: local := NIL + $lisplibSlot1 : local := NIL -- used by NRT mechanisms + $lisplibOperationAlist: local := NIL + $lisplibSuperDomain: local := NIL + $libFile: local := NIL + $lisplibVariableAlist: local := NIL + $lisplibRelatedDomains: local := NIL --from ++ Related Domains: see c-doc + $lisplibCategory: local := nil + --for categories, is rhs of definition; otherwise, is target of functor + --will eventually become the "constructorCategory" property in lisplib + --set in compDefineCategory if category, otherwise in finalizeLisplib + libName := getConstructorAbbreviation op + -- $incrementalLisplibFlag seems never to be set so next line not used + -- originalLisplibCategory:= getLisplib(libName,'constructorCategory) + BOUNDP '$compileDocumentation and $compileDocumentation => + compileDocumentation libName + sayMSG ['" initializing ",$spadLibFT,:bright libName, + '"for",:bright op] + initializeLisplib libName + sayMSG ['" compiling into ",$spadLibFT,:bright libName] + res:= FUNCALL(fn,df,m,e,prefix,fal) + sayMSG ['" finalizing ",$spadLibFT,:bright libName] +--finalizeLisplib libName + FRESH_-LINE $algebraOutputStream + sayMSG fillerSpaces(72,'"-") + unloadOneConstructor(op,libName) + res + +compTopLevel(x,m,e) == +--+ signals that target is derived from lhs-- see NRTmakeSlot1Info + $NRTderivedTargetIfTrue: local := false + $killOptimizeIfTrue: local:= false + $forceAdd: local:= false + $compTimeSum: local := 0 + $resolveTimeSum: local := 0 + $packagesUsed: local := [] + -- The next line allows the new compiler to be tested interactively. + compFun := if $newCompAtTopLevel=true then 'newComp else 'compOrCroak + if x is ["where",:.] then x := markWhereTran x + def := + x is ["where",a,:.] => a + x + $originalTarget : local := + def is ["DEF",.,[target,:.],:.] => target + 'sorry + x is ["DEF",:.] or x is ["where",["DEF",:.],:.] => + ([val,mode,.]:= FUNCALL(compFun,x,m,e); [val,mode,e]) + --keep old environment after top level function defs + FUNCALL(compFun,x,m,e) + +markWhereTran ["where",["DEF",form,sig,clist,body],:tail] == + items := + tail is [['SEQ,:l,['exit,n,x]]] => [:l,x] + [first tail] + [op,:argl] := form + [target,:atypeList] := sig + decls := [[":",a,b] for a in argl for b in atypeList | b] +-- not (and/[null x for x in atypeList]) => +-- systemError ['"unexpected WHERE argument list: ",:atypeList] + for x in items repeat + x is [":",a,b] => + a is ['LISTOF,:r] => + for y in r repeat decls := [[":",y,b],:decls] + decls := [x,:decls] + x is [key,fn,p,q,bd] and MEMQ(key,'(DEF MDEF)) and p='(NIL) and q='(NIL) => + fn = target or fn is [=target] => ttype := bd + fn = body or fn is [=body] => body := bd + macros := [x,:macros] + systemError ['"unexpected WHERE item: ",x] + nargtypes := [p for arg in argl | + p := or/[t for d in decls | d is [.,=arg,t]] or + systemError ['"Missing WHERE declaration for :", arg]] + nform := form + ntarget := ttype or target + ndef := ['DEF,nform,[ntarget,:nargtypes],clist,body] + result := + REVERSE macros is [:m,e] => + mpart := + m => ['SEQ,:m,['exit,1,e]] + e + ['where,ndef,mpart] + ndef + result + +compPART(u,m,e) == +--------new------------------------------------------94/10/11 + ['PART,.,x] := u + T := comp(x,m,e) => markAny('compPART,u, T) + nil + +xxxxx x == x + +qt(n,T) == + null T => nil + if null getProplist('R,T.env) then xxxxx n + T + +qe(n,e) == + if null getProplist('R,e) then xxxxx n + e + +comp(x,m,e) == + qe(7,e) + T := qt(8,comp0(x,m,e)) => qt(9,markComp(x,T)) +--T := m = "$" and comp(x,$EmptyMode,e) => coerce(T, m) + --------------------------------------------------------94/11/10 + nil + +comp0(x,m,e) == + qe(8,e) +--version of comp which skips the marking (see compReduce1) + T:= compNoStacking(x,m,e) => + $compStack:= nil + qt(10,T) + $compStack:= [[x,m,e,$exitModeStack],:$compStack] + nil + +compNoStacking(xOrig,m,e) == + $partExpression: local := nil + xOrig := markKillAllRecursive xOrig +-->xOrig is ['PART,n,x] => compNoStackingAux(xOrig,m,e) +----------------------------------------------------------94/10/11 + qt(11,compNoStacking0(xOrig,m,e)) + +markKillAllRecursive x == + x is [op,:r] => +--->op = 'PART => markKillAllRecursive CADR r + op = 'PART => ['PART, CAR r, markKillAllRecursive CADR r] +----------------------------------------------------------94/10/11 + constructor? op => markKillAll x + op = 'elt and constructor? opOf CAR r => + ['elt,markKillAllRecursive CAR r,CADR r] + x + x + +compNoStackingAux($partExpression,m,e) == +-----------------not used---------------------94/10/11 + x := CADDR $partExpression + T := compNoStacking0(x,m,e) or return nil + markParts($partExpression,T) + +compNoStacking0(x,m,e) == + qe(1,e) + T := compNoStacking01(x,m,qe(51,e)) + qt(52,T) + +compNoStacking01(x,m,e) == +--compNoStacking0(x,m,e) == + if CONTAINED('MI,m) then m := markKillAll(m) + T:= comp2(x,m,e) => + (m=$EmptyMode and T.mode=IFCAR(get('Rep,'value,e)) => + [T.expr,"Rep",T.env]; qt(12,T)) + --$Representation is bound in compDefineFunctor, set by doIt + --this hack says that when something is undeclared, $ is + --preferred to the underlying representation -- RDJ 9/12/83 + T := compNoStacking1(x,m,e,$compStack) + qt(13,T) + +compNoStacking1(x,m,e,$compStack) == + u:= get(if m="$" then "Rep" else m,"value",e) => + m1 := markKillAll u.expr +--------------------> new <------------------------- + T:= comp2(x,m1,e) => coerce(T,m) + nil +--------------------> new <------------------------- + nil + +compWithMappingMode(x,m,oldE) == + ["Mapping",m',:sl] := m + $killOptimizeIfTrue: local:= true + e:= oldE + x := markKillAll x + ------------------ + m := markKillAll m + ------------------ +--if x is ['PART,.,y] then x := y +--------------------------------- + isFunctor x => + if get(x,"modemap",$CategoryFrame) is [[[.,target,:argModeList],.],:.] and + (and/[extendsCategoryForm("$",s,mode) for mode in argModeList for s in sl] + ) and extendsCategoryForm("$",target,m') then return [x,m,e] + if STRINGP x then x:= INTERN x + for m in sl for v in (vl:= take(#sl,$FormalMapVariableList)) repeat + [.,.,e]:= compMakeDeclaration([":",v,m],$EmptyMode,e) + not null vl and not hasFormalMapVariable(x, vl) => return + [u,.,.] := comp([x,:vl],m',e) or return nil + extractCodeAndConstructTriple(u, m, oldE) + null vl and (t := comp([x], m', e)) => return + [u,.,.] := t + extractCodeAndConstructTriple(u, m, oldE) + [u,.,.]:= comp(x,m',e) or return nil + originalFun := u + if originalFun is ['WI,a,b] then u := b + uu := ['LAMBDA,vl,u] + --------------------------> 11/28 drop COMP-TRAN, optimizations + T := [uu,m,oldE] + originalFun is ['WI,a,b] => markLambda(vl,a,m,T) + markLambda(vl,originalFun,m,T) + +compAtom(x,m,e) == + T:= compAtomWithModemap(x,m,e,get(x,"modemap",e)) => markCompAtom(x,T) + x="nil" => + T:= + modeIsAggregateOf('List,m,e) is [.,R]=> compList(x,['List,R],e) + modeIsAggregateOf('Vector,m,e) is [.,R]=> compVector(x,['Vector,R],e) + T => convert(T,m) +--> + FIXP x and MEMQ(opOf m, '(Integer NonNegativeInteger PositiveInteger SmallInteger)) => markAt [x,m,e] +-- FIXP x and (T := [x, $Integer,e]) and (T' := convert(T,m)) => markAt(T, T') + t:= + isSymbol x => + compSymbol(x,m,e) or return nil + m = $Expression and primitiveType x => [x,m,e] + STRINGP x => + x ^= '"failed" and (member('(Symbol), $localImportStack) or + member('(Symbol), $globalImportStack)) => markAt [x, '(String), e] + [x, x, e] + [x,primitiveType x or return nil,e] + convert(t,m) + +extractCodeAndConstructTriple(u, m, oldE) == + u := markKillAll u + u is ["call",fn,:.] => + if fn is ["applyFun",a] then fn := a + [fn,m,oldE] + [op,:.,env] := u + [["CONS",["function",op],env],m,oldE] + +compSymbol(s,m,e) == + s="$NoValue" => ["$NoValue",$NoValueMode,e] + isFluid s => [s,getmode(s,e) or return nil,e] + s="true" => ['(QUOTE T),$Boolean,e] + s="false" => [false,$Boolean,e] + s=m or get(s,"isLiteral",e) => [["QUOTE",s],s,e] + v:= get(s,"value",e) => +--+ + MEMQ(s,$functorLocalParameters) => + NRTgetLocalIndex s + [s,v.mode,e] --s will be replaced by an ELT form in beforeCompile + [s,v.mode,e] --s has been SETQd + m':= getmode(s,e) => + if not member(s,$formalArgList) and not MEMQ(s,$FormalMapVariableList) and + not isFunction(s,e) and null ($compForModeIfTrue=true) then errorRef s + [s,m',e] --s is a declared argument + MEMQ(s,$FormalMapVariableList) => stackMessage ["no mode found for",s] +---> + m = $Symbol or m = $Expression => [['QUOTE,s],m,e] + ---> was ['QUOTE, s] + not isFunction(s,e) => errorRef s + +compForm(form,m,e) == + if form is [['PART,.,op],:r] then form := [op,:r] + ----------------------------------------------------- 94/10/16 + T:= + compForm1(form,m,e) or compArgumentsAndTryAgain(form,m,e) or return + stackMessageIfNone ["cannot compile","%b",form,"%d"] + T + +compForm1(form,m,e) == + [op,:argl] := form + $NumberOfArgsIfInteger: local:= #argl --see compElt + op="error" => + [[op,:[([.,.,e]:=outputComp(x,e)).expr + for x in argl]],m,e] + op is ['MI,a,b] => compForm1([markKillExpr b,:argl],m,e) + op is ["elt",domain,op'] => + domain := markKillAll domain + domain="Lisp" => + --op'='QUOTE and null rest argl => [first argl,m,e] + val := [op',:[([.,.,e]:= compOrCroak(x,$EmptyMode,e)).expr for x in argl]] + markLisp([val,m,e],m) +-------> new <------------- +-- foobar domain +-- markImport(domain,true) +-------> new <------------- + domain=$Expression and op'="construct" => compExpressionList(argl,m,e) + (op'="COLLECT") and coerceable(domain,m,e) => + (T:= comp([op',:argl],domain,e) or return nil; coerce(T,m)) +-------> new <------------- + domain= 'Rep and + (ans := compForm2([op',:argl],SUBST('Rep,'_$,m),e:= addDomain(domain,e), + [SUBST('Rep,'_$,x) for x in getFormModemaps([op',:argl],e) + | x is [[ =domain,:.],:.]])) => ans +-------> new <------------- + ans := compForm2([op',:argl],m,e:= addDomain(domain,e), + [x for x in getFormModemaps([op',:argl],e) | x is [[ =domain,:.],:.]]) => ans + (op'="construct") and coerceable(domain,m,e) => + (T:= comp([op',:argl],domain,e) or return nil; coerce(T,m)) + nil + + e:= addDomain(m,e) --???unneccessary because of comp2's call??? + (mmList:= getFormModemaps(form,e)) and (T:= compForm2(form,m,e,mmList)) => T + compToApply(op,argl,m,e) + +--% WI and MI + +compForm3(form is [op,:argl],m,e,modemapList) == +--order modemaps so that ones from Rep are moved to the front + modemapList := compFormOrderModemaps(modemapList,m = "$") + qe(22,e) + T:= + or/ + [compFormWithModemap(form,m,e,first (mml:= ml)) + for ml in tails modemapList] or return nil + qt(14,T) + result := + $compUniquelyIfTrue => + or/[compFormWithModemap(form,m,e,mm) for mm in rest mml] => + THROW("compUniquely",nil) + qt(15,T) + qt(16,T) + qt(17,markAny('compForm3,form,result)) + +compFormOrderModemaps(mml,targetIsDollar?) == +--order modemaps so that ones from Rep are moved to the front +--exceptions: if $ is the target and there are 2 modemaps with +-- identical signatures, move the $ one ahead + repMms := [mm for (mm:= [[dc,:.],:.]) in mml | dc = 'Rep] + if repMms and targetIsDollar? then + dollarMms := [mm for (mm := [[dc,:sig],:.]) in mml | dc = "$" + and or/[mm1 for (mm1:= [[dc1,:sig1],:.]) in repMms | sig1 = sig]] + repMms := [:dollarMms, :repMms] + null repMms => mml + [:repMms,:SETDIFFERENCE(mml,repMms)] + +compWI(["WI",a,b],m,E) == + u := comp(b,m,E) + pp (u => "====> ok"; 'NO) + u + +compMI(["MI",a,b],m,E) == + u := comp(b,m,E) + pp (u => "====> ok"; 'NO) + u + +compWhere([.,form,:exprList],m,eInit) == + $insideExpressionIfTrue: local:= false + $insideWhereIfTrue: local:= true +-- if not $insideFunctorIfTrue then +-- $originalTarget := +-- form is ['DEF,a,osig,:.] and osig is [otarget,:.] => +-- exprList is [['SEQ,:l,['exit,n,y]]] and (u := [:l,y]) and +-- (ntarget := or/[def for x in u | x is [op,a',:.,def] and ([op,a',otarget]) and +-- MEMQ(op,'(DEF MDEF)) and (a' = otarget or a' is [=otarget])]) => +-- [ntarget,:rest osig] +-- osig +-- nil +-- foobum exprList + e:= eInit + u:= + for item in exprList repeat + [.,.,e]:= comp(item,$EmptyMode,e) or return "failed" + u="failed" => return nil + $insideWhereIfTrue:= false + [x,m,eAfter]:= comp(macroExpand(form,eBefore:= e),m,e) or return nil + eFinal:= + del:= deltaContour(eAfter,eBefore) => addContour(del,eInit) + eInit + [x,m,eFinal] + +compMacro(form,m,e) == + $macroIfTrue: local:= true + ["MDEF",lhs,signature,specialCases,rhs]:= form := markKillAll form + firstForm := ["MDEF",first lhs,'(NIL),'(NIL),rhs] + markMacro(first lhs,rhs) + rhs := + rhs is ['CATEGORY,:.] => ['"-- the constructor category"] + rhs is ['Join,:.] => ['"-- the constructor category"] + rhs is ['CAPSULE,:.] => ['"-- the constructor capsule"] + rhs is ['add,:.] => ['"-- the constructor capsule"] + formatUnabbreviated rhs + sayBrightly ['" processing macro definition",'%b, + :formatUnabbreviated lhs,'" ==> ",:rhs,'%d] + ["MDEF",lhs,signature,specialCases,rhs]:= form:= macroExpand(form,e) + m=$EmptyMode or m=$NoValueMode => + ["/throwAway",$NoValueMode,put(first lhs,"macro",rhs,e)] + +--compMacro(form,m,e) == +-- $macroIfTrue: local:= true +-- ["MDEF",lhs,signature,specialCases,rhs]:= form +-- rhs := +-- rhs is ['CATEGORY,:.] => ['"-- the constructor category"] +-- rhs is ['Join,:.] => ['"-- the constructor category"] +-- rhs is ['CAPSULE,:.] => ['"-- the constructor capsule"] +-- rhs is ['add,:.] => ['"-- the constructor capsule"] +-- formatUnabbreviated rhs +-- sayBrightly ['" processing macro definition",'%b, +-- :formatUnabbreviated lhs,'" ==> ",:rhs,'%d] +-- ["MDEF",lhs,signature,specialCases,rhs]:= form:= macroExpand(form,e) +-- m=$EmptyMode or m=$NoValueMode => +-- rhs := markMacro(lhs,rhs) +-- ["/throwAway",$NoValueMode,put(first lhs,"macro",rhs,e)] + +compSetq(oform,m,E) == + ["LET",form,val] := oform + T := compSetq1(form,val,m,E) => markSetq(oform,T) + nil + +compSetq1(oform,val,m,E) == + form := markKillAll oform + IDENTP form => setqSingle(form,val,m,E) + form is [":",x,y] => + [.,.,E']:= compMakeDeclaration(form,$EmptyMode,E) + compSetq(["LET",x,val],m,E') + form is [op,:l] => + op="CONS" => setqMultiple(uncons form,val,m,E) + op="Tuple" => setqMultiple(l,val,m,E) + setqSetelt(oform,form,val,m,E) + +setqSetelt(oform,[v,:s],val,m,E) == + T:= comp0(["setelt",:oform,val],m,E) or return nil +---> ------- + markComp(oform,T) + +setqSingle(id,val,m,E) == + $insideSetqSingleIfTrue: local:= true + --used for comping domain forms within functions + currentProplist:= getProplist(id,E) + m'':= get(id,'mode,E) or getmode(id,E) or + (if m=$NoValueMode then $EmptyMode else m) +-----------------------> new <------------------------- + trialT := m'' = "$" and get("Rep",'value,E) and comp(val,'Rep,E) +-----------------------> new <------------------------- + T:= + (trialT and coerce(trialT,m'')) or eval or return nil where + eval() == + T:= comp(val,m'',E) => T + not get(id,"mode",E) and m'' ^= (maxm'':=maxSuperType(m'',E)) and + (T:=comp(val,maxm'',E)) => T + (T:= comp(val,$EmptyMode,E)) and getmode(T.mode,E) => + assignError(val,T.mode,id,m'') + T':= [x,m',e']:= convert(T,m) or return nil + if $profileCompiler = true then + null IDENTP id => nil + key := + MEMQ(id,rest $form) => 'arguments + 'locals + profileRecord(key,id,T.mode) + newProplist:= consProplistOf(id,currentProplist,"value",markKillAll removeEnv T) + e':= (PAIRP id => e'; addBinding(id,newProplist,e')) + x1 := markKillAll x + if isDomainForm(x1,e') then + if isDomainInScope(id,e') then + stackWarning ["domain valued variable","%b",id,"%d", + "has been reassigned within its scope"] + e':= augModemapsFromDomain1(id,x1,e') + --all we do now is to allocate a slot number for lhs + --e.g. the LET form below will be changed by putInLocalDomainReferences +--+ + if (k:=NRTassocIndex(id)) + then + $markFreeStack := [id,:$markFreeStack] + form:=['SETELT,"$",k,x] + else form:= + $QuickLet => ["LET",id,x] + ["LET",id,x, + (isDomainForm(x,e') => ['ELT,id,0];CAR outputComp(id,e'))] + [form,m',e'] + +setqMultiple(nameList,val,m,e) == + val is ["CONS",:.] and m=$NoValueMode => + setqMultipleExplicit(nameList,uncons val,m,e) + val is ["Tuple",:l] and m=$NoValueMode => setqMultipleExplicit(nameList,l,m,e) + --1. create a gensym, %add to local environment, compile and assign rhs + g:= genVariable() + e:= addBinding(g,nil,e) + T:= [.,m1,.]:= compSetq1(g,val,$EmptyMode,e) or return nil + e:= put(g,"mode",m1,e) + [x,m',e]:= convert(T,m) or return nil + --1.1 exit if result is a list + m1 is ["List",D] => + for y in nameList repeat e:= put(y,"value",[genSomeVariable(),D,$noEnv],e) + convert([["PROGN",x,["LET",nameList,g],g],m',e],m) + --2. verify that the #nameList = number of parts of right-hand-side + selectorModePairs:= + --list of modes + decompose(m1,#nameList,e) or return nil where + decompose(t,length,e) == + t is ["Record",:l] => [[name,:mode] for [":",name,mode] in l] + comp(t,$EmptyMode,e) is [.,["RecordCategory",:l],.] => + [[name,:mode] for [":",name,mode] in l] + stackMessage ["no multiple assigns to mode: ",t] + #nameList^=#selectorModePairs => + stackMessage [val," must decompose into ",#nameList," components"] + -- 3.generate code; return + assignList:= + [([.,.,e]:= compSetq1(x,["elt",g,y],z,e) or return "failed").expr + for x in nameList for [y,:z] in selectorModePairs] + if assignList="failed" then NIL + else [MKPROGN [x,:assignList,g],m',e] + +setqMultipleExplicit(nameList,valList,m,e) == + #nameList^=#valList => + stackMessage ["Multiple assignment error; # of items in: ",nameList, + "must = # in: ",valList] + gensymList:= [genVariable() for name in nameList] + for g in gensymList for name in nameList repeat + e := put(g,"mode",get(name,"mode",e),e) + assignList:= + --should be fixed to declare genVar when possible + [[.,.,e]:= compSetq1(g,val,$EmptyMode,e) or return "failed" + for g in gensymList for val in valList for name in nameList] + assignList="failed" => nil + reAssignList:= + [[.,.,e]:= compSetq1(name,g,$EmptyMode,e) or return "failed" + for g in gensymList for name in nameList] + reAssignList="failed" => nil + T := [["PROGN",:[T.expr for T in assignList], + :[T.expr for T in reAssignList]], $NoValueMode, (LAST reAssignList).env] + markMultipleExplicit(nameList,valList,T) + +canReturn(expr,level,exitCount,ValueFlag) == --SPAD: exit and friends + atom expr => ValueFlag and level=exitCount + (op:= first expr)="QUOTE" => ValueFlag and level=exitCount + MEMQ(op,'(WI MI)) => canReturn(CADDR expr,level,count,ValueFlag) + op="TAGGEDexit" => + expr is [.,count,data] => canReturn(data.expr,level,count,count=level) + level=exitCount and not ValueFlag => nil + op="SEQ" => or/[canReturn(u,level+1,exitCount,false) for u in rest expr] + op="TAGGEDreturn" => nil + op="CATCH" => + [.,gs,data]:= expr + (findThrow(gs,data,level,exitCount,ValueFlag) => true) where + findThrow(gs,expr,level,exitCount,ValueFlag) == + atom expr => nil + expr is ["THROW", =gs,data] => true + --this is pessimistic, but I know of no more accurate idea + expr is ["SEQ",:l] => + or/[findThrow(gs,u,level+1,exitCount,ValueFlag) for u in l] + or/[findThrow(gs,u,level,exitCount,ValueFlag) for u in rest expr] + canReturn(data,level,exitCount,ValueFlag) + op = "COND" => + level = exitCount => + or/[canReturn(last u,level,exitCount,ValueFlag) for u in rest expr] + or/[or/[canReturn(u,level,exitCount,ValueFlag) for u in v] + for v in rest expr] + op="IF" => + expr is [.,a,b,c] + if not canReturn(a,0,0,true) and not (BOUNDP '$convert2NewCompiler and $convert2NewCompiler) then + SAY "IF statement can not cause consequents to be executed" + pp expr + canReturn(a,level,exitCount,nil) or canReturn(b,level,exitCount,ValueFlag) + or canReturn(c,level,exitCount,ValueFlag) + --now we have an ordinary form + atom op => and/[canReturn(u,level,exitCount,ValueFlag) for u in expr] + op is ["XLAM",args,bods] => + and/[canReturn(u,level,exitCount,ValueFlag) for u in expr] + systemErrorHere '"canReturn" --for the time being + +compList(l,m is ["List",mUnder],e) == + markImport m + markImport mUnder + null l => [NIL,m,e] + Tl:= [[.,mUnder,e]:= + comp(x,mUnder,e) or return "failed" for i in 1.. for x in l] + Tl="failed" => nil + T:= [["LIST",:[T.expr for T in Tl]],["List",mUnder],e] + +compVector(l,m is ["Vector",mUnder],e) == + markImport m + markImport mUnder + null l => [$EmptyVector,m,e] + Tl:= [[.,mUnder,e]:= comp(x,mUnder,e) or return "failed" for x in l] + Tl="failed" => nil + [["VECTOR",:[T.expr for T in Tl]],m,e] + +compColon([":",f,t],m,e) == + $insideExpressionIfTrue=true => compPretend(["pretend",f,t],m,e) + --if inside an expression, ":" means to convert to m "on faith" + f := markKillAll f + $lhsOfColon: local:= f + t:= + t := markKillAll t + atom t and (t':= ASSOC(t,getDomainsInScope e)) => t' + isDomainForm(t,e) and not $insideCategoryIfTrue => + (if not member(t,getDomainsInScope e) then e:= addDomain(t,e); t) + isDomainForm(t,e) or isCategoryForm(t,e) => t + t is ["Mapping",m',:r] => t + unknownTypeError t + t + if $insideCapsuleFunctionIfTrue then markDeclaredImport t + f is ["LISTOF",:l] => + (for x in l repeat T:= [.,.,e]:= compColon([":",x,t],m,e); T) + e:= + f is [op,:argl] and not (t is ["Mapping",:.]) => + --for MPOLY--replace parameters by formal arguments: RDJ 3/83 + newTarget:= EQSUBSTLIST(take(#argl,$FormalMapVariableList), + [(x is [":",a,m] => a; x) for x in argl],t) + signature:= + ["Mapping",newTarget,: + [(x is [":",a,m] => m; + getmode(x,e) or systemErrorHere '"compColonOld") for x in argl]] + put(op,"mode",signature,e) + put(f,"mode",t,e) + if not $bootStrapMode and $insideFunctorIfTrue and + makeCategoryForm(t,e) is [catform,e] then + e:= put(f,"value",[genSomeVariable(),t,$noEnv],e) + ["/throwAway",getmode(f,e),e] + +compConstruct(form,m,e) == (T := compConstruct1(form,m,e)) and markConstruct(form,T) + +compConstruct1(form is ["construct",:l],m,e) == + y:= modeIsAggregateOf("List",m,e) => + T:= compList(l,["List",CADR y],e) => convert(T,m) + y:= modeIsAggregateOf("Vector",m,e) => + T:= compVector(l,["Vector",CADR y],e) => convert(T,m) + T:= compForm(form,m,e) => T + for D in getDomainsInScope e repeat + (y:=modeIsAggregateOf("List",D,e)) and + (T:= compList(l,["List",CADR y],e)) and (T':= convert(T,m)) => + return T' + (y:=modeIsAggregateOf("Vector",D,e)) and + (T:= compVector(l,["Vector",CADR y],e)) and (T':= convert(T,m)) => + return T' + +compPretend(u := ["pretend",x,t],m,e) == + t := markKillAll t + m := markKillAll m + e:= addDomain(t,e) + T:= comp(x,t,e) or comp(x,$EmptyMode,e) or return nil + if T.mode=t then warningMessage:= ["pretend",t," -- should replace by @"] + T1:= [T.expr,t,T.env] + t = "$" and m = "Rep" => markPretend(T1,T1) -->! WATCH OUT: correct? !<-- + T':= coerce(T1,m) => + warningMessage => + stackWarning warningMessage + markCompColonInside("@",T') + markPretend(T1,T') + nil + +compAtSign(["@",x,m'],m,e) == + m' := markKillAll m' + m := markKillAll m + e:= addDomain(m',e) + T:= comp(x,m',e) or return nil + coerce(T,m) + +compColonInside(x,m,e,m') == + m' := markKillAll m' + e:= addDomain(m',e) + T:= comp(x,$EmptyMode,e) or return nil + if T.mode=m' then warningMessage:= [":",m'," -- should replace by ::"] + T:= [T.expr,m',T.env] + m := markKillAll m + T':= coerce(T,m) => + warningMessage => + stackWarning warningMessage + markCompColonInside("@",T') + stackWarning [":",m'," -- should replace by pretend"] + markCompColonInside("pretend",T') + nil + +resolve(min, mout) == + din := markKillAll min + dout := markKillAll mout + din=$NoValueMode or dout=$NoValueMode => $NoValueMode + dout=$EmptyMode => din + STRINGP din and dout = '(Symbol) => dout ------> hack 8/14/94 + STRINGP dout and din = '(Symbol) => din ------> hack 8/14/94 + din^=dout and (STRINGP din or STRINGP dout) => + modeEqual(dout,$String) => dout + modeEqual(din,$String) => nil + mkUnion(din,dout) + dout + +coerce(T,m) == + T := [T.expr,markKillAll T.mode,T.env] + m := markKillAll m + if not get(m, 'isLiteral,T.env) then markImport m + $InteractiveMode => + keyedSystemError("S2GE0016",['"coerce", + '"function coerce called from the interpreter."]) +--==================> changes <====================== +--The following line is inappropriate for our needs::: +--rplac(CADR T,substitute("$",$Rep,CADR T)) + T' := coerce0(T,m) => T' + T := [T.expr,fullSubstitute("$",$Representation,T.mode),T.env] +--==================> changes <====================== + coerce0(T,m) + +coerce0(T,m) == + T':= coerceEasy(T,m) => T' + T':= coerceSubset(T,m) => markCoerce(T,T','AUTOSUBSET) + T':= coerceHard(T,m) => markCoerce(T,T','AUTOHARD) + T':= coerceExtraHard(T,m) => T' + T.expr = "$fromCoerceable$" or isSomeDomainVariable m => nil + T' := coerceRep(T,m) => markCoerce(T,T','AUTOREP) + stackMessage fn(T.expr,T.mode,m) where + -- if from from coerceable, this coerce was just a trial coercion + -- from compFormWithModemap to filter through the modemaps + fn(x,m1,m2) == + ["Cannot coerce","%b",x,"%d","%l"," of mode","%b",m1,"%d","%l", + " to mode","%b",m2,"%d"] + +coerceSubset(T := [x,m,e],m') == + m = $SmallInteger => + m' = $Integer => [x,m',e] + m' = (r := get(x,'range,e)) or isSubset(r,m',e) => [x,r,e] + nil +-- pp [m, m'] + isSubset(m,m',e) or m="Rep" and m'="$" => [x,m',e] + m is ['SubDomain,=m',:.] => [x,m',e] + (pred:= LASSOC(opOf m',get(opOf m,'SubDomain,e))) and INTEGERP x and + -- obviously this is temporary + eval substitute(x,"#1",pred) => [x,m',e] + (pred:= isSubset(m',maxSuperType(m,e),e)) and INTEGERP x -- again temporary + and eval substitute(x,"*",pred) => + [x,m',e] + nil + +coerceRep(T,m) == + md := T.mode + atom md => nil + CONTAINED('Rep,md) and SUBST('$,'Rep,md) = m or + CONTAINED('Rep,m) and SUBST('$,'Rep,m) = md => T + nil + +--- GET rid of XLAMs +spadCompileOrSetq form == + --bizarre hack to take account of the existence of "known" functions + --good for performance (LISPLLIB size, BPI size, NILSEC) + [nam,[lam,vl,body]] := form + CONTAINED(" ",body) => sayBrightly ['" ",:bright nam,'" not compiled"] + if vl is [:vl',E] and body is [nam',: =vl'] then + LAM_,EVALANDFILEACTQ ['PUT,MKQ nam,MKQ 'SPADreplace,MKQ nam'] + sayBrightly ['" ",:bright nam,'"is replaced by",:bright nam'] + else if (ATOM body or and/[ATOM x for x in body]) + and vl is [:vl',E] and not CONTAINED(E,body) then + macform := ['XLAM,vl',body] + LAM_,EVALANDFILEACTQ ['PUT,MKQ nam,MKQ 'SPADreplace,MKQ macform] + sayBrightly ['" ",:bright nam,'"is replaced by",:bright body] + $insideCapsuleFunctionIfTrue => first COMP LIST form + compileConstructor form + +coerceHard(T,m) == + $e: local:= T.env + m':= T.mode + STRINGP m' and modeEqual(m,$String) => [T.expr,m,$e] + modeEqual(m',m) or + (get(m',"value",$e) is [m'',:.] or getmode(m',$e) is ["Mapping",m'']) and + modeEqual(m'',m) or + (get(m,"value",$e) is [m'',:.] or getmode(m,$e) is ["Mapping",m'']) and + modeEqual(m'',m') => [T.expr,m,T.env] + STRINGP T.expr and T.expr=m => [T.expr,m,$e] + isCategoryForm(m,$e) => + $bootStrapMode = true => [T.expr,m,$e] + extendsCategoryForm(T.expr,T.mode,m) => [T.expr,m,$e] + nil + nil + +coerceExtraHard(T is [x,m',e],m) == + T':= autoCoerceByModemap(T,m) => T' + isUnionMode(m',e) is ["Union",:l] and (t:= hasType(x,e)) and + member(t,l) and (T':= autoCoerceByModemap(T,t)) and + (T'':= coerce(T',m)) => T'' + m' is ['Record,:.] and m = $Expression => + [['coerceRe2E,x,['ELT,COPY m',0]],m,e] + nil + +compCoerce(u := ["::",x,m'],m,e) == + m' := markKillAll m' + e:= addDomain(m',e) + m := markKillAll m +--------------> new code <------------------- + T:= compCoerce1(x,m',e) => coerce(T,m) + T := comp(x,$EmptyMode,e) or return nil + T.mode = $SmallInteger and + MEMQ(opOf m,'(NonNegativeInteger PositiveInteger)) => + compCoerce(["::",["::",x,$Integer],m'],m,e) +--------------> new code <------------------- + getmode(m',e) is ["Mapping",["UnionCategory",:l]] => + l := [markKillAll x for x in l] + T:= (or/[compCoerce1(x,m1,e) for m1 in l]) or return nil + coerce([T.expr,m',T.env],m) + +compCoerce1(x,m',e) == + T:= comp(x,m',e) + if null T then T := comp(x,$EmptyMode,e) + null T => return nil + m1:= + STRINGP T.mode => $String + T.mode + m':=resolve(m1,m') + T:=[T.expr,m1,T.env] + T':= coerce(T,m') => T' + T':= coerceByModemap(T,m') => T' + pred:=isSubset(m',T.mode,e) => + gg:=GENSYM() + pred:= substitute(gg,"*",pred) + code:= ['PROG1,['LET,gg,T.expr], ['check_-subtype,pred,MKQ m',gg]] + [code,m',T.env] + +coerceByModemap([x,m,e],m') == +--+ modified 6/27 for new runtime system + u:= + [modemap + for (modemap:= [map,cexpr]) in getModemapList("coerce",1,e) | map is [.,t, + s] and (modeEqual(t,m') or isSubset(t,m',e)) + and (modeEqual(s,m) or isSubset(m,s,e))] or return nil + mm:=first u -- patch for non-trival conditons + fn := genDeltaEntry ['coerce,:mm] + T := [["call",fn,x],m',e] + markCoerceByModemap(x,m,m',markCallCoerce(x,m',T),nil) + +autoCoerceByModemap([x,source,e],target) == + u:= + [cexpr + for (modemap:= [map,cexpr]) in getModemapList("autoCoerce",1,e) | map is [ + .,t,s] and modeEqual(t,target) and modeEqual(s,source)] or return nil + fn:= (or/[selfn for [cond,selfn] in u | cond=true]) or return nil + markCoerceByModemap(x,source,target,[["call",fn,x],target,e],true) + +--====================================================================== +-- From compiler.boot +--====================================================================== +--comp3x(x,m,$e) == + +comp3(x,m,$e) == + --returns a Triple or %else nil to signalcan't do' + $e:= addDomain(m,$e) + e:= $e --for debugging purposes + m is ["Mapping",:.] => compWithMappingMode(x,m,e) + m is ["QUOTE",a] => (x=a => [x,m,$e]; nil) + STRINGP m => (atom x => (m=x or m=STRINGIMAGE x => [m,m,e]; nil); nil) + ^x or atom x => compAtom(x,m,e) + op:= first x + getmode(op,e) is ["Mapping",:ml] and (u:= applyMapping(x,m,e,ml)) => u + op is ["KAPPA",sig,varlist,body] => compApply(sig,varlist,body,rest x,m,e) + op=":" => compColon(x,m,e) + op="::" => compCoerce(x,m,e) + not ($insideCompTypeOf=true) and stringPrefix?('"TypeOf",PNAME op) => + compTypeOf(x,m,e) + ------------special jump out code for PART (don't want $insideExpressionIfTrue=true)-- + x is ['PART,:.] => compPART(x,m,e) + ---------------------------------- + t:= qt(14,compExpression(x,m,e)) + t is [x',m',e'] and not member(m',getDomainsInScope e') => + qt(15,[x',m',addDomain(m',e')]) + qt(16,t) + +yyyyy x == x +compExpression(x,m,e) == + $insideExpressionIfTrue: local:= true + if x is ['LET,['PART,.,w],[['elt,B,'new],['PART,.,["#",['PART,.,l]]],:.],:.] then yyyyy x + x := compRenameOp x + atom first x and (fn:= GETL(first x,"SPECIAL")) => + FUNCALL(fn,x,m,e) + compForm(x,m,e) + +compRenameOp x == ----------> new 12/3/94 + x is [op,:r] and op is ['PART,.,op1] => + [op1,:r] + x + +compCase(["case",x,m1],m,e) == + m' := markKillAll m1 + e:= addDomain(m',e) + T:= compCase1(x,m',e) => coerce(T,m) + nil + +compCase1(x,m,e) == + x1 := + x is ['PART,.,a] => a + x + [x',m',e']:= comp(x1,$EmptyMode,e) or return nil + if m' = "$" then (m' := IFCAR get('Rep,'value,e)) and (switchMode := true) + -------------------------------------------------------------------------- + m' isnt ['Union,:r] => nil + mml := [mm for (mm := [map,cexpr]) in getModemapList("case",2,e') + | map is [.,.,s,t] and modeEqual(t,m) and + (modeEqual(s,m') or switchMode and modeEqual(s,"$"))] + or return nil + u := [cexpr for [.,cexpr] in mml] + fn:= (or/[selfn for [cond,selfn] in u | cond=true]) or return nil + tag := genCaseTag(m, r, 1) or return nil + x1 := + switchMode => markRepper('rep, x) + x + markCase(x, tag, markCaseWas(x1,[["call",fn,x'],$Boolean,e'])) + +genCaseTag(t,l,n) == + l is [x, :l] => + x = t => + STRINGP x => INTERN x + INTERN STRCONC("value", STRINGIMAGE n) + x is ["::",=t,:.] => t + STRINGP x => genCaseTag(t, l, n) + genCaseTag(t, l, n + 1) + nil + +compIf(["IF",aOrig,b,c],m,E) == + a := markKillButIfs aOrig + [xa,ma,Ea,Einv]:= compBoolean(a,aOrig,$Boolean,E) or return nil + [xb,mb,Eb]:= Tb:= compFromIf(b,m,Ea) or return nil + [xc,mc,Ec]:= Tc:= compFromIf(c,resolve(mb,m),Einv) or return nil + xb':= coerce(Tb,mc) or return nil + x:= ["IF",xa,quotify xb'.expr,quotify xc] + (returnEnv:= Env(xb'.env,Ec,xb'.expr,xc,E)) where + Env(bEnv,cEnv,b,c,E) == + canReturn(b,0,0,true) => + (canReturn(c,0,0,true) => intersectionEnvironment(bEnv,cEnv); bEnv) + canReturn(c,0,0,true) => cEnv + E + [x,mc,returnEnv] + +compBoolean(p,pWas,m,Einit) == + op := opOf p + [p',m,E]:= + fop := LASSOC(op,'((and . compAnd) (or . compOr) (not . compNot))) => + APPLY(fop,[p,pWas,m,Einit]) or return nil + T := comp(p,m,Einit) or return nil + markAny('compBoolean,pWas,T) + [p',m,getSuccessEnvironment(markKillAll p,E), + getInverseEnvironment(markKillAll p,E)] + +compAnd([op,:args], pWas, m, e) == +--called ONLY from compBoolean + cargs := [T.expr for x in args + | [.,.,e,.] := T := compBoolean(x,x,$Boolean,e) or return nil] + null cargs => nil + coerce(markAny('compAnd,pWas,[["AND",:cargs],$Boolean,e]),m) + +compOr([op,:args], pWas, m, e) == +--called ONLY from compBoolean + cargs := [T.expr for x in args + | [.,.,.,e] := T := compBoolean(x,x,$Boolean,e) or return nil] + null cargs => nil + coerce(markAny('compOr,pWas, [["OR",:cargs],$Boolean,e]),m) + +compNot([op,arg], pWas, m, e) == +--called ONLY from compBoolean + [x,m1,.,ei] := compBoolean(arg,arg,$Boolean,e) or return nil + coerce(markAny('compNot, pWas, [["NOT",x],$Boolean,ei]),m) + +compDefine(form,m,e) == + $tripleHits: local:= 0 + $macroIfTrue: local + $packagesUsed: local + ['DEF,.,originalSignature,.,body] := form + if not $insideFunctorIfTrue then + $originalBody := COPY body + compDefine1(form,m,e) + +compDefine1(form,m,e) == + $insideExpressionIfTrue: local:= false + --1. decompose after macro-expanding form + ['DEF,lhs,signature,specialCases,rhs]:= form:= macroExpand(form,e) + $insideWhereIfTrue and isMacro(form,e) and (m=$EmptyMode or m=$NoValueMode) + => [lhs,m,put(first lhs,'macro,rhs,e)] + null signature.target and not MEMQ(KAR rhs,$ConstructorNames) and + (sig:= getSignatureFromMode(lhs,e)) => + -- here signature of lhs is determined by a previous declaration + compDefine1(['DEF,lhs,[first sig,:rest signature],specialCases,rhs],m,e) + if signature.target=$Category then $insideCategoryIfTrue:= true + if signature.target is ['Mapping,:map] then + signature:= map + form:= ['DEF,lhs,signature,specialCases,rhs] + + +-- RDJ (11/83): when argument and return types are all declared, +-- or arguments have types declared in the environment, +-- and there is no existing modemap for this signature, add +-- the modemap by a declaration, then strip off declarations and recurse + e := compDefineAddSignature(lhs,signature,e) +-- 2. if signature list for arguments is not empty, replace ('DEF,..) by +-- ('where,('DEF,..),..) with an empty signature list; +-- otherwise, fill in all NILs in the signature + not (and/[null x for x in rest signature]) => compDefWhereClause(form,m,e) + signature.target=$Category => + compDefineCategory(form,m,e,nil,$formalArgList) + isDomainForm(rhs,e) and not $insideFunctorIfTrue => + if null signature.target then signature:= + [getTargetFromRhs(lhs,rhs,giveFormalParametersValues(rest lhs,e)),: + rest signature] + rhs:= addEmptyCapsuleIfNecessary(signature.target,rhs) + compDefineFunctor(['DEF,lhs,signature,specialCases,rhs],m,e,nil, + $formalArgList) + null $form => stackAndThrow ['"bad == form ",form] + newPrefix:= + $prefix => INTERN STRCONC(encodeItem $prefix,'",",encodeItem $op) + getAbbreviation($op,#rest $form) + compDefineCapsuleFunction(form,m,e,newPrefix,$formalArgList) + +compDefineCategory(df,m,e,prefix,fal) == + $domainShell: local -- holds the category of the object being compiled + $lisplibCategory: local + not $insideFunctorIfTrue and $LISPLIB => + compDefineLisplib(df,m,e,prefix,fal,'compDefineCategory1) + compDefineCategory1(df,m,e,prefix,fal) + +compDefineCategory1(df,m,e,prefix,fal) == + $DEFdepth : local := 0 --for conversion to new compiler 3/93 + $capsuleStack : local := nil --for conversion to new compiler 3/93 + $predicateStack:local := nil --for conversion to new compiler 3/93 + $signatureStack:local := nil --for conversion to new compiler 3/93 + $importStack : local := nil --for conversion to new compiler 3/93 + $globalImportStack : local := nil --for conversion to new compiler 3/93 + $catAddForm : local := nil --for conversion to new compiler 2/95 + $globalDeclareStack : local := nil + $globalImportDefAlist: local:= nil + $localMacroStack : local := nil --for conversion to new compiler 3/93 + $freeStack : local := nil --for conversion to new compiler 3/93 + $domainLevelVariableList: local := nil--for conversion to new compiler 3/93 + $categoryTranForm : local := nil --for conversion to new compiler 10/93 + ['DEF,form,sig,sc,body] := df + body := markKillAll body --these parts will be replaced by compDefineLisplib + categoryCapsule := +--+ + body is ['add,cat,capsule] => + body := cat + capsule + nil + [d,m,e]:= compDefineCategory2(form,sig,sc,body,m,e,prefix,fal) +--+ next two lines +-- if BOUNDP '$convertingSpadFile and $convertingSpadFile then nil +-- else + if categoryCapsule and not $bootStrapMode then + [.,.,e] := + $insideCategoryPackageIfTrue: local := true --see NRTmakeSlot1 + $categoryPredicateList: local := + makeCategoryPredicates(form,$lisplibCategory) + defform := mkCategoryPackage(form,cat,categoryCapsule) + ['DEF,[.,arg,:.],:.] := defform + $categoryNameForDollar :local := arg + compDefine1(defform,$EmptyMode,e) + else + [body,T] := $categoryTranForm + markFinish(body,T) + + [d,m,e] + +compDefineCategory2(form,signature,specialCases,body,m,e, + $prefix,$formalArgList) == + --1. bind global variables + $insideCategoryIfTrue: local:= true + $TOP__LEVEL: local + $definition: local + --used by DomainSubstitutionFunction + $form: local + $op: local + $extraParms: local + --Set in DomainSubstitutionFunction, used further down +-- 1.1 augment e to add declaration $:
+ [$op,:argl]:= $definition:= form + e:= addBinding("$",[['mode,:$definition]],e) + +-- 2. obtain signature + signature':= + [first signature,:[getArgumentModeOrMoan(a,$definition,e) for a in argl]] + e:= giveFormalParametersValues(argl,e) + +-- 3. replace arguments by $1,..., substitute into body, +-- and introduce declarations into environment + sargl:= TAKE(# argl, $TriangleVariableList) + $functorForm:= $form:= [$op,:sargl] + $formalArgList:= [:sargl,:$formalArgList] + aList:= [[a,:sa] for a in argl for sa in sargl] + formalBody:= SUBLIS(aList,body) + signature' := SUBLIS(aList,signature') +--Begin lines for category default definitions + $functionStats: local:= [0,0] + $functorStats: local:= [0,0] + $frontier: local := 0 + $getDomainCode: local := nil + $addForm: local:= nil + for x in sargl for t in rest signature' repeat + [.,.,e]:= compMakeDeclaration([":",x,t],m,e) + +-- 4. compile body in environment of %type declarations for arguments + op':= $op + -- following line causes cats with no with or Join to be fresh copies + if opOf(formalBody)^='Join and opOf(formalBody)^='mkCategory then + formalBody := ['Join, formalBody] + T := compOrCroak(formalBody,signature'.target,e) +--------------------> new <------------------- + $catAddForm := + $originalBody is ['add,y,:.] => y + $originalBody + $categoryTranForm := [$originalBody,[$form,['Mapping,:signature'],T.env]] +--------------------> new <------------------- + body:= optFunctorBody markKillAll T.expr + if $extraParms then + formals:=actuals:=nil + for u in $extraParms repeat + formals:=[CAR u,:formals] + actuals:=[MKQ CDR u,:actuals] + body := ['sublisV,['PAIR,['QUOTE,formals],['LIST,:actuals]],body] + if argl then body:= -- always subst for args after extraparms + ['sublisV,['PAIR,['QUOTE,sargl],['LIST,: + [['devaluate,u] for u in sargl]]],body] + body:= + ['PROG1,['LET,g:= GENSYM(),body],['SETELT,g,0,mkConstructor $functorForm]] + fun:= compile [op',['LAM,sargl,body]] + +-- 5. give operator a 'modemap property + pairlis:= [[a,:v] for a in argl for v in $FormalMapVariableList] + parSignature:= SUBLIS(pairlis,signature') + parForm:= SUBLIS(pairlis,form) +---- lisplibWrite('"compilerInfo", +---- ['SETQ,'$CategoryFrame, +---- ['put,['QUOTE,op'],' +---- (QUOTE isCategory),true,['addModemap,MKQ op',MKQ parForm, +---- MKQ parSignature,true,MKQ fun,'$CategoryFrame]]],$libFile) + --Equivalent to the following two lines, we hope + if null sargl then + evalAndRwriteLispForm('NILADIC, + ['MAKEPROP,['QUOTE,op'],'(QUOTE NILADIC),true]) + +-- 6. put modemaps into InteractiveModemapFrame + $domainShell := + BOUNDP '$convertingSpadFile and $convertingSpadFile => nil + eval [op',:MAPCAR('MKQ,sargl)] + $lisplibCategory:= formalBody +---- if $LISPLIB then +---- $lisplibForm:= form +---- $lisplibKind:= 'category +---- modemap:= [[parForm,:parSignature],[true,op']] +---- $lisplibModemap:= modemap +---- $lisplibCategory:= formalBody +---- form':=[op',:sargl] +---- augLisplibModemapsFromCategory(form',formalBody,signature') + [fun,'(Category),e] -- cgit v1.2.3