[Date Prev][Date Next][Subject Prev][Subject Next][ Date Index][ Subject Index]

Re: XPL shortcuts etc.



** Reply to note from "..."  Thu, 26 Dec 1996 13:25:21 -0500 (EST)

> Ahoy, Robert. What am I missing here? The purpose of some PFUN
> instructions baffles me. The CL parse seems to me extraneous and
> restrictive, limiting CMline conversion to func symbols that use ascii
> 128, excluding the two-thirds that involve ascii 129 and 130. (Cf.
> encoded file.)

No. The purpose of CL is different. See below. Also, the close
alternative to my code that you offer simply doesn't work (nothing
happens).

> A v4 thing? That section just doesn't work in v3; without it,
> a retroport works fine except for trouble with trailing nulls...

Actually it works fine. You just don't need it in most versions of 3+,
e.g. v3.57. But how did your 3+ versions become so wordy -- whew! The
original was short, lucid, and didactic (as the 3+ version should be):


{{5pfun}} Insert real function, either in Text or on CMline
{2}<>1>>SI
BX (pfun )<1>YD YD
DF CL DF RD 
+>
>GH {2}

All of this code for putting a true function on the CMline was aimed at
storing bytes two and three of the function -- the critical ones -- in a
single Save/Get (we know what the first byte is: 255). Look at the core
operation. If I write:

 

then it's clear that you need to examine func CL at the byte level. What
is CL? 255+128+91. Note that 91="[", and -- significantly -- that's the
input separator used in S/G 03. If you look ahead, you see that we discard
the output result S/G 03, so the only important result is S/G 04. Now,
what is the result (S/G 04) of the parse going to be? Obviously, S/G 04
will contain 255+128. So, you see, CL itself was unimportant; I could have
used _any_ three byte character for this part of the operation. My goal
was simply to get 255 plus _any_ other byte -- two bytes altogether -- into
a single Save/Get. Why?

Look what happens next: +> I concatenate S/G 04 and the
function call saved in S/G 01. What do we get? Let's use func BC as an
example. What is BC? 255+129+31. So, therefore, the result of this
concatenation is:

 255+128+255+129+31

Aha! 255+128+255 will form a function of its own -- a totally meaningless
function, to be sure, but one which will prise the 255 away from the last
two chars 129+31 of the concatenated string (something which is difficult
to do in Xy4, but relatively easy in some versions of 3+, i.e. whenever
wild X strictly parses one byte only -- instead of the looser concept of
parsing anything -- whether 1, 2, or 3 bytes long -- that occupies a single
visual space). This is accomplished in:

 

which leaves 129+31 by themselves on S/G 03. In v3.57 you can do that with
a single wildX (but, you know, I wasn't writing the routine for 3+, so it's
certainly not going to work out of the box). All that remains is to
concatenate a three byte 255 in front of 129+31, and move it from memory
onto the CMline, where a 3-byte to 1-byte conversion is performed for the
255. Voil?: a true function on the CMline. And "the two-thirds that
involve ascii 129 and 130" are _not_ excluded!

N.B.: If you concatenated a one byte 255 in front of 129+31, and tried to
move that from memory to the CMline, the bloody thing would execute, e.g.
BC would clear the command line -- which is not what you intend.

These concepts are classic XPL. This procedure _does_ work in 3+. You
gotta jiggle some things, of course! what they are, I dunno, I'm never
going back to III+ -- but it works, I promise you. And even though all
this stuff long predates Tyson, he never discussed ANY of it! 'The Book',
you say? Puh-leeze...

Now, in III+, you gotta be careful, because "wild X" as an input separator
in XS parses means different things in different versions of III+. One of
the most infuriating things about 3+ was that they kept changing the
treatment of wild X. Sometimes it parsed one byte, sometimes three bytes.
Every time they issued a minor upgrade, all your programming, your whole
setup, went AWOL! So each person needs to determine the behavior for his
3+ version. (I was, and remain, overjoyed to put 3+ behind me!)

But -- OK, for sake of argument, let's emulate this in v3.57. We'll design
it to run from the KBD file, on a dedicated key (or a LDPM key). We need
some preliminary values. One of the many intractable problems with 3+ is
that you can get 2 out of these 3 values, but not all: 1) position
of cursor within CMline; 2) cursor Insert|Overstrike state; 3) Header|Text
location of cursor. You gotta choose two among those three. In Xy4, it's
a cinch to get all three, and moreover you never require use of the CMline
anyway so no need to mess with it; but in 3+, impossible to get all three
with accuracy. Personally, I'd much rather have the position of the cursor
in the CMline, than the Insert|Overstrike state. So I'll select 1) and 3)
from the list above.

