How to write anything to files from vars with gforth?

254 Views Asked by At

I use few gforth codes & I now want to register results

when I try :

0 value output 

\ some other code

50 testvar !

: test 

  s" .test" r/w open-file throw fd-out

  testvar @ fd-out write-line throw

  fd-out  write-file throw

  fd-out  close-file throw

;

I got an memory address error

fd-out  write-file  
:119: Invalid memory address
fd-out  >>>write-file<<<
Backtrace:

I refer to official documentation but I found nowhere what am I supposed to do to have right memory address depending on variable I set (can be either text & numbers (both)).

2

There are 2 best solutions below

2
On BEST ANSWER

Francois,

In s" .test" r/w open-file throw fd-out does fd-out get the correct value? I would expect a to before fd_out, assuming fd_out is defined with Value.

write-line requires a string (write-line ( c-addr u fileid -- ior ) file: General files), see https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Word-Index.html#Word-Index

So s" 50" would work for the write-line instead of testvar @ which is incomplete, as also an string address is needed on the stack.

write-file also requires a string (write-file ( c-addr u1 fileid – ior ) file: General files), not just the fd_out.

With these changes it should work, good luck!

1
On

WRITE-LINE takes a file handle and a string, and writes the string into the file. A string is just a buffer identified by an address and length.

To write a number in textual representation, we need to convert this number from the binary into the text form.

The standard provides only low level words for that. A library can provide a word like u-to-s to convert an unsigned number into a text.

: u-to-s ( u -- c-addr u ) 0 <# #s #> ;

The result ( c-addr u ) is located in a transient buffer.

Using this helper word, your test can be rewritten as the following:

: test 
  ".test" r/w open-file throw to fd-out
  testvar @ u-to-s fd-out write-line throw
  "test passed" fd-out  write-file throw
  fd-out  close-file throw
;

Gforth has $tmp ( xt -- c-addr u ) word that redirects output into a temporary string. So you can do

  [: testvar @ . ;] $tmp fd-out write-line throw