Xref: utzoo comp.lang.c:14950 comp.lang.misc:2364 comp.arch:7610 Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!rutgers!gatech!purdue!decwrl!sun!pitstop!sundc!seismo!uunet!mcvax!ukc!warwick!cvaxa!aarons From: aarons@cvaxa.sussex.ac.uk (Aaron Sloman) Newsgroups: comp.lang.c,comp.lang.misc,comp.arch Subject: Re: Assembly or .... (really multiple assignments) Message-ID: <543@cvaxa.sussex.ac.uk> Date: 17 Dec 88 22:19:53 GMT Organization: School of Cognitive Sciences, Univ of Sussex, Brighton, UK Lines: 117 > From: ok@quintus.uucp (Richard A. O'Keefe) > Message-ID: <764@quintus.UUCP> > Date: 29 Nov 88 11:24:15 GMT > In article <1032@l.cc.purdue.edu> cik@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@nss.cs.ucl.ac.uk JANET aarons@cvaxa.sussex.ac.uk BITNET: aarons%uk.ac.sussex.cvaxa@uk.ac UUCP: ...mcvax!ukc!cvaxa!aarons or aarons@cvaxa.uucp