Stephen Pelc wrote:
> At long last I've started on my Forth200x tasks. Here's the first
> cut of the enhanced local variables using the { ... } notation.
Coincidentally, I have been working on the locals implementation in the
W32F native code version this last week. Timely; thank you.
>
> Stephen
>
> RfD - Enhanced local variable syntax
>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> Stephen Pelc - 20 August 2006
>
> Problem
> =3D=3D=3D=3D=3D=3D=3D
> 1) The current LOCALS| ... | notation explicitly forces all locals
> to be initialised from the data stack.
> 2) 1) The current LOCALS| ... | notation defines locals in reverse
> order to the normal stack notation.
> 3) When programming large applications, especially those interfacing
> with a host operating system, there is a frequent need for tem****ary
> buffers.
> 4) Current implementations show that creation and destruction of
> local buffers are much faster than using ALLOCATE (14.6.1.0707)
> and FREE (14.6.1.1605).
Agree with the above, and would add
5) Current implementations of { are diverging in the facilities they
provide.
6) { and } are visually confusing. Perhaps select another character or
string, which would allow existing implementations to do their own
thing unmolested.
>
> Solution
> =3D=3D=3D=3D=3D=3D=3D=3D
> Base version
> ------------
> The following syntax for local arguments and local variables is
> proposed. The sequence:
> { ni1 ni2 ... | lv1 lv2 ... -- o1 o2 }
> defines local arguments, local variables, and outputs. The local
> arguments are automatically initialised from the data stack on
> entry, the rightmost being taken from the top of the data stack.
> Local arguments and local variables can be referenced by name within
> the word during compilation. The output names are dummies to allow
> a complete stack comment to be generated.
IMHO the locals should really not replace the stack commentary (and
perhaps it's time there was an RFD for those too that can replace { }
?). The maximal requirement should be
{ ni1 ni2 ... | lv1 lv2 ... }
otherwise dummies may be taken for real values (and I also prefer the
word values to variables above to avoid ambiguity). They're suggestive
of automatic return values, which they are not.
> The items between { and | are local arguments.
> The items between | and -- are local variables or buffers.
> The items between -- and } are outputs.
>
> Local arguments and variables return their values when referenced,
> and must be preceded by TO to perform a store.
That's the bit I hate, but it's too late to argue for local variables I
know.
>
> Local buffers may be defined in the form:
> arr[ <expr> ]
> Any name ending in the '[' character will be treated as an buffer,
> the expression up to the terminating ']' will be interpreted to
> provide the size of the buffer. Local buffers only return their base
> address, all operators such as TO generate an ambiguous condition.
I do like the idea of being able to declare variables as opposed to
values.
I don't like the requirement to have a special token recogniser in the
parse a for the [ on grounds of aesthetics if nothing else. Plus, other
syntaxes can be envisaged in which a modified EVALUATE/QUIT with a
minor modification can handle the string between { and } in compile
mode; DPANS section 3.4 clause "d) If unsuccessful, an ambiguous
condition exists" would be "d) if unsuccesful, declare a local cell
sized value". It also makes f: or float: and other type modifiers
sup****table as parsing immediate words.
So, does the [ have to be part of the name? Here's a parsing example;
{ a
[ 10 ] buffer: b
float: f
variable: v
| value: c }
Question: is this
: x [ 128 ] { a arr[ ] } ;
valid? And is this
128 : X { a arr[ ] } ;
ambiguous or invalid?
[A note. In Forths like W32F that have a MOPS based OOP, [ is becoming
overworked as it is also used for late binding. I can see potentially
ambiguous situations should locals be extended to include objects.
That, however, is a problem for another discusssion.]
>
> In the example below, a and b are local arguments, a+b and a*b are
> local variables, and arr[ is a 10 byte local buffer.
>
> : foo { a b | a+b a*b arr[ 10 ] -- }
> a b + to a+b
> a b * to a*b
> cr a+b . a*b .
> arr[ 10 erase
> s" Hello" arr[ swap cmove
Ouch. That [ really grates.
> ;
>
> Local types
> -----------
> Some current Forth systems use indicators to define local variables
> of sizes other than a cell. It is proposed that any name ending in a
> ':'
> (colon) be reserved for this use.
>
> : foo { a b | F: f1 F: f2 -- c }
> ...
> ;
>
> Discussion
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> The '|' (ASCII 0x7C) character is widely used as the separator
> between local arguments and local variables. Other characters
> accepted in current Forth implementations are '\' (ASCII 0x5C) and
> '=A6' (ASCII 0xA6).. Since the ANS standard is defined in terms of
> 7 bit ASCII, and with regard to internationalistion, we propose only
> to consider the '|' and '\' characters further. Only recognition of
> the '|' separator is mandatory.
Use of \ should be discouraged on the grounds of ambiguity. It also
gives parsing & colouring editors indigestion. 0xA6 is outside the
range of ASCII.
[snipped]
> 0 0 0 0 BUILDLV
Is 0 0 (LOCALS) an equivalent?
--=20
Regards
Alex McDonald


|