-
Notifications
You must be signed in to change notification settings - Fork 1
/
locals.html
562 lines (493 loc) · 20.1 KB
/
locals.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
<html>
<head>
<title>Enhanced local variable syntax </title>
<style type="text/css">
ol li { margin-left: -1em; }
.item { width: 5em; }
ul.results { margin-left: 0em; padding-left: 20px; }
ul.results li { margin-bottom: 1ex; }
ul.results li:first-line { font-weight: bold; }
.history dd { margin-bottom: 1ex; }
.def dd { margin-bottom: 2ex; }
</style>
</head>
<body>
<h3>Enhanced local variable syntax</h3>
<p>
[ <a href="rfds.html">RfDs/CfVs</a> | <a href="proposals.html">Other proposals</a> ]
</p>
<h3>Poll Standings</h3>
See <a href="#voting">below</a> for voting instructions.
<h4>Systems</h4>
<dl>
<dt> [ ] conforms to ANS Forth.</dt>
<dd>SwiftForth<br/>
SwiftX<br/>
VFX Forth<br/>
Forth 7
</dd>
<dt> [ ] already implements the proposal in full since release [ ].</dt>
<dd>VFX Forth [10 years ago]</dd>
<dt> [ ] implements the proposal in full in a development version.</dt>
<dt> [ ] will implement the proposal in full in release [ ].</dt>
<dt> [ ] will implement the proposal in full in some future release.</dt>
<dd>SwitfForth<br/>
SwitfX
</dd>
<dt> [ ] There are no plans to implement the proposal in full in [ ].</dt>
<dd>4tH [3.61.1]</dd>
<dt> [ ] will never implement the proposal in full.
</dl>
<h4>Programmers</h4>
<dl>
<dt> [ ] I have used (parts of) this proposal in my programs.</dt>
<dd>Doug Hoffman<br/>
Gerry Jackson<br/>
Stephen Pelc
</dd>
<dt> [ ] I would use (parts of) this proposal in my programs if the systems I am interested in implemented it.</dt>
<dd>Doug Hoffman<br/>
Gerry Jackson</dd>
<dt> [ ] I would use (parts of) this proposal in my programs if this proposal was in the Forth standard.</dt>
<dd>Doug Hoffman<br/>
Gerry Jackson</dd>
<dt> [ ] I would not use (parts of) this proposal in my programs.</dt>
<dd>Hans Bezemer<br/>
Doug Hoffman<br/>
Leon Wagner<br/>
Andrew Haley
</dd>
</dl>
<h4>Informal Results</h4>
<ul class="results">
<li>Hans Bezemer<br/>
I don't like locals, enhanced or otherwise. If I wanted to program C, I'd program C.
</li>
<li>Doug Hoffman<br/></li>
I will use the historically normal and very common { ... } syntax.<br/>
I will normally not use the "never been seen before" {: ... :} syntax.
</ul>
<h2>Rationale</h2>
<table width="500"><tr><td>
<h3>Problem</h3>
<ol>
<li>The current <code>LOCALS|</code> ... <code>|</code> notation explicitly
forces all locals to be initialised from the data stack.<p/></li>
<li>The current <code>LOCALS|</code> ... <code>|</code> notation defines
locals in reverse order to the normal stack notation.</li>
</ol>
This proposal is derived from implementations that have existed for
more than 25 years.
<h3>Solution</h3>
<h4>Base version</h4>
The following syntax for locals is proposed. The sequence:
<blockquote>
<code>{:</code> arg1 arg2 ... <code>|</code> lv1 lv2 ... <code>--</code> o1 o2 ... <code>:}</code>
</blockquote>
declares local arguments, local values, and dummy outputs.
<p/>
Local arguments and local values both behave as locals, they differ
only in respect to their initialisation.
<p/>
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 values can be referenced by name within the
word during compilation. The output names are dummies to allow a local
declaration to be read as a stack comment.
<ul>
<li>The items between <code>{:</code> and <code>|</code> are local arguments
initialised from the data stack.</li>
<li>The items between <code>|</code> and <code>--</code> are uninitialised
local values.</li>
<li>The items between <code>--</code> and <code>:}</code> are outputs for
formal comments only.</li>
</ul>
The <code>--</code> to <code>:}</code> section is optional, i.e., <code>|</code>
or <code>{:</code> direct to <code>:}</code> is permitted.
<p/>
The outputs are provided in the notation so that complete stack
comments can be produced. However, all text between <code>--</code>
and <code>:}</code> is ignored. This facility is there to permit the
notation to form a complete stack comment, which eases documentation.
<p/>
Local arguments and values return their values when referenced,
and must be preceded by <code>TO</code> to perform a store.
<p/>
In the example below, <em>a</em> and <em>b</em> are local arguments,
and <em>c</em> and <em>d</em> are local values.
<blockquote><pre>
: foo {: a b | c d -- :}
a b + to c
a b * to d
cr c . d .
;
</pre></blockquote>
<h4>Local types and extensions</h4>
Although out of the scope of this proposal, it should be noted that
some current Forth systems use indicators to define local values of
sizes other than a cell. To avoid issues when porting code to such
systems, names ending in a '<code>:</code>' (colon) should be avoided.
<blockquote><pre>
: foo {: a b | F: f1 F: f2 -- c :}
...
;
</pre></blockquote>
At least one Forth implementation uses local value names ending in
the '<code>[</code>' character to indicate local buffers. This character should
be avoided to prevent disfranchising implementations that implement
the behaviour. For similar reasons the use of non-alphabetic single
character local names should also be avoided.
<h3>Discussion</h3>
The phrase <code>{</code> ... <code>}</code> rather than
<code>{:</code> ... <code>:}</code> has been used by systems for
over 25 years. However, it conflicts with existing practise in other
Forth systems. Choosing the new name allows both practises to coexist.
<p/>
The '<code>|</code>' (ASCII $7C) character is widely used as the separator between
local arguments and local values. Other characters accepted in current
Forth implementations are '<code>\</code>' (ASCII $5C) and '<code>¦</code>' ($A6). We propose
only to consider the '<code>|</code>' character further. Only recognition of the
'<code>|</code>' separator is mandatory.
<p/>
Some current systems permit <code>TO</code> to be used with floats (children of
<code>FVALUE</code>) and other data types. Such systems often provide additional
operators such as <code>+TO</code> (add from stack to item) for children of
<code>VALUE</code> and <code>FVALUE</code>.
<h3>Proposal</h3>
In order to facilitate the use of BNF in the <code>{:</code> definition it is
necessary to move the BNF definition added to <strong>2.2.1 Numeric notation</strong>
by the <strong>X:number-prefix</strong> proposal to a more general description in
section <strong>2.2 Notation</strong>.
<blockquote>
The following notation is used to define the syntax of the various
elements within the document:
<ul>
<li>Each component of the element is defined with a rule consisting
of the name of the component (italicized in angle-brackets,
e.g., <<em>decdigit</em>>), the characters <code>:=</code> and
a concatenation of tokens and metacharacters;<p/></li>
<li>Tokens may be literal characters (in bold face, e.g., <strong>E</strong>) or
rule names in angle brackets (e.g., <<em>decdigit</em>>);<p/></li>
<li>The metacharacter * is used to specify zero or more occurrences
of the preceding token (e.g., <<em>decdigit</em>>*);<p/></li>
<li>Tokens enclosed with [ and ] are optional (e.g., [<strong>-</strong>]);<p/></li>
<li>Vertical bars separate choices from a list of tokens enclosed
with braces (e.g., { <strong>0</strong> | <strong>1</strong> }).</li>
</ul>
See: 3.4.1.3 Text interpreter input number conversion,
12.3.7 Text interpreter input number conversion,
12.6.1.0558 <code>>FLOAT</code>,
12.6.2.1613 <code>FS</code> and
13.6.2.xxxx <code>{:</code>.
</blockquote>
<strong>13.3.3.1 Compilation semantics</strong>
<p/>
Replace "at least eight locals" in the last paragraph with "at least
sixteen locals".
<p/>
<strong>13.3.3.2 Syntax restrictions</strong>
<p/>
Replace item f)
<blockquote>
A program that declares more than eight locals in a single
definition has an environmental dependency;
</blockquote>
with
<blockquote>
A program that declares more than sixteen locals in a single
definition has an environmental dependency;
</blockquote>
<strong>13.4.1.2 Ambiguous conditions</strong>
<p/>
Add the following ambiguous conditions:
<ul>
<li>a local name ends in "<code>:</code>", "<code>[</code>", "<code>^</code>";</li>
<li>a local name is a single non-alphabetic character;</li>
<li>the text between <code>{:</code> and <code>:}</code> extends over more than one line;</li>
<li><code>{:</code> ... <code>:}</code> is used more than once in a word.</li>
</ul>
<strong>13.4.2.1 Environmental dependencies</strong>
<p/>
Replace:
<ul>
<li>declaring more than eight locals in a single definition
(13.3.3 Processing locals).</li>
</ul>
with
<ul>
<li>declaring more than sixteen locals in a single definition
(13.3.3 Processing locals).</li>
</ul>
<strong>13.6.2 Locals extension words</strong>
<pre>
13.6.2.xxxx {: brace-colon LOCAL EXT
</pre>
<dl class="def">
<dt>Interpretation:</dt>
<dd>Interpretation semantics for this word are undefined.</dd>
<dt>Compilation: ( <em>i*x "<spaces>ccc</em><code>:}</code>" -- )</dt>
<dd>
Parse <em>ccc</em> according to the following syntax:
<blockquote>
<strong><code>{:</code></strong> <<em>arg</em>>*
[<strong><code>|</code></strong> <<em>val</em>>*]
[<strong><code>--</code></strong> <<em>out</em>>*]
<strong><code>:}</code></strong>
</blockquote>
where <<em>arg</em>>, <<code>val</code>> and <<em>out</em>> are local names,
and <em>i</em> is the number of <<em>arg</em>> names given.
<p/>
The following ambiguous conditions exist when:
<ul>
<li>a local name ends in "<code>:</code>", "<code>[</code>", "<code>^</code>";</li>
<li>a local name is a single non-alphabetic character;</li>
<li>the text between <code>{:</code> and <code>:}</code> extends over more than one line;</li>
<li><code>{:</code> ... <code>:}</code> is used more than once in a word.</li>
</ul>
<p/>
Append the run-time semantics below.
</dd>
<dt>run-time: ( <em>x1</em> ... <em>xn</em> -- )</dt>
<dd>Create locals for <<em>arg</em>>s and <<em>val</em>>s. <<em>out</em>>s are ignored.
<p/>
<<em>arg</em>> names are initialized from the data stack, with the top of
the stack being assigned to the right most <<em>arg</em>> name.
<p/>
<<em>val</em>> names are uninitialized.
<p/>
<<em>val</em>> names and <<em>arg</em>> names have the execution semantics given
below.
</dd>
<dt><em>name</em> Execution: ( -- <em>x</em> )</dt>
<dd>Place the value currently assigned to <em>name</em> on the stack.
An ambiguous condition exists when local is executed while in interpretation state.
</dd>
<dt><code>TO</code> <em>name</em> Run-time: ( <em>x</em> -- )</dt>
<dd>Assign the value <em>x</em> to the local <em>name</em>.</dd>
<dt>See:</dt>
<dd>2.2 Notation, 6.2.2405 <code>VALUE</code>, 6.2.2295 <code>TO</code>
and A.13.6.2.xxxx <code>{:</code>.
</dd>
</dl>
<strong>A.13.6 Glossary</strong>
<dl class="def">
<dt>A.13.6.2.xxxx <code>{:</code></dt>
<dd>
In A.13 The optional Locals word set of ANS Forth '94 the TC identifies
the significant difficulties experienced when addressing the issue
of locals. Since the Technical Committee was unable to identify any
common practice they provided a way to define locals 13.6.1.0086
<code>(LOCAL)</code>) and a method of parsing them (13.6.2.1795 <code>LOCALS|</code>). In
the hope that a common practice will emerge.
<p/>
Common practice has since emerged. Most implementations that
provide <code>(LOCAL)</code> and <code>LOCALS|</code> also provide some form of the <code>{</code> ... <code>}</code>
notation; however, the phrase <code>{</code> ... <code>}</code> conflicts with other systems.
The <code>{:</code> ... <code>:}</code> notation is a compromise to avoid name conflicts.
<p/>
The notation provides for different classes: locals that are
initialized from the data stack at run-time; uninitialized locals
and outputs. Initialized locals are separated from uninitalized
locals by '<code>|</code>'. The definition of locals is terminated by '<code>--</code>' or
'<code>:}</code>'.
<p/>
All text between '<code>--</code>' and '<code>:}</code>' is ignored. This eases documentation
by allowing a complete stack comment in the locals definition.
<p/>
The '<code>|</code>' (ASCII $7C) character is widely used as the separator
between local arguments and local values. Some implementations
have used '<code>\</code>' (ASCII $5C) or '<code>¦</code>' ($A6). Systems are free to
continue to provide these alternative separators. However, only
the recognition of the '<code>|</code>' separator is mandatory. Therefore
portable programs must use the '<code>|</code>' separator.
<p/>
A number of systems extend the locals notation in various ways.
Some of these extensions may emerge as common practice. This
standard has reserved the notation used by these extensions to
avoid difficulties when porting code to these systems. In
particular local names ending in '<code>:</code>' (colon), '<code>[</code>' (open bracket),
or '<code>^</code>' (carat) are reserved.
</dl>
</td></tr></table>
<h3>Reference Implementation</h3>
<pre><code>
0 [if]
BUILDLV c-addr u +n mode
When executed during compilation, BUILDLV passes a message to the
system identifying a new local argument whose definition name is
given by the string of characters identified by c-addr u. The size
of the data item is given by +n address units, and the mode
identifies the construction required as follows:
0 - finish construction of initialisation and data storage
allocation code. C-addr and u are ignored. +n is 0
(other values are reserved for future use).
1 - identify a local argument, +n = cell
2 - identify a local value, +n = cell
3+ - reserved for future use
-ve - implementation specific values
The result of executing BUILDLV during compilation of a definition
is to create a set of named local arguments and values, each of
which is a definition name, that only have execution semantics
within the scope of that definition's source.
Note that it is often useful to accumulate and store the size of
locals storage (0=none), so that compilers for EXIT can easily
determine if locals clean up code is required.
[then]
VARIABLE #LVS \ -- addr
\ Holds size of locals storage required.
: BUILDLV \ c-addr u +n mode --
\ Dummy for testing
OVER #LVS +!
CR 2SWAP TYPE SPACE SWAP . .
;
: TOKEN \ -- caddr u
\ Get the next space delimited token from the input stream.
\ Can be extended to permit multiple line declarations.
PARSE-NAME
;
: LTERM? \ caddr u -- flag
\ Return true if the string caddr/u is "--" or ":}"
2DUP S" --" COMPARE 0= >R
S" :}" COMPARE 0= R> OR
;
: LSEP? \ caddr u -- flag
\ Return true if the string caddr/u is the separator between
\ local arguments and local values or buffers.
2DUP S" |" COMPARE 0= >R
S" \" COMPARE 0= R> OR
;
: {: \ --
\ Parse the locals declaration up to the closing ":}".
0 #LVS ! \ indicate no locals yet
0 >R \ indicate arguments
BEGIN
TOKEN 2DUP LTERM? 0=
WHILE \ -- caddr len
2DUP LSEP? IF \ if '|'
R> DROP 1 >R \ change to vars and buffers
ELSE
R@ 0= IF \ argument?
CELL 1
ELSE \ value
CELL 2
THEN
BUILDLV
THEN
REPEAT
BEGIN
S" :}" COMPARE
WHILE
TOKEN
REPEAT
0 0 0 0 BUILDLV
R> DROP
; IMMEDIATE
</code></pre>
<h3>Test Cases</h3>
<pre><code>
: LT1 {: a b | c -- f :}
CR ." Hello1 " CR a ;
T{ 3 4 LT1 -> 3 }T \ Outputs Hello1
: LT2 {: a | b c e :}
CR ." Hello2 " CR ;
T{ 3 LT2 -> }T \ Outputs Hello2
: LT3 {: a b c -- :}
CR ." Hello3 " CR ;
T{ 3 4 5 LT3 -> }T \ Outputs Hello3
: LT4 {: a b c :}
CR ." Hello4 " CR ;
T{ 3 4 5 LT4 -> }T \ Outputs Hello4
: LT5 {: a | b c d -- e f g :}
CR ." Hello5 " CR
a 2* to b b 2* to c c 2* to d
b c d ;
T{ 3 LT5 -> 6 12 24 }T \ Outputs Hello5
</code></pre>
<h3>Change History</h3>
<dl class="history">
<dt>2010-10-11</dt><dd>
Replaced ambiguous condition on locals named
"<code>\</code>", "<code>|</code>",
"<code>:</code>" and "<code>}</code>"
with the more general condition of using a single non-alphabetic
character as a local name.
<br>Added additional document for sixteen locals rather than eight.</dd>
<dt>2010-09-24</dt><dd>
Added local names "<code>:</code>" and "<code>}</code>"
as ambiguous condition.</dd>
<dt>2010-03-25</dt><dd>
Wordsmithing at Rostock meeting
<br>Moved to BNF description
<br>Added rationale
<br>Converted Testing to new harness</dd>
<dt>2009-10-22</dt><dd>
Discussion about <code>{</code> and <code>{:</code>.
<br>"Should" to "shall".</dd>
<dt>2009-08-30</dt><dd>Tidied.</dd>
<dt>2009-03-25</dt><dd>Updated with some renaming.</dd>
<dt>2008-08-11</dt><dd>Removed references to local buffers as appropriate.</dd>
<dt>2007-09-14</dt><dd>Moved local buffers to separate proposal.</dd>
<dt>2007-06-07</dt><dd>Wordsmithing. Corrected reference implementation.</dd>
<dt>2006-08-22</dt><dd>
Added explanatory text.
<br>Corrected reference implementation.
<br>Updated ambiguous conditions.</dd>
</dl>
<h3>Credits</h3>
Stephen Pelc, <stephen<em>@</em>mpeforth<em>.</em>com><br/>
MicroProcessor Engineering Ltd - More Real, Less Time<br/>
133 Hill Lane, Southampton SO15 5AF, England<br/>
tel: +44 (0)23 8063 1441,<br/>
fax: +44 (0)23 8033 9691<br/>
web: <a href="http://www.mpeforth.com">www.mpeforth.com</a> - free VFX Forth downloads
<p/>
Peter Knaggs, <pjk<em>@</em>bcs<em>.</em>org><br/>
Engineering, Mathematics and Physical Sciences,<br/>
University of Exeter, Exeter, Devon, Ex4 4QF, England<br/>
tel: +44 (0) 1392 723594<br/>
web: <a href="http://www.rigwit.co.uk/">www.rigwit.co.uk</a>
<a name="voting"><h3>Voting Instructions</h3></a>
Fill out the appropriate ballot(s) below and mail it/them to
<[email protected]>. Your vote will be published (including your
name (without email address) and/or the name of your system) here.
You can vote (or change your vote) at any time, and the results will
be published here.
<p>
Note that you can be both a system implementor and a programmer, so
you can submit both kinds of ballots.
</p>
<h4>Ballot for systems</h4>
If you maintain several systems, please mention the systems separately
in the ballot. Insert the system name or version between the brackets.
Multiple hits for the same system are possible (if they do not
conflict).
<dl>
<dt>[ ] conforms to ANS Forth. </dt>
<dt>[ ] already implements the proposal in full since release [ ]. </dt>
<dt>[ ] implements the proposal in full in a development version. </dt>
<dt>[ ] will implement the proposal in full in release [ ]. </dt>
<dt>[ ] will implement the proposal in full in some future release. </dt>
<dt>[ ] There are no plans to implement the proposal in full in [ ]. </dt>
<dt>[ ] will never implement the proposal in full. </dt>
</dl>
If you want to provide information on partial implementation, please do
so informally, and I will aggregate this information in some way.
<h4>Ballot for programmers</h4>
Just mark the statements that are correct for you (e.g., by putting an
"x" between the brackets). If some statements are true for some of your
programs, but not others, please mark the statements for the dominating
class of programs you write.
<dl>
<dt>[ ] I have used (parts of) this proposal in my programs.</dt>
<dt>[ ] I would use (parts of) this proposal in my programs if the systems
I am interested in implemented it.</dt>
<dt>[ ] I would use (parts of) this proposal in my programs if this
proposal was in the Forth standard.</dt>
<dt>[ ] I would not use (parts of) this proposal in my programs.</dt>
</dl>
If you feel that there is closely related functionality missing from the
proposal (especially if you have used that in your programs), make an
informal comment, and I will collect these, too. Note that the best time
to voice such issues is the RfD stage.
</body>
</html>