aboutsummaryrefslogtreecommitdiff
path: root/src/interp/define.boot
diff options
context:
space:
mode:
Diffstat (limited to 'src/interp/define.boot')
-rw-r--r--src/interp/define.boot39
1 files changed, 30 insertions, 9 deletions
diff --git a/src/interp/define.boot b/src/interp/define.boot
index 43405cc3..8430610e 100644
--- a/src/interp/define.boot
+++ b/src/interp/define.boot
@@ -231,7 +231,8 @@ compDefineCategory2(form,signature,specialCases,body,m,e,
-- 2. obtain signature
signature':=
- [first signature,:[getArgumentModeOrMoan(a,$definition,e) for a in argl]]
+ [first signature,
+ :[getArgumentModeOrMoan(a,$definition,e) for a in argl]]
e:= giveFormalParametersValues(argl,e)
-- 3. replace arguments by $1,..., substitute into body,
@@ -832,17 +833,26 @@ getSignatureFromMode(form,e) ==
getmode(opOf form,e) is ['Mapping,:signature] =>
#form^=#signature => stackAndThrow ["Wrong number of arguments: ",form]
EQSUBSTLIST(rest form,take(#rest form,$FormalMapVariableList),signature)
-
+
+candidateSignatures(op,nmodes,slot1) ==
+ [sig for [[=op,sig,:.],:.] in slot1 | #sig = nmodes]
+
+++ We are compiling a capsule function definition with head given by `form'.
+++ Determine whether the function with possibly partial signature `opsig'
+++ is exported. Return the complete signature if yes; otherwise
+++ return nil, with diagnostic in ambiguity case.
hasSigInTargetCategory(argl,form,opsig,e) ==
- mList:= [getArgumentMode(x,e) for x in argl]
+ sigs := candidateSignatures($op,#form,$domainShell.1)
+ cc := checkCallingConvention(sigs,#argl)
+ mList:= [(cc.i > 0 => quasiquote x; getArgumentMode(x,e))
+ for x in argl for i in 0..]
--each element is a declared mode for the variable or nil if none exists
potentialSigList:=
REMDUP
- [sig
- for [[opName,sig,:.],:.] in $domainShell.(1) |
- fn(opName,sig,opsig,mList,form)] where
- fn(opName,sig,opsig,mList,form) ==
- opName=$op and #sig=#form and (null opsig or opsig=first sig) and
+ [sig for sig in sigs |
+ fn(sig,opsig,mList)] where
+ fn(sig,opsig,mList) ==
+ (null opsig or opsig=first sig) and
(and/[compareMode2Arg(x,m) for x in mList for m in rest sig])
c:= #potentialSigList
1=c => first potentialSigList
@@ -866,10 +876,10 @@ getArgumentMode(x,e) ==
m:= get(x,'mode,e) => m
checkAndDeclare(argl,form,sig,e) ==
-
-- arguments with declared types must agree with those in sig;
-- those that don't get declarations put into e
for a in argl for m in rest sig repeat
+ isQuasiquote m => nil -- we just built m from a.
m1:= getArgumentMode(a,e) =>
^modeEqual(m1,m) =>
stack:= [" ",:bright a,'"must have type ",m,
@@ -1063,6 +1073,17 @@ spadCompileOrSetq (form is [nam,[lam,vl,body]]) ==
--bizarre hack to take account of the existence of "known" functions
--good for performance (LISPLLIB size, BPI size, NILSEC)
CONTAINED(" ",body) => sayBrightly ['" ",:bright nam,'" not compiled"]
+
+ -- flag parameters needs to be made atomic, otherwise Lisp is confused.
+ -- We try our best to preserve
+ -- Note that we don't need substitution in the body because flag
+ -- parameters are never used in the body.
+ vl := [ renameParameter for v in vl] where
+ renameParameter() ==
+ NUMBERP v or IDENTP v or STRINGP v => v
+ GENSYM '"flag"
+ form := [nam,[lam,vl,body]]
+
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']