diff options
Diffstat (limited to 'src/interp/compiler.boot')
-rw-r--r-- | src/interp/compiler.boot | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/src/interp/compiler.boot b/src/interp/compiler.boot index 2204a0f7..c759bafa 100644 --- a/src/interp/compiler.boot +++ b/src/interp/compiler.boot @@ -479,17 +479,23 @@ compForm2(form is [op,:argl],m,e,modemapList) == compForm3(form,m,e,modemapList) compForm3(form,m,e,modemapList) +++ We are about to compile a call. Returns true if each argument +++ partially matches (as could be determined by type inference) the +++ corresponding expected type in the callee's modemap. +compFormMatch: (%Modemap,%List) -> %Boolean +compFormMatch(mm,partialModeList) == main where + main() == + mm is [[.,.,:argModeList],:.] and match(argModeList,partialModeList) + or wantArgumentsAsTuple(partialModeList,argModeList) + match(a,b) == + null b => true + null first b => match(rest a,rest b) + first a=first b and match(rest a,rest b) + compFormPartiallyBottomUp(form,m,e,modemapList,partialModeList) == mmList:= [mm for mm in modemapList | compFormMatch(mm,partialModeList)] => compForm3(form,m,e,mmList) -compFormMatch(mm,partialModeList) == - mm is [[.,.,:argModeList],:.] and match(argModeList,partialModeList) where - match(a,b) == - null b => true - null first b => match(rest a,rest b) - first a=first b and match(rest a,rest b) - compForm3(form is [op,:argl],m,e,modemapList) == T:= or/ @@ -501,12 +507,19 @@ compForm3(form is [op,:argl],m,e,modemapList) == T T +++ Returns the list of candidate modemaps for a form. A modemap +++ is candidate for a form if its signature has the same number +++ of paramter types as arguments supplied to the form. A special +++ case is made for a modemap whose sole parameter type is a Tuple. +++ In that case, it matches any number of supplied arguments. getFormModemaps: (%Form,%Env) -> %List getFormModemaps(form is [op,:argl],e) == op is ["elt",domain,op1] => [x for x in getFormModemaps([op1,:argl],e) | x is [[ =domain,:.],:.]] - null atom op => nil + not atom op => nil modemapList:= get(op,"modemap",e) + -- Within default implementations, modemaps cannot mention the + -- current domain. if $insideCategoryPackageIfTrue then modemapList := [x for x in modemapList | x is [[dom,:.],:.] and dom ^= '$] if op="elt" @@ -515,7 +528,8 @@ getFormModemaps(form is [op,:argl],e) == if op="setelt" then modemapList:= seteltModemapFilter(CADR argl,modemapList,e) or return nil nargs:= #argl - finalModemapList:= [mm for (mm:= [[.,.,:sig],:.]) in modemapList | #sig=nargs] + finalModemapList:= [mm for (mm:= [[.,.,:sig],:.]) in modemapList + | enoughArguments(argl,sig)] modemapList and null finalModemapList => stackMessage('"no modemap for %1b with %2 arguments", [op,nargs]) finalModemapList @@ -1255,7 +1269,7 @@ coerce(T,m) == keyedSystemError("S2GE0016",['"coerce", '"function coerce called from the interpreter."]) if $useRepresentationHack then - rplac(CADR T,substitute("$",$Rep,CADR T)) + rplac(CADR T,MSUBST("$",$Rep,CADR T)) T':= coerceEasy(T,m) => T' T':= coerceSubset(T,m) => T' T':= coerceHard(T,m) => T' @@ -1409,6 +1423,30 @@ autoCoerceByModemap([x,source,e],target) == [x,source,target]) [["call",genDeltaEntry ["autoCoerce", :fn],x],target,e] + +++ Compile a comma separated expression list. These typically are +++ tuple objects, or argument list in a call to a homogeneous +++ vararg operations. +compComma: (%Form,%Mode,%Env) -> %Maybe %Triple +compComma(form,m,e) == + form isnt ["%Comma",:argl] => systemErrorHere "compComma" + Tl := [comp(a,$EmptyMode,e) or return "failed" for a in argl] + Tl = "failed" => nil + -- ??? Ideally, we would like to compile to a Cross type, then + -- convert to the target type. However, the current compiler and + -- runtime data structures are not regular enough in their interfaces; + -- so we make a special rule when compiling with a Tuple as target, + -- we do the convertion here (instead of calling convert). Semantically, + -- there should be no difference, but it makes the compiler code + -- less regular, with duplicated effort. + m is ["Tuple",t] => + Tl' := [convert(T,t) or return "failed" for T in Tl] + Tl' = "failed" => nil + [["asTupleNew0", [T.expr for T in Tl']], m, e] + T := [["LIST2VEC", [T.expr for T in Tl]], + ["Cross",:[T.mode for T in Tl]], e] + convert(T,m) + --% Very old resolve -- should only be used in the old (preWATT) compiler @@ -1704,5 +1742,6 @@ for x in [["|", :"compSuchthat"],_ ["Mapping", :"compCat"],_ ["UnionCategory", :"compConstructorCategory"],_ ["where", :"compWhere"],_ + ["%Comma",:"compComma"],_ ["[||]", :"compileQuasiquote"]] repeat MAKEPROP(first x, "SPECIAL", rest x) |