Assembly or .... (really multiple assignments)

Aaron Sloman aarons at cvaxa.sussex.ac.uk
Sun Dec 18 08:19:53 AEST 1988


> From: ok at quintus.uucp (Richard A. O'Keefe)
> Message-ID: <764 at quintus.UUCP>
> Date: 29 Nov 88 11:24:15 GMT

> In article <1032 at l.cc.purdue.edu> cik at l.cc.purdue.edu (Herman Rubin) writes:
> > A trivial example is having a list of results to the left of
> > the replacement operator.  I do not mean a vector or a struct; the items
> > may be of different types, and should not be stored in adjacent memory
> > locations.

> If you mean things like being able to write
>		x, i, s := x/(1.0,+x), i-2, s || "x" || s
> CPL had it, BCPL has it (in sequential form), MESA has it (you have to
> put record constructor functions around both sides, but that's merely
> notational), and it has appeared in several experimental languages.
> Common Lisp supports it under the name PSETQ:
>		(psetq x (/ x (+ 1.0 x))
>		       i (- i 2)
>		       s (however-you-concatenate-strings s "x" s))
> I have never understood why it was omitted from Pascal, Modula, ADA:
>		x, y := y, x
> is the clearest way to exchange two variables I know.  I once put
> this construct into the compiler for an Algol-like language; it was
> easy, and if the compiler had done any optimisation it would still
> have been easy.

-----------------------
I think Algol68 also has it ("collateral assignment"??).

I have not read the discussion that preceded all this, but
just for information, if you want to do multiple assignments in
Pop-11 (where assignments go left to right) you can do things like

    [a list], 'a string', "word", 99 -> x1 -> x2 -> x3 -> x4;

Because Pop-11 uses a stack this is equivalent to
    99         -> x1;
    "word"     -> x2;
    'a string' -> x3;
    [a list]   -> x4;
etc.

Swapping the values of two variables in Pop-11 is done thus:

    x, y -> x -> y

I.e. you don't need the usual "temporary" variable - just stack
the value of x, stack the value of y, then pop the top of the
stack into x, then pop into y. I assume Forth can do this too.

It would be trivial in Pop-11 to write a macro that did a multiple
assignment in the "natural" order, i.e. not in the above stack-oriented
last-in first-out order.

Not quite so trivial, but also possible (and more efficient), is
defining a new "syntax word" to do it. The difference is that a macro
reads in text then rearranges the compiler input stream, whereas a
syntax word reads in some of the input stream and then plants Poplog
virtual machine instructions to be compiled. Also, defining syntax
words helps the parser give more helpful error messages if you make
syntactic mistakes.

E.g. to define ">->" as a new Pop-11 syntax operator to do multiple
assignment, with a precedence of 11, i.e. equal to that of the built-in
assignment symbol "->", you could do something like the following:

    define syntax 11 >-> ;
        ;;; Define local recursive sub-procedure to read in comma-separated
        ;;; variables up to semi-colon and plant assignments to them
        ;;; in reverse order (on exit from recursion).
        define plant_assignments();
            lvars varname;
            if nextitem() /== ";" then
                ;;; Read the next item in input stream
                itemread() -> varname;
                ;;; Do all the rest up to the semi-colon
                plant_assignments();
                unless varname == "," then
                    ;;; plant VM code to assign top of stack to variable
                    sysPOP(varname);
                endunless;
            endif;
        enddefine;

        ;;; Now the main body of the procedure for ">->"
        ;;; First some mumbo jumbo to plant code for last Pop-11 operation
        pop_expr_inst(pop_expr_item);
        pop11_FLUSHED -> pop_expr_inst;

        ;;; Now read in variable names and plant assignments
        plant_assignments();
    enddefine;

We can test the above definition as follows
    ;;; Declare some variables
    vars a, b, c;

    ;;; Try a multiple assignment to a, b, c.
    11, 22, 33 >-> a, b, c;

    ;;; Make a list containing values of a, b, and c, and check that
    ;;; the order is right when it is printed out
    [^a ^b ^c] =>
    ** [11 22 33]

Ideally the definition of ">->" would include extra instructions
to do more syntax checking (e.g. complaining if a syntax word
is read in before ";", or if a comma is missing).


Aaron Sloman,
School of Cognitive and Computing Sciences,
Univ of Sussex, Brighton, BN1 9QN, England
    ARPANET : aarons%uk.ac.sussex.cvaxa at nss.cs.ucl.ac.uk
    JANET     aarons at cvaxa.sussex.ac.uk
    BITNET:   aarons%uk.ac.sussex.cvaxa at uk.ac
    UUCP:     ...mcvax!ukc!cvaxa!aarons or aarons at cvaxa.uucp



More information about the Comp.lang.c mailing list