Discussion:
HELD
Add Reply
dxf
2024-04-25 01:33:18 UTC
Reply
Permalink
This is a new word introduced by MPE. It avoids some of the complications when
using #> to return the current contents of the PNO buffer. The definition is:

HELD ( -- caddr len )

Return the address and length of the string held in the pictured numeric output
buffer.

HELD is a factor of #> allowing the latter to be defined:

: #> 2DROP HELD ;

So if you've found yourself writing 0 0 #> or <# 2DUP HOLDS #> to avoid the
2DROP built into #> then HELD may be a neater solution.
mhx
2024-04-25 06:35:48 UTC
Reply
Permalink
Post by dxf
This is a new word introduced by MPE. It avoids some of the complications when
HELD ( -- caddr len )
Return the address and length of the string held in the pictured numeric output
buffer.
: #> 2DROP HELD ;
So if you've found yourself writing 0 0 #> or <# 2DUP HOLDS #> to avoid the
2DROP built into #> then HELD may be a neater solution.
Doesn't everybody use the low level factors of "." etc.? Wanting to format
a number in a special way is rather infrequent, but not wanting to print a
number right away is common.

25 (.) TYPE
PI (F.) TYPE

-marcel

-marcel
dxf
2024-04-25 07:34:10 UTC
Reply
Permalink
Post by mhx
...
Doesn't everybody use the low level factors of "." etc.? Wanting to format
a number in a special way is rather infrequent, but not wanting to print a
number right away is common.
25 (.)  TYPE
PI (F.) TYPE
(F.) is an example of where I used HELD two or three times. Some others:

\ Return string right-aligned as a2 u2. Uses HOLD buffer
: RJUST ( a u +n c -- a2 u2 )
Post by mhx
r >r <# shold held r> over - 0 max r> nhold #> ;
\ Get the full directory path for logical disk drive u
: PATH ( u -- c-addr u2 ior )
zbuf @ 2dup 'SI ! 'DX c! $47 doscall doserr? >r
<# zcount dup if [char] \ hold then shold s" :\\" shold
Post by mhx
drv [char] A + hold held r> ;
HOLDS (200x) recognizes that the numeric conversion buffer can and is used for
string processing. In that situation HELD is often more appropriate than #> .
mhx
2024-04-25 10:51:40 UTC
Reply
Permalink
dxf wrote:

[..]
Post by dxf
\ Return string right-aligned as a2 u2. Uses HOLD buffer
: RJUST ( a u +n c -- a2 u2 )
Post by mhx
r >r <# shold held r> over - 0 max r> nhold #> ;
[..]
Post by dxf
HOLDS (200x) recognizes that the numeric conversion buffer can and is used for
string processing. In that situation HELD is often more appropriate than #> .
I was never really satisfied with this low-level assembly work.
Nowadays I use device redirection to a string, for example:

: dd>matlab ( F: sel -- ) ( -col -- c-addr u )
FLOCAL sel
LOCAL -col
|resudata 0= IF S" >matlab :: ERROR :: TASK-DATA is unavailable." EXIT ENDIF
<$$ ." %% iSPICE output" CR ." % "
#|params 0 ?DO I -col <> IF |head .pnames I CSTR[] .$ .FOURTABS
ENDIF
LOOP
#|results 0 ?DO I >headrow .resname .$ .FOURTABS LOOP
CR ." data = ["
#|tasks
0 ?DO -col 0> IF |head .paramdata I #|params * -col +
DFLOAT[] DF@ sel -1e-4 F~ ( equal to 0.01% )
ELSE TRUE
ENDIF
IF CR #|params 0 ?DO I -col
<> IF |head .paramdata
J #|params * I +
DFLOAT[] DF@ +E. 3 SPACES
ENDIF
LOOP
#|results 0 ?DO |resudata J #|results * I +
DFLOAT[] DF@ +E. 3 SPACES
LOOP
ENDIF
LOOP
CR ." ];"
CR
$$> ;

: .JOB>console ( -- ) 0e -1 dd>matlab TYPE ;
: .JOB>matlab ( -- ) 0e -1 dd>matlab MFILE-NAME DUMP-TO-FILE ;

-marcel
dxf
2024-04-25 12:05:47 UTC
Reply
Permalink
[..]
Post by dxf
\ Return string right-aligned as a2 u2. Uses HOLD buffer
: RJUST ( a u +n c -- a2 u2 )
  >r >r  <# shold held  r> over - 0 max  r> nhold #> ;
[..]
Post by dxf
HOLDS (200x) recognizes that the numeric conversion buffer can and is used for
string processing.  In that situation HELD is often more appropriate than #> .
...
Well-factored code has a simplicity and a rightness to it. When one sees
something that irreducible, all the other machinations go out the window.
dxf
2024-04-26 05:06:24 UTC
Reply
Permalink
Post by dxf
[..]
Post by dxf
\ Return string right-aligned as a2 u2. Uses HOLD buffer
: RJUST ( a u +n c -- a2 u2 )
  >r >r  <# shold held  r> over - 0 max  r> nhold #> ;
