Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #17649 > unrolled thread
| Started by | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| First post | 2012-11-28 20:18 +0000 |
| Last post | 2012-11-29 17:12 +0000 |
| Articles | 5 — 3 participants |
Back to article view | Back to comp.lang.forth
Forth 200X words S\" and SUBSTITUTE Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2012-11-28 20:18 +0000
Re: Forth 200X words S\" and SUBSTITUTE Alex McDonald <blog@rivadpm.com> - 2012-11-28 12:41 -0800
Re: Forth 200X words S\" and SUBSTITUTE Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2012-11-28 22:59 +0000
Re: Forth 200X words S\" and SUBSTITUTE anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2012-11-29 13:57 +0000
Re: Forth 200X words S\" and SUBSTITUTE Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2012-11-29 17:12 +0000
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2012-11-28 20:18 +0000 |
| Subject | Forth 200X words S\" and SUBSTITUTE |
| Message-ID | <k95rit$jp3$1@dont-email.me> |
I've just added the Forth 200X words S\" and SUBSTITUTE to my Forth
system with an extension that I've found useful in other contexts. This
extension is the ability to execute a named Forth word in the string
being processed by S\" and SUBSTITUTE. Such Forth words return a (caddr
u) string that is inserted into the result string. At the point the
Forth word is executed the stack is cleared of the S\" and SUBSTITUTE
working data so that the Forth word has access to user data on the
stack. This provides the ability to convert numbers into particular
formats and insert them into the resulting string.
In the case of SUBSTITUTE this requires no additional syntax, the name
of the Forth word is bracketed by % characters. The implementation has
to be extended to execute any Forth word, not just replacement names as
well as ensuring the stack is relatively empty. e.g.
: foo s" bar" ;
s" blah blah %foo% blah" buf 128 substitute
will insert the string "bar" into the resulting string.
This reduces the need for the word REPLACES
Another example shows that it provides an alternative to EXECUTE-PARSING
e.g.
: noop ( -- ) ;
: $define ( caddr1 u1 caddr2 u2 -- )
s" %noop% %noop%" buf 80 substitute if evaluate then
;
: $: s" :" $define ; \ $: same as :name
s" bar" $: 456 . ;
bar
displays 456
Of course this can also be done with the standard definition of
SUBSTITUTE, but is awkward as REPLACES has to be used.
Moving on to S\" the extension requires:
- an extension to the syntax, I use an extra escape e.g. \{foo}
- S\" must be usable in interpretation mode and at run-time
- user arguments to be made available to the called word
- preferably words affecting transient areas do not affect the S\"
buffer and vice versa
e.g.
: foo s" xyz" ;
s\" abc\{foo}def" type
displays abcxyzdef
As with SUBSTITUTE it can be an alternative to EXECUTE-PARSING e.g.
: $define ( caddr1 u1 caddr2 u2 -- )
s\" s\\\" \\{noop} \\{noop}\" evaluate" evaluate
;
: $: s" :" $define ;
s" foo" $: 123 . ;
defines foo which, when executed, displays 123
It is not the intention of this post to belittle EXECUTE-PARSING, I'm
just using examples to show the versatility of the extension. In fact
EXECUTE-PARSING can even be defined using this extended S\" e.g.
: execute-parsing ( ... caddr u xt -- )
s\" -rot s\\\" execute \\{noop}\" evaluate" evaluate
;
Which is not be very readable but is far more concise than the usual
definition. Usage e.g.
1234 s" bar" ' constant execute-parsing
bar .
displays 1234
To make the definitions like EXECUTE-PARSING more readable and easier to
write it may be worth adding two more escapes to S\" e.g.
\[...] to copy a literal string
\s to use the string on top of the stack, this replaces \{noop}
Then the above becomes (untested)
: execute-parsing ( ... caddr u xt -- )
s\" -rot \[s\" execute \s"] evaluate" evaluate
;
Other uses might be to insert UTF-8 sequences into strings
My conclusion is that trivial extensions to SUBSTITUTE and S\" make them
far more versatile and that those to S\" probably remove the need for
SUBSTITUTE and friends entirely.
Opinions please.
--
Gerry
[toc] | [next] | [standalone]
| From | Alex McDonald <blog@rivadpm.com> |
|---|---|
| Date | 2012-11-28 12:41 -0800 |
| Message-ID | <b688a7ef-a4f4-4e89-b5cc-ce615b9ffd1f@bq2g2000vbb.googlegroups.com> |
| In reply to | #17649 |
On Nov 28, 8:18 pm, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
wrote:
> I've just added the Forth 200X words S\" and SUBSTITUTE to my Forth
> system with an extension that I've found useful in other contexts. This
> extension is the ability to execute a named Forth word in the string
> being processed by S\" and SUBSTITUTE. Such Forth words return a (caddr
> u) string that is inserted into the result string. At the point the
> Forth word is executed the stack is cleared of the S\" and SUBSTITUTE
> working data so that the Forth word has access to user data on the
> stack. This provides the ability to convert numbers into particular
> formats and insert them into the resulting string.
>
> In the case of SUBSTITUTE this requires no additional syntax, the name
> of the Forth word is bracketed by % characters. The implementation has
> to be extended to execute any Forth word, not just replacement names as
> well as ensuring the stack is relatively empty. e.g.
>
> : foo s" bar" ;
> s" blah blah %foo% blah" buf 128 substitute
> will insert the string "bar" into the resulting string.
>
> This reduces the need for the word REPLACES
>
> Another example shows that it provides an alternative to EXECUTE-PARSING
> e.g.
>
> : noop ( -- ) ;
> : $define ( caddr1 u1 caddr2 u2 -- )
> s" %noop% %noop%" buf 80 substitute if evaluate then
> ;
> : $: s" :" $define ; \ $: same as :name
> s" bar" $: 456 . ;
> bar
> displays 456
>
> Of course this can also be done with the standard definition of
> SUBSTITUTE, but is awkward as REPLACES has to be used.
>
> Moving on to S\" the extension requires:
> - an extension to the syntax, I use an extra escape e.g. \{foo}
> - S\" must be usable in interpretation mode and at run-time
> - user arguments to be made available to the called word
> - preferably words affecting transient areas do not affect the S\"
> buffer and vice versa
> e.g.
>
> : foo s" xyz" ;
> s\" abc\{foo}def" type
> displays abcxyzdef
>
> As with SUBSTITUTE it can be an alternative to EXECUTE-PARSING e.g.
>
> : $define ( caddr1 u1 caddr2 u2 -- )
> s\" s\\\" \\{noop} \\{noop}\" evaluate" evaluate
> ;
> : $: s" :" $define ;
> s" foo" $: 123 . ;
>
> defines foo which, when executed, displays 123
>
> It is not the intention of this post to belittle EXECUTE-PARSING, I'm
> just using examples to show the versatility of the extension. In fact
> EXECUTE-PARSING can even be defined using this extended S\" e.g.
>
> : execute-parsing ( ... caddr u xt -- )
> s\" -rot s\\\" execute \\{noop}\" evaluate" evaluate
> ;
>
> Which is not be very readable but is far more concise than the usual
> definition. Usage e.g.
>
> 1234 s" bar" ' constant execute-parsing
> bar .
> displays 1234
>
> To make the definitions like EXECUTE-PARSING more readable and easier to
> write it may be worth adding two more escapes to S\" e.g.
> \[...] to copy a literal string
> \s to use the string on top of the stack, this replaces \{noop}
>
> Then the above becomes (untested)
> : execute-parsing ( ... caddr u xt -- )
> s\" -rot \[s\" execute \s"] evaluate" evaluate
> ;
Very neat, and very versatile too.
>
> Other uses might be to insert UTF-8 sequences into strings
>
> My conclusion is that trivial extensions to SUBSTITUTE and S\" make them
> far more versatile and that those to S\" probably remove the need for
> SUBSTITUTE and friends entirely.
>
> Opinions please.
>
> --
> Gerry
I've added \uxxxx to my S\" to support Unicode. Do you mean UTF-8 or
Unicode?
s\" \u017D" type Ž ok
where 017D is the unicode; the UTF-8 is the transformation;
s\" \u017D" dump
167371 | C5 BD |..| ok
which could be inserted with s\" \xC5\xBD"
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2012-11-28 22:59 +0000 |
| Message-ID | <k9650k$g50$1@dont-email.me> |
| In reply to | #17650 |
Damn, I've done it again, hit 'Reply' in Thunderbird instead of
'Followup'. Sorry for sending it to your email address.
On 28/11/2012 20:41, Alex McDonald wrote:
> On Nov 28, 8:18 pm, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
[...]
>
> I've added \uxxxx to my S\" to support Unicode. Do you mean UTF-8 or
> Unicode?
>
> s\" \u017D" type Ž ok
>
> where 017D is the unicode; the UTF-8 is the transformation;
>
> s\" \u017D" dump
> 167371 | C5 BD |..| ok
>
> which could be inserted with s\" \xC5\xBD"
>
I don't know, my ignorance on Unicode & UTF-8 is almost total. I just
remember someone complaining that they couldn't insert a 2 byte
sequence in as you've added above. I was just thinking that if they
wanted \xC5\xBD in several strings they could define something like
: funny-Z s" \xC5\xBD" ;
and refer to it with s\" ...\{funny-Z}..." whenever they needed it.
Just factoring it really.
--
Gerry
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2012-11-29 13:57 +0000 |
| Message-ID | <2012Nov29.145701@mips.complang.tuwien.ac.at> |
| In reply to | #17649 |
Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
>In the case of SUBSTITUTE this requires no additional syntax, the name
>of the Forth word is bracketed by % characters. The implementation has
>to be extended to execute any Forth word, not just replacement names as
>well as ensuring the stack is relatively empty. e.g.
>
>: foo s" bar" ;
>s" blah blah %foo% blah" buf 128 substitute
>will insert the string "bar" into the resulting string.
>
>This reduces the need for the word REPLACES
What is the search order for the replacements?
Another alternative for this kind of stuff is >STRING-EXECUTE:
: >string-execute ( ... xt -- ... addr u )
\G execute xt while the standard output (TYPE, EMIT, and everything
\G that uses them) is redirected to a string. The resulting string
\G is addr u, which is in ALLOCATEd memory; it is the
\G responsibility of the caller of >STRING-EXECUTE to FREE this
\G string.
Your example could be replaced with
:noname ." blah blah " foo type ." blah" ; >string-execute
>Another example shows that it provides an alternative to EXECUTE-PARSING
>e.g.
>
>: noop ( -- ) ;
>: $define ( caddr1 u1 caddr2 u2 -- )
> s" %noop% %noop%" buf 80 substitute if evaluate then
>;
>: $: s" :" $define ; \ $: same as :name
>s" bar" $: 456 . ;
>bar
>displays 456
This has the problem of most EVALUATE-based approaches: It binds ":"
at run-time, so it requires ":" to be visible at run-time and be the
same ":" as you intended, contrary to the usual Forth approach of
early binding. EXECUTE-PARSING avoids this problem by passing an xt,
and the name->xt binding can (and usually does) happen early.
>It is not the intention of this post to belittle EXECUTE-PARSING, I'm
>just using examples to show the versatility of the extension. In fact
>EXECUTE-PARSING can even be defined using this extended S\" e.g.
>
>: execute-parsing ( ... caddr u xt -- )
> s\" -rot s\\\" execute \\{noop}\" evaluate" evaluate
>;
Again, this relies on EXECUTE, S", and EVALUATE being visible and the
intended one at run-time, if I understand this correctly. Take a look
at the lengths that I went to in the Forth-94 implemenation of
EXECUTE-PARSING to ensure that the one word it binds at run-time is
indeed the word I intend to use.
>Which is not be very readable but is far more concise than the usual
>definition.
Yes, if we skip correctness in corner cases, the Forth-94 definition
will also be more concise.
>Other uses might be to insert UTF-8 sequences into strings
From a later message I gather that you want to refer to non-ASCII
Unicode characters by name. I think a good way to refer to Unicode
characters is by just putting them in as literal characters. I.e., if
you want to have "a" in the string, just put an "a" there, not
"\{latin-a}" or whatever; with xchars, you can do it with Unicode
characters, too. Of course, it requires you to use an editor that can
grok and display Unicode, but that's not a big issue these days.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2012: http://www.euroforth.org/ef12/
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2012-11-29 17:12 +0000 |
| Message-ID | <k9851n$nug$1@dont-email.me> |
| In reply to | #17694 |
On 29/11/2012 13:57, Anton Ertl wrote:
> Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
>> In the case of SUBSTITUTE this requires no additional syntax, the name
>> of the Forth word is bracketed by % characters. The implementation has
>> to be extended to execute any Forth word, not just replacement names as
>> well as ensuring the stack is relatively empty. e.g.
>>
>> : foo s" bar" ;
>> s" blah blah %foo% blah" buf 128 substitute
>> will insert the string "bar" into the resulting string.
>>
>> This reduces the need for the word REPLACES
>
> What is the search order for the replacements?
>
In my implementation it's the substitution wordlist then the current
search-order, not just a substitution wordlist as in the reference
implementation of SUBSTITUTE & REPLACES
> Another alternative for this kind of stuff is >STRING-EXECUTE:
>
> : >string-execute ( ... xt -- ... addr u )
> \G execute xt while the standard output (TYPE, EMIT, and everything
> \G that uses them) is redirected to a string. The resulting string
> \G is addr u, which is in ALLOCATEd memory; it is the
> \G responsibility of the caller of >STRING-EXECUTE to FREE this
> \G string.
>
> Your example could be replaced with
>
> :noname ." blah blah " foo type ." blah" ; >string-execute
>
OK but presumably it's GForth specific and requires a bigger change to
the system than a trivial extension to a single word. Redirecting output
is very useful, has any effort been made towards standardising that?
>> Another example shows that it provides an alternative to EXECUTE-PARSING
>> e.g.
>>
>> : noop ( -- ) ;
>> : $define ( caddr1 u1 caddr2 u2 -- )
>> s" %noop% %noop%" buf 80 substitute if evaluate then
>> ;
>> : $: s" :" $define ; \ $: same as :name
>> s" bar" $: 456 . ;
>> bar
>> displays 456
>
> This has the problem of most EVALUATE-based approaches: It binds ":"
> at run-time, so it requires ":" to be visible at run-time and be the
> same ":" as you intended, contrary to the usual Forth approach of
> early binding. EXECUTE-PARSING avoids this problem by passing an xt,
> and the name->xt binding can (and usually does) happen early.
Yes that's the usual objection but ISTM more of a theoretical problem
than a problem in practice (for me at least). Anyway I was only using
that as an example rather than a replacement for EXECUTE-PARSING.
>
>> It is not the intention of this post to belittle EXECUTE-PARSING, I'm
>> just using examples to show the versatility of the extension. In fact
>> EXECUTE-PARSING can even be defined using this extended S\" e.g.
>>
>> : execute-parsing ( ... caddr u xt -- )
>> s\" -rot s\\\" execute \\{noop}\" evaluate" evaluate
>> ;
>
> Again, this relies on EXECUTE, S", and EVALUATE being visible and the
> intended one at run-time, if I understand this correctly. Take a look
> at the lengths that I went to in the Forth-94 implemenation of
> EXECUTE-PARSING to ensure that the one word it binds at run-time is
> indeed the word I intend to use.
>
>> Which is not be very readable but is far more concise than the usual
>> definition.
>
> Yes, if we skip correctness in corner cases, the Forth-94 definition
> will also be more concise.
>
Of course, but you would still have to allocate space & copy strings to
it rather than have it be done for you.
--
Gerry
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.forth
csiph-web