Hi,S <0> ok
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.
On Thursday, October 6, 2022 at 2:18:58 PM UTC+2, Jose Morales wrote:An example of text processing in Forth by Sam Falvo II. https://www.youtube.com/watch?v=mvrE2ZGe-rs
Hi,
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.S <0> ok
ok
: splitword here >r 2swap
begin compiled
2dup 2,
2over search
while dup negate here 2 cells - +!
2over nip
repeat
2drop 2drop
here over - ( tokens length )dup negate allot
2 cells / ;
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?
On Thursday, October 6, 2022 at 9:25:47 AM UTC-5, jem...@gmail.com wrote:
On Thursday, October 6, 2022 at 2:18:58 PM UTC+2, Jose Morales wrote:
Hi,
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.S <0> ok
ok
: splitword here >r 2swap
begin compiled
2dup 2,
2over search
while dup negate here 2 cells - +!
2over nip
repeat
2drop 2drop
here over - ( tokens length )dup negate allot
2 cells / ;
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?An example of text processing in Forth by Sam Falvo II. https://www.youtube.com/watch?v=mvrE2ZGe-rs
On Thursday, October 6, 2022 at 9:25:47 AM UTC-5, jem...@gmail.com wrote:
On Thursday, October 6, 2022 at 2:18:58 PM UTC+2, Jose Morales wrote:
Hi,
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.S <0> ok
ok
: splitword here >r 2swap
begin compiled
2dup 2,
2over search
while dup negate here 2 cells - +!
2over nip
repeat
2drop 2drop
here over - ( tokens length )dup negate allot
2 cells / ;
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?An example of text processing in Forth by Sam Falvo II. https://www.youtube.com/watch?v=mvrE2ZGe-rs
On Thursday, October 6, 2022 at 9:25:47 AM UTC-5, jem...@gmail.com wrote:
On Thursday, October 6, 2022 at 2:18:58 PM UTC+2, Jose Morales wrote:
Hi,
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.S <0> ok
ok
: splitword here >r 2swap
begin compiled
2dup 2,
2over search
while dup negate here 2 cells - +!
2over nip
repeat
2drop 2drop
here over - ( tokens length )dup negate allot
2 cells / ;
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?An example of text processing in Forth by Sam Falvo II. https://www.youtube.com/watch?v=mvrE2ZGe-rs
...
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?
Hi,
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.
On 7/10/2022 1:25 am, Jose Morales wrote:
...
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?Not sure what you mean but my 'goto' word is SPLIT :
\ Split string at character leaving first on top
: SPLIT ( a u c -- a2 u2 a3 u3 )
r 2dup r> scan 2swap 2 pick - ;
I then use BL SKIP BL SPLIT in a loop to extract and process the tokens
one by one.
On Thursday, October 6, 2022 at 2:18:58 PM UTC+2, Jose Morales wrote:
Hi,S <0> ok
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.
ok
: splitword here >r 2swap
begin compiled
2dup 2,
2over search
while dup negate here 2 cells - +!
2over nip
repeat
2drop 2drop
r> here over - ( tokens length )
dup negate allot
2 cells / ;
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?
On 06/10/2022 15:25, Jose Morales wrote:
On Thursday, October 6, 2022 at 2:18:58 PM UTC+2, Jose Morales wrote:
Hi,S <0> ok
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.
ok
: splitword here >r 2swap
begin compiled
2dup 2,
2over search
while dup negate here 2 cells - +!
2over nip
repeat
2drop 2drop
here over - ( tokens length )dup negate allot
2 cells / ;
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?A problem with using SEARCH to scan a string for single spaces is that
it will return zero length strings if more than one space occurs between
the words on the string being SEARCHed.
Instead of using SEARCH to scan a string you could use the definition of XT-SKIP at:
https://forth-standard.org/standard/core/PARSE-NAME
and use the definition of PARSE-NAME as a guide to scanning your source string.
Unfortunately PARSE-NAME only works on the input source line but can be
used directly. For example given these definitions to split and display
words in your test string:
: sw ( "str1" .. "strn" -- x 0 can un .. ca1 u1 )
parse-name 2>r r@
if recurse then
;
: .words ( x 0 can un .. ca1 u1 -- )
begin
dup
while
type dup if ." , " then
repeat 2drop
;
: split-words sw cr .words cr ;
\ Now try it on your test words
split-words G1 G100 S100
G1, G100, S100
ok
Which is probably not convenient in practice. A way around this is to
use a GForth word called EXECUTE-PARSING, for example using the above definitions for SW and .WORDS:
: split-words ['] sw execute-parsing ;
\ test it
s" G1 G100 S100" split-words cr .words cr
G1, G100, S100
ok
The advantage of using PARSE-NAME is that the Forth system text
interpreter does the scanning for you.
Unfortunately most Forth systems don't include EXECUTE-PARSING as it
isn't a standard word but a definition of it in standard Forth can be
found at: https://github.com/forthy42/gforth/blob/master/compat/execute-parsing.fs
Gerry Jackson schrieb am Dienstag, 11. Oktober 2022 um 13:22:43 UTC+2:
On 06/10/2022 15:25, Jose Morales wrote:
On Thursday, October 6, 2022 at 2:18:58 PM UTC+2, Jose Morales wrote:A problem with using SEARCH to scan a string for single spaces is that
Hi,S <0> ok
While in my learning Forth journey, I was looking at more functional use of the stack and how to manage common tasks like file parsing.
GCode seem like a good candidate to leverage to tackle other more complex file types.
Thanks,
Jose.
ok
: splitword here >r 2swap
begin compiled
2dup 2,
2over search
while dup negate here 2 cells - +!
2over nip
repeat
2drop 2drop
here over - ( tokens length )dup negate allot
2 cells / ;
: .tokens 1 ?do dup 2@ type ." , " cell+ cell+ loop 2@ type ;
s" G1 G100 S100" s" " splitword .tokens G1, G100, S100 ok
I found a good source in rosettacode, but is there any way to do this better, specially on a buffer rather than the dictionary?
it will return zero length strings if more than one space occurs between
the words on the string being SEARCHed.
Instead of using SEARCH to scan a string you could use the definition of
XT-SKIP at:
https://forth-standard.org/standard/core/PARSE-NAME
and use the definition of PARSE-NAME as a guide to scanning your source
string.
Unfortunately PARSE-NAME only works on the input source line but can be
used directly. For example given these definitions to split and display
words in your test string:
: sw ( "str1" .. "strn" -- x 0 can un .. ca1 u1 )
parse-name 2>r r@
if recurse then
;
: .words ( x 0 can un .. ca1 u1 -- )
begin
dup
while
type dup if ." , " then
repeat 2drop
;
: split-words sw cr .words cr ;
\ Now try it on your test words
split-words G1 G100 S100
G1, G100, S100
ok
Which is probably not convenient in practice. A way around this is to
use a GForth word called EXECUTE-PARSING, for example using the above
definitions for SW and .WORDS:
: split-words ['] sw execute-parsing ;
\ test it
s" G1 G100 S100" split-words cr .words cr
G1, G100, S100
ok
The advantage of using PARSE-NAME is that the Forth system text
interpreter does the scanning for you.
Unfortunately most Forth systems don't include EXECUTE-PARSING as it
isn't a standard word but a definition of it in standard Forth can be
found at:
https://github.com/forthy42/gforth/blob/master/compat/execute-parsing.fs
Why so complicated?
: PARSE-STRING \ ( a u -- a' u' ap up ) parse ws-delimited string within given string (a u)
BEGIN over c@ bl > 0= over and
WHILE 1- swap 1+ swap
REPEAT over >r
BEGIN over c@ bl > over and
WHILE 1- swap 1+ swap
REPEAT over r@ - r> swap ;
\ Test:
: STRING-EXTRACT \ ( a u -- )
BEGIN dup WHILE
parse-string cr type
REPEAT 2drop ;
S" Mary had a little lamb" STRING-EXTRACT
Mary
had
a
little
lamb ok
This solves a slightly different problem, it gets the first word,
displays it, then gets the second word and so on
Admittedly the final result is the same but I don't know if the OP had a
good reason for doing it the way he did.
He seemed concerned about using dataspace to save the (ca u)'s of the
words to be displayed - my solution shows they can be stacked and
recursion is a good way to leave them in the correct order on the stack
for display.
Whether using recursion and EXECUTE-PARSING is a complicated solution is
open to argument. Certainly EXECUTE-PARSING is complicated to implement
but has a well tested solution in standard Forth and is easy to use.
Anyway an equivalent to your solution is:
: string-extract
begin
parse-name dup
while
cr type
repeat 2drop
;
----
Gerry
Why so complicated?I replicated the functionality of the OPs solution which was to:
- extract all the words from the string saving the (ca u)s in dataspace
- then to display them in the order in which they occur in the original string on the same line with commas between them.
: PARSE-STRING \ ( a u -- a' u' ap up ) parse ws-delimited string within given string (a u)
BEGIN over c@ bl > 0= over and
WHILE 1- swap 1+ swap
REPEAT over >r
BEGIN over c@ bl > over and
WHILE 1- swap 1+ swap
REPEAT over r@ - r> swap ;
\ Test:
: STRING-EXTRACT \ ( a u -- )
BEGIN dup WHILE
parse-string cr type
REPEAT 2drop ;
S" Mary had a little lamb" STRING-EXTRACT
Mary
had
a
little
lamb ok
This solves a slightly different problem, it gets the first word,
displays it, then gets the second word and so on
Admittedly the final result is the same but I don't know if the OP had a
good reason for doing it the way he did.
He seemed concerned about using dataspace to save the (ca u)'s of the
words to be displayed - my solution shows they can be stacked and
recursion is a good way to leave them in the correct order on the stack
for display.
Whether using recursion and EXECUTE-PARSING is a complicated solution is
open to argument. Certainly EXECUTE-PARSING is complicated to implement
but has a well tested solution in standard Forth and is easy to use.
Anyway an equivalent to your solution is:
: string-extract
begin
parse-name dup
while
cr type
repeat 2drop
;
s" Mary had a little lamb" ' string-extract execute-parsing
Mary
had
a
little
lamb ok
No need for your PARSE-STRING, PARSE-NAME does the job.
But I forget, real Forthers implement everything from scratch :)
In article <ti5vj2$1e3v5$1...@dont-email.me>,
Gerry Jackson <do-no...@swldwa.uk> wrote:
<SNIP>
This solves a slightly different problem, it gets the first word,
displays it, then gets the second word and so on
Admittedly the final result is the same but I don't know if the OP had a >good reason for doing it the way he did.
He seemed concerned about using dataspace to save the (ca u)'s of the
words to be displayed - my solution shows they can be stacked and
recursion is a good way to leave them in the correct order on the stack
for display.
Whether using recursion and EXECUTE-PARSING is a complicated solution is >open to argument. Certainly EXECUTE-PARSING is complicated to implement: EXECUTE-PARSING ROT ROT SAVE SET-SRC CATCH RESTORE THROW ;
but has a well tested solution in standard Forth and is easy to use. EXECUTE-PARSING is easy to define (in ciforth at least)
Much easier is to use SAVE / RESTORE and SET-SRC itself and
inside do whatever you want to do .
SAVE RESTORE is similar to the clunky saving and restoring
the current input stream with SAVE-INPUT but doesn't leave clutter on the data stack.
SET-SRC make the string passed to it the input stream and
exits at the end. Much easier to use than EXECUTE-PARSING
: EVALUATE SAVE SET-SRC 'INTERPRET CATCH RESTORE THROW ;
without error detection it is
: EVALUATE SAVE SET-SRC INTERPRET RESTORE ;
But I forget, real Forthers implement everything from scratch:)That's it of course, when it is worthwhile.;-)
AFAICS the proposed EXECUTE-PARSING moves strings around and
even needs an extra wordlist
. PARSE-NAME moves >IN around.
Dumb little PARSE-STRING does nothing of that sort.
AFAICS the proposed EXECUTE-PARSING moves strings around and
even needs an extra wordlist.
"minf...@arcor.de" <minf...@arcor.de> writes:
AFAICS the proposed EXECUTE-PARSING moves strings around andApparently what you se is the implementation in standard Forth, which
even needs an extra wordlist.
has to implement EXECUTE-PARSING in terms of EVALUATE instead of the
other way round. A proper implementation of EXECUTE-PARSING that uses
carnal knowledge about the system does not move strings around and
does not involve any extra wordlist.
How to get there: Take your existing implementation of EVALUATE, but
instead of calling the text interpreter inside it, call CATCH; you
probably have to do some stack shuffling to get the xt to the CATCH
and to avoid having internal stack items visible when performing the
CATCH.
Once you have that, the implementation of EVALUATE becomes trivial.
In Gforth it is:
: evaluate ( ... addr u -- ... ) \ core,block
['] interpret2 execute-parsing ;
Where INTERPRET2 is a variant of interpret that includes supports for backtraces:
: interpret2 ['] interpret bt-rp0-wrapper ;
Anton Ertl schrieb am Mittwoch, 12. Oktober 2022 um 18:36:24 UTC+2:
"minf...@arcor.de" <minf...@arcor.de> writes:
AFAICS the proposed EXECUTE-PARSING moves strings around andApparently what you se is the implementation in standard Forth, which
even needs an extra wordlist.
has to implement EXECUTE-PARSING in terms of EVALUATE instead of the
other way round. A proper implementation of EXECUTE-PARSING that uses
carnal knowledge about the system does not move strings around and
does not involve any extra wordlist.
How to get there: Take your existing implementation of EVALUATE, but
instead of calling the text interpreter inside it, call CATCH; you
probably have to do some stack shuffling to get the xt to the CATCH
and to avoid having internal stack items visible when performing the
CATCH.
Once you have that, the implementation of EVALUATE becomes trivial.
In Gforth it is:
: evaluate ( ... addr u -- ... ) \ core,block
['] interpret2 execute-parsing ;
Where INTERPRET2 is a variant of interpret that includes supports for
backtraces:
: interpret2 ['] interpret bt-rp0-wrapper ;
I really appreciate your insights. Actually my EVALUATE does already use
.. ['] interpret CATCH .. internally; moving that xt upfront would be
trivial indeed.
Now I am waiting for a use case in my work. ;-)
On 12/10/2022 13:03, minf...@arcor.de wrote:
But I forget, real Forthers implement everything from scratch:)That's it of course, when it is worthwhile.;-)
AFAICS the proposed EXECUTE-PARSING moves strings around and
even needs an extra wordlist
also allocating and freeing memory.
. PARSE-NAME moves >IN around.
Yes but when EXECUTE-PARSING is built into a system it should be much
simpler with none of the above being necessary e.g. in my system
--<SNIP>
Gerry
In article <ti6m5r$1hc6c$1@dont-email.me>,
Gerry Jackson <do-not-use@swldwa.uk> wrote:
On 12/10/2022 13:03, minf...@arcor.de wrote:
But I forget, real Forthers implement everything from scratch:)That's it of course, when it is worthwhile.;-)
AFAICS the proposed EXECUTE-PARSING moves strings around and
even needs an extra wordlist
also allocating and freeing memory.
Not in my book. Parsing is in the core. ALLOCATE is a loaded
facility.
. PARSE-NAME moves >IN around.
Yes but when EXECUTE-PARSING is built into a system it should be much
simpler with none of the above being necessary e.g. in my system
Parsing moves the parse pointer around. Big deal. I have PP instead
of >IN. All of this is totally invisible, if you have the correct
parsing tools.
On 13/10/2022 9:25 pm, albert wrote:
In article <ti6m5r$1hc6c$1...@dont-email.me>,
Gerry Jackson <do-no...@swldwa.uk> wrote:
On 12/10/2022 13:03, minf...@arcor.de wrote:
But I forget, real Forthers implement everything from scratch:)That's it of course, when it is worthwhile.;-)
AFAICS the proposed EXECUTE-PARSING moves strings around and
even needs an extra wordlist
also allocating and freeing memory.
Not in my book. Parsing is in the core. ALLOCATE is a loaded
facility.
. PARSE-NAME moves >IN around.
Yes but when EXECUTE-PARSING is built into a system it should be much
simpler with none of the above being necessary e.g. in my system
Parsing moves the parse pointer around. Big deal. I have PP insteadOccam's razor: Given two adequate solutions to a problem, take the least resource-intensive one.
of >IN. All of this is totally invisible, if you have the correct
parsing tools.
In article <ti6m5r$1hc6c$1...@dont-email.me>,
Gerry Jackson <do-no...@swldwa.uk> wrote:
On 12/10/2022 13:03, minf...@arcor.de wrote:
But I forget, real Forthers implement everything from scratch:)That's it of course, when it is worthwhile.;-)
AFAICS the proposed EXECUTE-PARSING moves strings around and
even needs an extra wordlist
also allocating and freeing memory.Not in my book. Parsing is in the core. ALLOCATE is a loaded
facility.
. PARSE-NAME moves >IN around.
Yes but when EXECUTE-PARSING is built into a system it should be much >simpler with none of the above being necessary e.g. in my systemParsing moves the parse pointer around. Big deal. I have PP instead
of >IN. All of this is totally invisible, if you have the correct
parsing tools.
Good. The originally proposed EXECUTE-PARSING should also be surrounded
by CATCH .. THROW because it does EVALUATE under the hood and the input >source is thus changed twice.
On Thursday, October 13, 2022 at 12:43:50 PM UTC+2, dxforth wrote:
On 13/10/2022 9:25 pm, albert wrote:
In article <ti6m5r$1hc6c$1...@dont-email.me>,Occam's razor: Given two adequate solutions to a problem, take the least
Gerry Jackson <do-no...@swldwa.uk> wrote:
On 12/10/2022 13:03, minf...@arcor.de wrote:
But I forget, real Forthers implement everything from scratch:)That's it of course, when it is worthwhile.;-)
AFAICS the proposed EXECUTE-PARSING moves strings around and
even needs an extra wordlist
also allocating and freeing memory.
Not in my book. Parsing is in the core. ALLOCATE is a loaded
facility.
. PARSE-NAME moves >IN around.
Yes but when EXECUTE-PARSING is built into a system it should be much
simpler with none of the above being necessary e.g. in my system
Parsing moves the parse pointer around. Big deal. I have PP instead
of >IN. All of this is totally invisible, if you have the correct
parsing tools.
resource-intensive one.
That is not what Occam said :--)
On 13/10/2022 11:08 pm, Marcel Hendrix wrote:
On Thursday, October 13, 2022 at 12:43:50 PM UTC+2, dxforth wrote:
Occam's razor: Given two adequate solutions to a problem, take the least >>> resource-intensive one.
That is not what Occam said :--)
You're right. It was Brodie applying it. Ref: 'Thinking FORTH' p.60
dxforth <dxforth@gmail.com> writes:
On 13/10/2022 11:08 pm, Marcel Hendrix wrote:
On Thursday, October 13, 2022 at 12:43:50 PM UTC+2, dxforth wrote:
Occam's razor: Given two adequate solutions to a problem, take the least >>>> resource-intensive one.
That is not what Occam said :--)
You're right. It was Brodie applying it. Ref: 'Thinking FORTH' p.60
Nope. On p. 60 Brodie claims that the origin is an old saying, and
gives this wording:
|Given two solutions to a problem, the correct one is the simpler.
On p. 61 the illustration is captioned with a slight variation:
|Given two adequate solutions, the correct one is the simpler.
The thing about "the least resource-intensive one" seems to be a
dxforth interpretation, although it does not even decide the case of STRING-EXTRACT using PARSE-STRING vs. PARSE-NAME, as one uses more of
one resource, and the other uses more of a different resource.
Backtrace:readfile<<<
Hi, I missed the emails coming in on this...
Thank you all for the feedback, Minf... Thank you for the words to extract this... This is really helpful as I did not see the bl word for the ws delimiter. This has solved many more issues I was having with other parts of the code...
S" G0 F4800 X7.966 Y15.054 Z0.300" STRING-EXTRACT
G0
F4800
X7.966
Y15.054
Z0.300 ok
ok
I just retook this and I'm implementing the words to properly capture STRINGS and evaluate for error as Gary mentioned but I can seem to get the file open working... file is a single line like the example provide with a staring FILE read.
: srcfile S" ./sample.g" ;
PARSE-STRING \ ( a u -- a' u' ap up ) parse ws-delimited string within given string (a u)
BEGIN over c@ bl > 0= over and
WHILE 1- swap 1+ swap
REPEAT over >r
BEGIN over c@ bl > over and
WHILE 1- swap 1+ swap
REPEAT over r@ - r> swap ;
: STRING-EXTRACT \ ( a u -- )
BEGIN dup WHILE
parse-string cr type
REPEAT 2drop ;
: READFILE srcfile r/o open-file throw
begin here 1024 read-file throw dup allot
STRING-EXTRACT 0= until ;
ok
readfile
:36: Invalid memory address
Backtrace:readfile<<<
$7F8CBAF8F1D0 read-file
ok
I'll keep at it, but can't seem to get it to work and I crashing forth :D
Hi, I missed the emails coming in on this...
Thank you all for the feedback, Minf... Thank you for the words to extract this... This is really helpful as I did not see the bl word for the ws delimiter. This has solved many more issues I was having with other parts of the code...
S" G0 F4800 X7.966 Y15.054 Z0.300" STRING-EXTRACT
G0
F4800
X7.966
Y15.054
Z0.300 ok
ok
I just retook this and I'm implementing the words to properly capture STRINGS and evaluate for error as Gary mentioned but I can seem to get the file open working... file is a single line like the example provide with a staring FILE read.
: srcfile S" ./sample.g" ;
PARSE-STRING \ ( a u -- a' u' ap up ) parse ws-delimited string within given string (a u)
BEGIN over c@ bl > 0= over and
WHILE 1- swap 1+ swap
REPEAT over >r
BEGIN over c@ bl > over and
WHILE 1- swap 1+ swap
REPEAT over r@ - r> swap ;
: STRING-EXTRACT \ ( a u -- )
BEGIN dup WHILE
parse-string cr type
REPEAT 2drop ;
: READFILE srcfile r/o open-file throw
begin here 1024 read-file throw dup allot
STRING-EXTRACT 0= until ;
ok
readfile
:36: Invalid memory address
Backtrace:readfile<<<
$7F8CBAF8F1D0 read-file
ok
I'll keep at it, but can't seem to get it to work and I crashing forth :D
[...]
: READFILE srcfile r/o fd-in OPEN-FILE THROW
BEGIN line-buffer max-line fd-in READ-LINE
STRING-EXTRACT 0=
UNTIL
fd-in CLOSE-FILE THROW ;
Still not working...
???
SpainHackForth schrieb am Montag, 21. November 2022 um 22:56:01 UTC+1:
Hi, I missed the emails coming in on this...
Thank you all for the feedback, Minf... Thank you for the words to extract this... This is really helpful as I did not see the bl word for the ws delimiter. This has solved many more issues I was having with other parts of the code...
So close, yet so far...S" G0 F4800 X7.966 Y15.054 Z0.300" STRING-EXTRACT
G0
F4800
X7.966
Y15.054
Z0.300 ok
ok
I just retook this and I'm implementing the words to properly capture STRINGS and evaluate for error as Gary mentioned but I can seem to get the file open working... file is a single line like the example provide with a staring FILE read.
: srcfile S" ./sample.g" ;
PARSE-STRING \ ( a u -- a' u' ap up ) parse ws-delimited string within given string (a u)
BEGIN over c@ bl > 0= over and
WHILE 1- swap 1+ swap
REPEAT over >r
BEGIN over c@ bl > over and
WHILE 1- swap 1+ swap
REPEAT over r@ - r> swap ;
: STRING-EXTRACT \ ( a u -- )
BEGIN dup WHILE
parse-string cr type
REPEAT 2drop ;
: READFILE srcfile r/o open-file throw
begin here 1024 read-file throw dup allot
STRING-EXTRACT 0= until ;
ok
readfile
:36: Invalid memory address
Backtrace:readfile<<<
$7F8CBAF8F1D0 read-file
ok
I'll keep at it, but can't seem to get it to work and I crashing forth :Duse READ-LINE (and close the file when done).
So close, yet so far...
0 Value fd-in
256 CONSTANT max-line
Create line-buffer max-line 2 + allot
: READFILE srcfile r/o fd-in OPEN-FILE THROW
BEGIN line-buffer max-line fd-in READ-LINE
STRING-EXTRACT 0=
UNTIL
fd-in CLOSE-FILE THROW ;
Still not working...
???
Hi, I missed the emails coming in on this...
Thank you all for the feedback, Minf... Thank you for the words to extract this... This is really helpful as I did not see the bl word for the
ws delimiter. This has solved many more issues I was having with other parts of the code...
S" G0 F4800 X7.966 Y15.054 Z0.300" STRING-EXTRACT
G0
F4800
X7.966
Y15.054
Z0.300 ok
ok
I just retook this and I'm implementing the words to properly capture STRINGS and evaluate for error as Gary mentioned but I can seem to get
the file open working... file is a single line like the example provide with a staring FILE read.
: srcfile S" ./sample.g" ;
PARSE-STRING \ ( a u -- a' u' ap up ) parse ws-delimited string within given string (a u)
BEGIN over c@ bl > 0= over and
WHILE 1- swap 1+ swap
REPEAT over >r
BEGIN over c@ bl > over and
WHILE 1- swap 1+ swap
REPEAT over r@ - r> swap ;
: STRING-EXTRACT \ ( a u -- )
BEGIN dup WHILE
parse-string cr type
REPEAT 2drop ;
: READFILE srcfile r/o open-file throw
begin here 1024 read-file throw dup allot
STRING-EXTRACT 0= until ;
ok
readfile
:36: Invalid memory address
Backtrace:readfile<<<
$7F8CBAF8F1D0 read-file
ok
I'll keep at it, but can't seem to get it to work and I crashing forth :D
On 22/11/2022 8:44 pm, SpainHackForth wrote:
[...]
: READFILE srcfile r/o fd-in OPEN-FILE THROW
BEGIN line-buffer max-line fd-in READ-LINE
STRING-EXTRACT 0=
UNTIL
fd-in CLOSE-FILE THROW ;
Still not working...
???Try
: READFILE srcfile r/o OPEN-FILE THROW to fd-in
BEGIN line-buffer DUP max-line fd-in READ-LINE THROW
WHILE STRING-EXTRACT REPEAT 2DROP
fd-in CLOSE-FILE THROW ;
On Tuesday, November 22, 2022 at 11:10:48 AM UTC+1, dxforth wrote:
On 22/11/2022 8:44 pm, SpainHackForth wrote:
[...]
: READFILE srcfile r/o fd-in OPEN-FILE THROW
BEGIN line-buffer max-line fd-in READ-LINE
STRING-EXTRACT 0=
UNTIL
fd-in CLOSE-FILE THROW ;
Still not working...
???Try
: READFILE srcfile r/o OPEN-FILE THROW to fd-inah, missing 2drop was killing me! Thank you!
BEGIN line-buffer DUP max-line fd-in READ-LINE THROW
WHILE STRING-EXTRACT REPEAT 2DROP
fd-in CLOSE-FILE THROW ;
Quick question:
when I do this...
s" ./sample.g" r/o open-file ok
S. <2>93873986665184 0 ok
So I'm getting wfileid wior ... somehow I had 4 items on the stack ( which has been fixed as I was reviewing and writing ... 2DROP fixed this. )
Ok so two items on the stack, throw consumes TOS, in this case 0, OK getting the wfield TOS and "to" fd-in again to continue the file operation.
Also, the WHILE ... REPEAT, does that have any control on finish... I see E5.54714 ok
This is the last entry, so there is no EOF... or is that one of the flags...
Where do I read the reference all the different stack comments? I'm still not 100% on read-line
read-line c_addr u1 wfileid – u2 flag wior file “read-line”
Thank you!
On Tuesday, November 22, 2022 at 11:10:48 AM UTC+1, dxforth wrote:
On 22/11/2022 8:44 pm, SpainHackForth wrote:
[...]Try
: READFILE srcfile r/o fd-in OPEN-FILE THROW
BEGIN line-buffer max-line fd-in READ-LINE
STRING-EXTRACT 0=
UNTIL
fd-in CLOSE-FILE THROW ;
Still not working...
???
: READFILE srcfile r/o OPEN-FILE THROW to fd-in
BEGIN line-buffer DUP max-line fd-in READ-LINE THROW
WHILE STRING-EXTRACT REPEAT 2DROP
fd-in CLOSE-FILE THROW ;
ah, missing 2drop was killing me! Thank you!
Quick question:
when I do this...
s" ./sample.g" r/o open-file ok
S. <2>93873986665184 0 ok
So I'm getting wfileid wior ... somehow I had 4 items on the stack ( which has been fixed as I was reviewing and writing ... 2DROP fixed this. )
Ok so two items on the stack, throw consumes TOS, in this case 0, OK getting the wfield TOS and "to" fd-in again to continue the file operation.
Also, the WHILE ... REPEAT, does that have any control on finish...
I see
E5.54714 ok
This is the last entry, so there is no EOF... or is that one of the flags...
Where do I read the reference all the different stack comments? I'm still not 100% on read-line
read-line c_addr u1 wfileid – u2 flag wior file “read-line”
THE reference:
http://www.forth200x.org/documents/forth-2012.pdf
On 23/11/2022 2:24 am, SpainHackForth wrote:
On Tuesday, November 22, 2022 at 11:10:48 AM UTC+1, dxforth wrote:
On 22/11/2022 8:44 pm, SpainHackForth wrote:
[...]Try
: READFILE srcfile r/o fd-in OPEN-FILE THROW
BEGIN line-buffer max-line fd-in READ-LINE
STRING-EXTRACT 0=
UNTIL
fd-in CLOSE-FILE THROW ;
Still not working...
???
: READFILE srcfile r/o OPEN-FILE THROW to fd-in
BEGIN line-buffer DUP max-line fd-in READ-LINE THROW
WHILE STRING-EXTRACT REPEAT 2DROP
fd-in CLOSE-FILE THROW ;
ah, missing 2drop was killing me! Thank you!
Quick question:
when I do this...
s" ./sample.g" r/o open-file ok
S. <2>93873986665184 0 ok
So I'm getting wfileid wior ... somehow I had 4 items on the stack ( which has been fixed as I was reviewing and writing ... 2DROP fixed this. )
Ok so two items on the stack, throw consumes TOS, in this case 0, OK getting the wfield TOS and "to" fd-in again to continue the file operation.
Also, the WHILE ... REPEAT, does that have any control on finish...WHILE ( not EOF) STRING-EXTRACT REPEAT is repeated for each text line in your file
I see
E5.54714 ok
This is the last entry, so there is no EOF... or is that one of the flags...
Where do I read the reference all the different stack comments? I'm still not 100% on read-lineflag=0 returned by READ-LINE means EOF was reached
read-line c_addr u1 wfileid – u2 flag wior file “read-line”
Here's the code with intermediate stack comments shown. It's a good idea doing this
until you are familiar with what each word does/expects.
: READFILE srcfile r/o OPEN-FILE ( fid ior) THROW ( fid) to fd-in
BEGIN line-buffer DUP max-line fd-in
( buf buf maxlen fid) READ-LINE ( buf len flag ior) THROW
( buf len flag) WHILE \ not EOF
( buf len) STRING-EXTRACT REPEAT
( buf len) 2DROP
fd-in CLOSE-FILE THROW ;
I'm, still seen some stuff on the Stack;Assuming hex mode, you attempted to read a line of up to $30 characters at HERE
here 20 dump
7FCC9B49C160: 47 31 20 58 36 32 2E 30 - 39 38 20 59 31 2E 33 35 G1 X62.098 Y1.35
7FCC9B49C170: 34 20 45 33 2E 35 35 36 - 35 39 33 2E 35 39 35 39 4 E3.556593.5959
ok
ok
here 30 fh read-line 2drop ok
.S <1> 1A ok
"minf...@arcor.de" <minforth@arcor.de> writes:
THE reference:
http://www.forth200x.org/documents/forth-2012.pdf
A little more conventient:
<https://forth-standard.org/standard/words>.
However, a standard is not a textbook.
- anton
Is there an overview of the changes w.r.t to ISO93?
A list of paragraphs altered would be great.
albert@cherry.(none) (albert) writes:
Is there an overview of the changes w.r.t to ISO93?
https://forth-standard.org/standard/diff#diff:forth94
and the following section C.8
A list of paragraphs altered would be great.
For that you have to go to
http://www.forth200x.org/documents/
and look at the individual drafts, which contain change bars
(typically against the previous draft).
- anton
An example of text processing in Forth by Sam Falvo II. https://www.youtube.com/watch?v=mvrE2ZGe-rsIs he really just replacing a handful characters with glyphs - and take an hour for all that?
BTW, How does one use parse-name?
S" G1 X25.787 Y2.954 E1.51298" over c@ bl ok
.S <4> 55B8AF0B3460 1A 47 20 ok
What is the 47 left by C@
and 20 left by BL?
Is he really just replacing a handful characters with glyphs - and take an hour for all that?
I didn't actually get the specs for his program.
My take is that it's a pretty simple but extensible macro processor. For folks new to Forth, it's a great demonstration of an approach to concatenative programming, though he certainly has his own style."Extensible" in the sense you've got to change the code anytime you want to "extend" it.
On 25/11/2022 3:07 am, SpainHackForth wrote:
BTW, How does one use parse-name?Inside a definition.
: get-tokens ( "ccc ccc ccc" )
begin parse-name dup while cr type repeat 2drop ;
get-tokens G1 X25.787 Y2.954 E1.51298
G1
X25.787
Y2.954
E1.51298 ok
S" G1 X25.787 Y2.954 E1.51298" over c@ bl ok
.S <4> 55B8AF0B3460 1A 47 20 ok
What is the 47 left by C@'G'
and 20 left by BL?BL is a standard word. Look up its definition.
I ran into parse-word, I think I like that option better in terms of usability, not sure is very portable considering maybe will not be available in other Forth.
Hi,forth
I may suggest different way but with a twist. this is a specific to the posted case (GCode), but never the less may be applicable to other cases. take the idea.
the below steps are based on what I understood may help you:
1- first pre-process the GCode file to have all commands which take parameters to have a space in between (i.e. X10 -> X 10). simplify the task a little bit.
2- define words that correspond to all the commands to do what is indented/planned (i.e. lets say X word sets the x variable, so : X x ! ; or maybe move a motor or something suitable to the problem being solved at hand). transform input into runnable
3- feed the GCode file as a forth file to a forth compiler/interpreter. hand over the task to Forth to run with it.Hello ama... thanks for the feedback.
In summary the idea: transfer the source (here GCode) into a runnable Forth words.
Hope it helps.
Regards,
On 26/11/2022 2:39 am, SpainHackForth wrote:
I ran into parse-word, I think I like that option better in terms of
usability, not sure is very portable considering maybe will not be
available in other Forth.
PARSE-NAME and predecessors PARSE-WORD & WORD form part of the forth interpreter - the
primary purpose of which is to compile forth source code. Being
designed for the latter,
they require some effort to use in other applications. Such are the
issues I rarely -
if ever - use them, preferring to code parsers from scratch as one would
do in other
languages; and as you did with 'PARSE-STRING'.
FWIW in my own forth I went as far as segregating the forth compiler
entirely - removing any temptation to use it in applications.
30 years on, I don't regret that decision in the least. While others
are fooling around with recognizers and working out how to stop
users crashing the system, I'm writing apps that are inherently
idiot-proof :)
Hi,
I may suggest different way but with a twist. this is a specific to the >posted case (GCode), but never the less may be applicable to other
cases. take the idea.
the below steps are based on what I understood may help you:
1- first pre-process the GCode file to have all commands which take >parameters to have a space in between (i.e. X10 -> X 10). simplify the
task a little bit.
Regards,
(Forth)
My take is that it's a pretty simple but extensible macro processor.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 45:44:08 |
Calls: | 6,710 |
Calls today: | 3 |
Files: | 12,243 |
Messages: | 5,354,237 |
Posted today: | 1 |