[..]
Post by dxf
HOLDS (200x) recognizes that the numeric conversion buffer can and is used for
string processing.  In that situation HELD is often more appropriate than #> .
...
Well-factored code has a simplicity and a rightness to it. When one sees
something that irreducible, all the other machinations go out the window.
Regarding redirection I'd say apps intended for disk output are written that
way which implies functions have string output. If OTOH apps are written
for console output, then usually the OS has a mechanism for redirection in
which case the app writer need not concern himself.
mhx
2024-05-08 09:18:01 UTC
Reply
Permalink
[..]
Post by dxf
Regarding redirection I'd say apps intended for disk output are written that
way which implies functions have string output. If OTOH apps are written
for console output, then usually the OS has a mechanism for redirection in
which case the app writer need not concern himself.
Typically text output is meant to be read by humans, while file
output is mainly meant to be read by computers (further processing).
For debugging it is prudent to make sure the files are (somewhat)
human readable though.

I think redirection is difficult (or at least inconvenient)
from *within* a program, as is switching back and forth
between different streams.

Indeed, for trivial and conventional programs, that do not use the
Forth interpreter as an essential component, the standard OS tools
may be sufficient.

-marcel
dxf
2024-05-09 00:57:52 UTC
Reply
Permalink
[..]
Post by dxf
Regarding redirection I'd say apps intended for disk output are written that
way which implies functions have string output.  If OTOH apps are written
for console output, then usually the OS has a mechanism for redirection in
which case the app writer need not concern himself.
Typically text output is meant to be read by humans, while file output is mainly meant to be read by computers (further processing).
For debugging it is prudent to make sure the files are (somewhat) human readable though.
I think redirection is difficult (or at least inconvenient) from *within* a program, as is switching back and forth between different streams.
Indeed, for trivial and conventional programs, that do not use the
Forth interpreter as an essential component, the standard OS tools
may be sufficient.
Text may have originally been intended for humans but it became so massive that
now we use computers to process it and disks to store it. Redirecting text data
intended for disk to the console might be useful in certain circumstances and
when amounts are small. But the idea of sending data to disk using console output
statements seems confusing. How does the programmer differentiate bona-fide
console output from disk output? I don't like it at all.
mhx
2024-05-09 05:29:09 UTC
Reply
Permalink
Post by dxf
How does the programmer differentiate bona-fide
console output from disk output?
I have to admit I didn't expect that one coming.

-marcel
a***@spenarnc.xs4all.nl
2024-05-09 11:40:00 UTC
Reply
Permalink
Post by mhx
[..]
Post by dxf
Regarding redirection I'd say apps intended for disk output are written that
way which implies functions have string output.  If OTOH apps are written
for console output, then usually the OS has a mechanism for redirection in
which case the app writer need not concern himself.
Typically text output is meant to be read by humans, while file output is mainly meant to be read by computers (further processing).
For debugging it is prudent to make sure the files are (somewhat) human readable though.
I think redirection is difficult (or at least inconvenient) from *within* a program, as is switching back and forth between
different streams.
Indeed, for trivial and conventional programs, that do not use the
Forth interpreter as an essential component, the standard OS tools
may be sufficient.
Text may have originally been intended for humans but it became so massive that
now we use computers to process it and disks to store it. Redirecting text data
intended for disk to the console might be useful in certain circumstances and
when amounts are small. But the idea of sending data to disk using console output
statements seems confusing. How does the programmer differentiate bona-fide
console output from disk output? I don't like it at all.
Using EVALUATE to extend the compiler is frowned upon by some.
I use FORMAT&EVAL formatting a string, then evaluate to great advantage.
(It is similar to MPE-forth )

Example: this is a simple OO of one screen.
The FORMAT&EVAL word helps distracting detail away from defining
classes and methods.

