Greetings! Robert Boyer <[EMAIL PROTECTED]> writes:
> > might there be some other construct which could be used to > > regain the exact arity > > Dunno, but here are some more unjustified opinions. > > A. I think you should reflect on the syntax in > cmpnew/gcl_cmpopt.lsp. There, one deals with type > expression that are conditional: if the inputs are of such > and such a type, then the outputs are of such and such a > type. This is very important for efficiency. Agreed! We've expanded on this significantly by the type propagator functions you can find in gcl_cmptype.lsp, and the inline-types fuctions (mostly for aref and aset)you can find in gcl_cmpinline.lsp. The idea being that functions give more flexibility and a finer degree of control than a preset list of discrete possibilities. > > B. I hope you utterly stop using the symbol 'values' because > I think it does not make real and practical sense yet to me. > Probably a good idea, but thus far, 'values means 'returns-at-most. We do distinguish this from returns-exactly as you so helpfully suggested -- thanks! Its just a simple text editor replacement to do as you suggest, however. > C. For internal GCL compiler purposes only, simply not > visible to the ordinary user, the compiler should use a > language for talking about the outputs of a function that > permits only three basic options (depending of course upon > conditions on the types of inputs, as suggested above). > > (1) the stupid case of 'I know nothing' > * ; meaning any number of values of any type possible, > ; including the possibility of no values at all. > ; callee will have to set some indicator of > ; number of values returned (and maybe even where > ; they are returned and what their types are). > ; calls to functions of this output type > ; must read the indicator of # of values returned. > ; calls to such functions are slow! The user will > ; learn not to use such functions except in very > ; special cases, such as when the user must resort > ; to calling 'eval' > Right now, '* means the callee writes to the traditional value stack, and sets vs_base and vs_top. The caller retrieves the values from there. > (2) the 'vanilla' case of exactly one value always returned > bar ; meaning that one value of type bar is returned, where type bar > ; is built up out of 'and', 'or', 'not' > ; and atomic types like t and fixnum, and vector > ; (but no use of 'values' is permitted). > ; Any caller of a function with such an output type > ; knows this will be an ordinary c function call > ; returning one thing in the ordinary way a c function does > This is typically returned in a register when fast linking is on. For correctness with Paul's random compiler tester, we may have a few excessive resets of vs_top for safety still. Most functions set base to be their vs_top on entry, sup which exceeds base by a computed amount needed by the function, and then vs_top to sup. Calls to '* functions push values up from here. On exit, vs_top is reset to base. When the caller is done extracting values, it sets vs_top back to sup for the next call to avoid value stack leaks -- sometimes we do this even in this case, where we should know that the callee has left vs_top alone. This might take a little thought :-) > (3) the 'chocolate' case of exactly 4 values always returned > (obviously for any specific number 4) > > (si::returns-exactly fixnum t t foo) > ; meaning that exactly and always, > ; 4 outputs are returned, the first > ; a fixnum, the second and third unknown, > ; and the last of type foo (defined with > ; 'and', or, 'not', and atomic types but no > ; use of 'values'). > > When some function foo is being compiled and foo's code > calls a function bar, if the compiler knows that bar is of > type 2 or 3 above, then it can lay down an ordinary c > function call that 'knows' where and how many values are > returned and does not need to ask or be told anything about > the number of values returned. However, if, when compiling > foo, the compiler does not (yet) know that the output type > of bar fits into exactly one of class 2 or and 3 above, the > compiler lays down a more general call of bar that at > runtime will pay the price for an unknown return number; the > compiler leaves a note to recompile foo if and when it > learns that bar is of type 2 or 3. And the compiler notes > that whenever bar is redefined by anyone, the compiler must > consider recompiling foo, especially if bar used to have > output type 2 or 3 and that changes. > OK so we have both returns-exactly, and values at present. In the former case, the callee writes to the provided area if not null, and sets vs_top only to the end of the space. The caller does nothing but reset vs_top and proceed, as the values are already in place. We have the callee setting vs_top at present to prevent error in the case where it is redefined and the caller is not recompiled -- the fast link is not reestablished here with a warning printed to the screen, and only the number allowed by the caller are written into place. We could actually achieve the same effect by using a element in the sfn and vfn structures that now hold the number of values returned -- this will probably accelerate things somewhat. You can see the warning if you like by setting *disable-recompile* to t, compiling foo with (values 1 2), bar with a mvbind, then foo again with (values 1 2 3), then trying to run bar. In the values case (as opposed to returns-exactly), the callee is as before, but the caller reads vs_top to set any unset variables to nil. Actually, in the returns-exactly case, the same is done when binding more variables that the callee returns. This could be sped up a bit too. Take care, > Some example output type expressions for some primititives: > > apropos * > eval * > cons t > intern (si::returns-exactly symbol boolean) > gethash (si::returns-exactly t boolean) > read t > eq boolean > nconc t > > Obviously all special operators have to been handled > specially because they are 'special', e.g., > > quote -- type of the object quoted > progn -- the return type of the last element, or 'symbol' if > no elements > catch -- *very* hard to tell. > depends upon whether you can analyze all > possible throws to the tag. probably *. > values -- (returns-exactly ... first output type for each arg) > or * if there are none > if -- 'union' of the output values of the then-form > and the else-form, which is * unless both have > the exact same number of outputs, and otherwise > one forms the pointwise 'or' of those outputs > > Bob > > > > > -- Camm Maguire [EMAIL PROTECTED] ========================================================================== "The earth is but one country, and mankind its citizens." -- Baha'u'llah _______________________________________________ Gcl-devel mailing list Gcl-devel@gnu.org http://lists.gnu.org/mailman/listinfo/gcl-devel