This string, an enhanced comment, is consumed (gets printed)
The sound of a cow "MOO"
This string with '"bar" (foo)' is compiled
om OVER MINUS
String fetched from comment
Comment string
( This string is a simple comment)
( The comment can be enhanced to include parethises in the string)
( This string is an (enhanced) comment)
Accessing enhanced comments
A comment string, when interpreting, can be found in the
input buffer. It can be accessed and used if it's consumed
or moved before the end of line.
.( ( ccc<)> -- ) Print enhanced comment string
cr i. .( This string, an enhanced comment, is consumed (gets printed))
This string, an enhanced comment, is consumed (gets printed)
s( ( ccc<)> -- s ) Save enhanced comment string
s( "MOO") s( The sound of a cow)
The above strings are saved in a ring buffer and
return string references to be used soon.
cr i. ul( tell ) tab tell
The sound of a cow "MOO"
,( ( ccc<)> -- ) Compile enhanced comment string
here ,( This string with '"bar" (foo)' is compiled)
here om cr i. type
This string with '"bar" (foo)' is compiled
...
String fetched from comment
Comment string
( This string is a simple comment)
( The comment can be enhanced to include parethises in the string)
( This string is an (enhanced) comment)
second only to premature optimisation and goto's.
Buddha said, om is boundless wisdom. ;-)
For us poor novices, could you please share some Forth code
to show how you have implemented your novel nestable comments?
Not understanding where it fits in. Is this meant to be in lieu of
." ," S" etc ?
Nested comments is a source of a lot of evil, second only to
premature optimisation and goto's.
...
The enhanced comment is more robust than the existing string operators
that you show in that any mix of printable characters can be contained
in the comment and string operators that base on it. No breaking up
text nor escaping characters needed (by the Forth):
.( The function("bar") char ) emit .( is to be used) \ standard, bah
.( The function("bar") is to be used) \ enhanced, ok
." Jack said " char " emit ." boo" char " emit . \ standard, bah
.( Jack said "boo") \ enhanced, ok
@( echo -e "Hello World\!") /sys \ enhanced, ok
I am not a fan of S\" TYPE as it tends to move the parsing and
interpretation problems to parts of the code / library that may
not be prepared for it, or where it would be quite an overhead
to anticipate every present and future possibility.
For instance,
having a backspace in a string has no obvious meaning in most
of the system code
and an application can simply redefine BS
to have it do what is necessary.
...
I am not a fan of S\" TYPE as it tends to move the parsing and
interpretation problems to parts of the code / library that may
not be prepared for it, or where it would be quite an overhead
to anticipate every present and future possibility.
second only to premature optimisation and goto's.
How to code a state-machine without goto's?
-marcel
albeit not idiot-proof ... ( ) needs to be balanced.
For me the other issue was non-graphic characters. Unable to avoid it
I adopted a simplified form of 200x escapes whereby " becomes \22 .
On 04/03/2025 15:55, mhx wrote:...
How to code a state-machine without goto's?
But you probably knew about that so why doesn't it count as gotoless?
Does it make a difference in understandability whether you implement a
state transition as "goto state123" or in the Dijkstra-compatible
"state = state123"? So why should I care whether it is gotoless?
.( Use this when () are balanced )
@( Use this when "foo(" left () unblanced)) 1- type
foo (bar) "bat("
foo (bar) "bat)"--
On Wed, 5 Mar 2025 16:50:13 +0000, Anton Ertl wrote:
Does it make a difference in understandability whether you implement a
state transition as "goto state123" or in the Dijkstra-compatible
"state = state123"? So why should I care whether it is gotoless?
The syntax is fine (the one is just as unreadable as the other) but what >about the implementation?
I couldn't locate the pertinent subject at >https://www.cs.utexas.edu/~EWD/welcome.html, do you have a hint?
Gerry Jackson <do-not-use@swldwa.uk> writes:
On 04/03/2025 15:55, mhx wrote:...
How to code a state-machine without goto's?
But you probably knew about that so why doesn't it count as gotoless?
Does it make a difference in understandability whether you implement a
state transition as "goto state123" or in the Dijkstra-compatible
"state = state123"? So why should I care whether it is gotoless?
I couldn't locate the pertinent subject at >>https://www.cs.utexas.edu/~EWD/welcome.html, do you have a hint?
https://dl.acm.org/doi/10.1145/362929.362947
On 5/03/2025 6:57 pm, mhx wrote:
...
I am not a fan of S\" TYPE as it tends to move the parsing and
interpretation problems to parts of the code / library that may
not be prepared for it, or where it would be quite an overhead
to anticipate every present and future possibility.
What finally drove me to implement escapes was this:
: RC$ ( -- a n ) \ row/col string
bin? if s" \00" end s" 000" drop #asc ;
Every other way of doing it looked like a hack. ... And it solved
the embedded double-quote problem.
I couldn't locate the pertinent subject at >>>https://www.cs.utexas.edu/~EWD/welcome.html, do you have a hint?
https://dl.acm.org/doi/10.1145/362929.362947
That was a nice read! I see Dijkstra's argument that a goto as
we know it is lacking necessary functionality.
However, a state machine has well defined rules based on a
state's stored information and its inputs, causing it to go to
another well-defined state while generating outputs. In that
context a goto is harmless and merely serves as a crutch when
there are not enough computing nodes to serve all states in
parallel. How to make such an efficient crutch in Forth?
-marcel
In article <74a5b61b65b89c594e3f653a0266dc874d6cc739@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 5/03/2025 6:57 pm, mhx wrote:
...
I am not a fan of S\" TYPE as it tends to move the parsing and
interpretation problems to parts of the code / library that may
not be prepared for it, or where it would be quite an overhead
to anticipate every present and future possibility.
What finally drove me to implement escapes was this:
: RC$ ( -- a n ) \ row/col string
bin? if s" \00" end s" 000" drop #asc ;
Every other way of doing it looked like a hack. ... And it solved
the embedded double-quote problem.
I don't understand this.
"every other way to do what?".
( -- a n ) i s not a specification.
If you introduce a word like RC$ tell us what it is supposed to
do.
However, a state machine has well defined rules based on a
state's stored information and its inputs, causing it to go to
another well-defined state while generating outputs. In that
context a goto is harmless and merely serves as a crutch when
there are not enough computing nodes to serve all states in
parallel. How to make such an efficient crutch in Forth?
String fetched from comment
Notes
i. Print "-->"
ul(...) Underline output of enclosed code
tell COUNT TYPE
om OVER MINUS
-fin-
Note The underline didn't show in the post.
mhx@iae.nl (mhx) writes:
However, a state machine has well defined rules based on a
state's stored information and its inputs, causing it to go to
another well-defined state while generating outputs. In that
context a goto is harmless and merely serves as a crutch when
there are not enough computing nodes to serve all states in
parallel. How to make such an efficient crutch in Forth?
You lost me. Why would one "serve all states in parallel"?
mhx@iae.nl (mhx) writes:
However, a state machine has well defined rules based on a
state's stored information and its inputs, causing it to go to
another well-defined state while generating outputs. In that
context a goto is harmless and merely serves as a crutch when
there are not enough computing nodes to serve all states in
parallel. How to make such an efficient crutch in Forth?
You lost me. Why would one "serve all states in parallel"?
Anyway, if the question is how to implement a state machine
efficiently in Forth, one answer is to stay at a higher, more
structured level of abstraction or recreate it from the state machine.
E.g., don't transform a regular expression into a (indeterministic or deterministic) finite state machine, but instead interpret it directly (that's what Bernd Paysan's regexp.fs does). Or instead of
transforming a grammar into a push-down automaton, transform it into a structured Forth program (like Gray does).
If you cannot do that, in standard Forth you don't really have good
options. The best is probably to have the current state on the stack (probably in the form of the address of an array indexed with the
input (or whatever causes a state change) and containing the potential
next states at the appropriate elements.
In a particular implementation, you can do more, including goto-like
things. What I would do then is have a colon definition per state,
and do the transition to the next state as tail call. Have some
efficient forward-tail-call mechanism to allow calling states where
the definition comes later. Gforth has a clever FORWARD, but for now
that does not do tail-calls.
- anton
mhx@iae.nl (mhx) writes:
I am not a fan of S\" TYPE as it tends to move the parsing and >>interpretation problems to parts of the code / library that may
not be prepared for it, or where it would be quite an overhead
to anticipate every present and future possibility.
Can you elaborate on that, especially about the overhead?
For instance,
having a backspace in a string has no obvious meaning in most
of the system code
Nobody forces you you to use \b if it's inappropriate.
and an application can simply redefine BS
to have it do what is necessary.
One would have to define BS first; otherwise you cannot redefine it.
What is BS supposed to do, and what is redefining BS supposed to
achieve?
- anton
Use of a wordlist, whose wid is held in an immediate constant, enables
easy linkage between states at compile time, eg a typical state action
in outline is:
:noname <action>
if state-x [ >order ] next-state [ previous ]
else state-y [ >order ] next-state [ previous ]
; this-state >order to next-state previous
Disadvantages are:
- the Forth code doesn't give much idea of the overall operation of the
FSM (probably true for FSMs in general)
: run-fsm ( ad xt -- ) begin dup while execute repeat 2drop ;
Gerry Jackson <do-not-use@swldwa.uk> writes::) Well if you've never encountered this in (how many years has GForth
Use of a wordlist, whose wid is held in an immediate constant, enables
easy linkage between states at compile time, eg a typical state action
in outline is:
:noname <action>
if state-x [ >order ] next-state [ previous ]
else state-y [ >order ] next-state [ previous ]
; this-state >order to next-state previous
It means that Gforth will have to improve its SEE in order to point
out the differences between the different NEXT-STATEs. Currently I get:
/2 >order ok
next-state xt-see
noname :
dup @ #1 and
IF next-state
ELSE next-state
THEN ; ok
Disadvantages are:
- the Forth code doesn't give much idea of the overall operation of the
FSM (probably true for FSMs in general)
That's definitely the case here.
IIRC for Michael Gassanenko it was a
demonstration of filtering and backtracking,
but it's unclear to me
how that transfers to FSMs.
Anyway, let's look at the core:
: run-fsm ( ad xt -- ) begin dup while execute repeat 2drop ;
This means that every state has to return to this loop to dispatch the
next one. Now Gforth (development) has EXECUTE-EXIT, which allows tail-calling the next state for better efficiency.
I have worked out an example: https://www.complang.tuwien.ac.at/forth/programs/fsm-ae.4th
- anton--
Here are the results on a Zen4:...
loop plain optimized implementation variant
1_278_763_454 1_175_241_846 1_175_505_964 cycles
3_651_376_357 2_441_376_030 2_045_832_844 instructions
For now I don't see why the whole thing takes so many cycles. I'll
take a closer look later.
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 1,030 |
Nodes: | 10 (1 / 9) |
Uptime: | 22:45:24 |
Calls: | 13,346 |
Calls today: | 3 |
Files: | 186,574 |
D/L today: |
1,683 files (457M bytes) |
Messages: | 3,357,683 |