0 ( class endclass M: M; ) \ AH B6jan23
1 "SWAP-DP" WANTED "FORMAT" WANTED VARIABLE LAST-IN
2 VARIABLE DP-MARKER DATA NAME$ 128 ALLOT DATA BLD$ 4096 ALLOT
3 : -WORD 1- BEGIN 1- DUP C@ ?BLANK UNTIL 1+ ; ( in -- firstch)
4 : {BLD PP @ LAST-IN ! ;
5 \ Retain input since {BLD excluding word name.
6 : BLD} LAST-IN @ PP @ -WORD OVER - BLD$ $+! ;
7 : class NAME NAME$ $! NAME$ $@ "VARIABLE ^%s" FORMAT&EVAL
8 "" BLD$ $! SWAP-DP HERE DP-MARKER ! {BLD ;
9 : M: BLD} HERE DP-MARKER @ - >R SWAP-DP :
10 R> NAME$ $@ "^%s @ %d +" FORMAT&EVAL ;
11 : M; POSTPONE ; SWAP-DP {BLD ; IMMEDIATE
12 : endclass BLD} DP-MARKER @ HERE - ALLOT SWAP-DP
13 BLD$ $@ NAME$ $@ ": BUILD-%s HERE >R %s R> ;" FORMAT&EVAL
14 NAME$ $@ 2DUP 2DUP 2DUP
15 ": %s CREATE BUILD-%s ^%s ! DOES> ^%s ! ;" FORMAT&EVAL ;

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat purring. - the Wise from Antrim -
Anton Ertl
2024-05-09 15:02:26 UTC
Reply
Permalink
Post by dxf
But the idea of sending data to disk using console output
statements seems confusing.
I have been doing this for many decades without confusion, and I am
not the only one. Lots of shell and awk code works that way.
Post by dxf
How does the programmer differentiate bona-fide
console output from disk output?
The typical case is that error messages should go to the console while
regular output is directed to disk. For that purpose Unix has two
file descriptors: 1 (stdout as C FILE *), and 2 (stderr as C FILE *).
If you want to print an error or warning message, you print to stderr,
otherwise to stdout.

Concerning OUTFILE-EXECUTE in Gforth, you can do the same:

[~:149311] gforth -e '." data for a file" s" error message" '"'"' type stderr outfile-execute bye' >/tmp/myfile
error message[~:149312]
[~:149312] cat /tmp/myfile
data for a file[~:149313]

You can also do a STDERR OUTFILE-EXECUTE in a definition that is
executed by OUTFILE-EXECUTE (i.e., where the other TYPEs are
redirected to some file, or (probably less common) interleave plain
TYPEs with calls to OUTFILE-EXECUTE. E.g.,

s" /tmp/myfile" w/o open-file throw constant myfile
: foo ." data for myfile" cr ;
' foo myfile outfile-execute
.( "bona-fide" console output) cr

- 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: https://forth-standard.org/
EuroForth 2023: https://euro.theforth.net/2023
dxf
2024-05-10 04:02:25 UTC
Reply
Permalink
Post by Anton Ertl
Post by dxf
But the idea of sending data to disk using console output
statements seems confusing.
I have been doing this for many decades without confusion, and I am
not the only one. Lots of shell and awk code works that way.
Post by dxf
How does the programmer differentiate bona-fide
console output from disk output?
The typical case is that error messages should go to the console while
regular output is directed to disk. For that purpose Unix has two
file descriptors: 1 (stdout as C FILE *), and 2 (stderr as C FILE *).
If you want to print an error or warning message, you print to stderr,
otherwise to stdout.
[~:149311] gforth -e '." data for a file" s" error message" '"'"' type stderr outfile-execute bye' >/tmp/myfile
error message[~:149312]
[~:149312] cat /tmp/myfile
data for a file[~:149313]
You can also do a STDERR OUTFILE-EXECUTE in a definition that is
executed by OUTFILE-EXECUTE (i.e., where the other TYPEs are
redirected to some file, or (probably less common) interleave plain
TYPEs with calls to OUTFILE-EXECUTE. E.g.,
s" /tmp/myfile" w/o open-file throw constant myfile
: foo ." data for myfile" cr ;
' foo myfile outfile-execute
.( "bona-fide" console output) cr
The nearest I've been to what you're suggesting is this single app:

https://pastebin.com/tTUK3xmx

It defaults to console output as that's the only way I get to see
startup messages and queries. To send to disk, output must be
preceded by "DISK" - which was ok as I didn't expect errors at this
point. Problems would arise should I want to abort as the app will
ask for confirmation.

If the purpose of all this was to 'save effort' then it's questionable
because I found myself dealing with scenarios that wouldn't exist had
I sent directly to disk. As for output to console, that was never
going to be useful for this particular app. Was it useful in the sense
I could say 'Gee whizz, I'm sending to the console and it's to going to
disk'. I guess it was but such amusements tend to be short-lived.
sjack
2024-05-10 12:20:18 UTC
Reply
Permalink
Post by Anton Ertl
The typical case is that error messages should go to the console while
regular output is directed to disk. For that purpose Unix has two
file descriptors: 1 (stdout as C FILE *), and 2 (stderr as C FILE *).
If you want to print an error or warning message, you print to stderr,
otherwise to stdout.
Prompt and error messages send to stderr. Normally both stdout and stderr
go to console, no noticable distinction.
When desired, redirect stdout (pure data) to disk or other window with
prompt and error messages left at console.

Loading...