Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #17649 > unrolled thread

Forth 200X words S\" and SUBSTITUTE

Started byGerry Jackson <gerry@jackson9000.fsnet.co.uk>
First post2012-11-28 20:18 +0000
Last post2012-11-29 17:12 +0000
Articles 5 — 3 participants

Back to article view | Back to comp.lang.forth


Contents

  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

#17649 — Forth 200X words S\" and SUBSTITUTE

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2012-11-28 20:18 +0000
SubjectForth 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]


#17650

FromAlex McDonald <blog@rivadpm.com>
Date2012-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]


#17653

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2012-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]


#17694

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2012-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]


#17698

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2012-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