><>1>SI
>x>>BD

So S/G 01 now emulates the VA$TX of Xy4, which evaluates 1 if the cursor is
in Text, and 0 if on the CMline. Now, let's mark the position of the
cursor within the CMline, and then store the CMline (this isn't fastidious
 -- to capture every possible character, including bizarre 3-byters and the
compost heap, you must(!) run a subset of Stack's code, but -- that's
another excursion, so let's be brief and sloppy):

<1>>NO >

So the CMline is more-or-less stored in S/G 03, and a bizarre|nonexistent
3-byte character 255-33-36 (which looks like an inverted exclamation point)
marks the cursor position within the CMline. If we hadn't wanted to
capture the cursor position within the CMline, I would propose a much
faster, non-invasive, non-destructive method to determine the Header-or-
Text location of the cursor:

CH )>0>

Note that there is no longwinded cursoring around, backdeleting, or other
mickey mouse with this method. If you're in Text, func WA isn't Put --
nothing happens. Very clean. After this, you could get the Overstrike-or-
Insert state (assuming you cared):

BC xCL x)>1>

So S/G 06 would store Overstrike=0, Insert=1. Now we go a-PFUNning:

BC pfun XC 

If the cursor was originally on the CMline, we basically recap the code
of the Xy4 version, thus:

<1>YD XD DF CL DF RD 
+>
BC 

But if the cursor was originally in Text, we just restore the CMline:

BC GT

Finito. It's small, it's fast, it uses just four Save/Gets.

In use, you might construct a SEarch string, e.g.:

 CMse //

then locate your cursor between the slashes, and run the program. It would
put the function string between the slashes, and terminate so that you
could eXeCute the SEarch, or do whatever you want.

There are a couple of residual problems -- actually there are about seven
problems, named $A $I @6 DT TS WC and WL -- but we'll leave them for
another time.


XPLeNCODE v1.9
b-gin PFUN.PM
{{Cpfun}} PFUN.PM for XyWrite v3.57 1/4/97 R.J.Holmgren[cr|l
f][cr|lf]
{2}{<}SX01,{<}VA$WS{>}{>}{<}IF{<}PV01{>}<>1{>}{<}PRN
o file{>}{<}EX{>}{<}EI{>}[SI_]{<}SX01,0{>}{<}SX02,{<}CP{>}{>}
x{<}IF{<}CP{>}>{<}PV02{>}{>}{<}SX01,1{>}{<}EI{>}[BD_]{<}IF{<}
PV01{>}<1{>}{<}SV02,[255+70+70]!${>}{<}PV02{>}{<}EI{>}{<}SU02
,{<}SX03,{<}IS00{>}{>}[NO_]{>}{<}GT02{>}[BC_]pfun {<}PRPFUN-i
ng...{>}{<}RC{>}{<}RC{>}[XC_]{<}PR {>}{<}IF{<}PV01{>}<1{>}[YD
_][XD_][DF_][CL_][DF_]{<}SV01{>}[RD_]{<}SV02,{27}X{>}{<}XS01,
02,,02,04{>}{<}SV02,[255+70+70]{>}{<}SX04,{<}IS02{>}+{<}IS04{
>}{>}{<}SV02,[255+33+36]{>}{<}XS03,02,02,,01{>}[BC_]{<}PV02{>
}{<}PV04{>}{<}PV01{>}{<}EX{>}{<}EI{>}[BC_]{<}PV03{>}[GT_]{<}E
X{>}[cr|lf]
[cr|lf]

-nd
XPLeNCODE


Moronic UUenCoder for XyWrite RexXPL v1.0 R.J.Holmgren 9/22/96
begin 644 TMP32.MUD
M>WM#<&9U;GU](%!&54XN4$T@9F]R(%AY5W)I=&4@=C,N-3<@(#$O-"\Y-R!2
M+DHN2&]L;6=R96X-"@T*`JY36#`Q+*Y602174Z^OKDE&KE!6,#&O/#XQKZY0
M4DYO(&9I;&6OKD58KZY%2:__@xxxxxxxxN4U@P,2PPKZY36#`R+*Y#4*^O>*Y)1JY#
M4*\^KE!6,#*OKZY36#`Q+#&OKD5)K_^!*ZY)1JY05C`QKSPQKZY35C`R+/]&
M1B$DKZY05C`RKZY%2:^N4U4P,BRN4U@P,RRN25,P,*^O_X&CKZY'5#`RK_^!
M'W!F=6X@KE!24$953BUI;F