Note: this isn't Python or PHP like "easy to use" - where the magician
hides the rabbit behind his back. The effect is perfectly predictable -
and quite intuitive (if I may say so myself).
Note in C, printf() isn't capable of redirection (unless from OS level). >fprintf() is - but how many people use it in combination with stdout
(present company excepted)?
Hans Bezemer
In article <nnd$68843db9$0f3297b6@f356aed0e515fe8b>,
The integration with the OS-es makes for useful applications. ~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: cat printhex.frt
: doit 1 ARG[] EVALUATE HEX . ;
~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: printhex 1024;echo
400
[lina -c printhex.frt]
SCRIPTFILE-NAME DUMP-TO-FILE
Mime-Version: 1.0
User-Agent: Rocksolid Light
Path: not-for-mail
From: mhx@iae.nl (mhx)
Newsgroups: comp.lang.forth
Organization: novaBBS
Injection-Info: i2pn2.org; logging-data="921598"; mail-complaints-to="usenet@i2pn2.org"; posting-account="J+nubxJRM7ncpF4l6KLO+OONWmFAYJHVJegfwQXJ8vc";
Subject: Re: Back & Forth - 4tH I/O and You
References: <nnd$306ecdcd$714b9ebb@8c19de68479dc08d> <b2a4690cc4cdcb9e39310166d37070ab2a16d8b2@i2pn2.org> <nnd$68843db9$0f3297b6@f356aed0e515fe8b> <nnd$0346461b$62171617@be8ddde8960df4cb>
Content-Transfer-Encoding: 8bit
X-Rslight-Site: $2y$10$OOQsNDELF5uNo3A3Uv7gJOwfOwKYrncFKKKX4OxnyyB9YDRoHEGxG >X-Rslight-Posting-User: 4e0dc1fdad1ead10b39e7eb5db19bf73d73e3ab3
Date: Sun, 18 May 2025 19:10:34 +0000
Message-Id: <fce9942b8d6e52702b330d5edcde5b4f@www.novabbs.com>
Content-Type: text/plain; charset=utf-8; format=flowed >X-Spam-Checker-Version: SpamAssassin 4.0.0
On Sun, 18 May 2025 18:55:27 +0000, albert@spenarnc.xs4all.nl wrote:
In article <nnd$68843db9$0f3297b6@f356aed0e515fe8b>,
The integration with the OS-es makes for useful applications.
~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: cat printhex.frt
: doit 1 ARG[] EVALUATE HEX . ;
~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: printhex 1024;echo
400
[lina -c printhex.frt]
In iForth we can redirect to a string:
: ngspice-POSTLUDE ( -- c-addr u )
DRY-RUN ( using TASK-DATA setup by SP>NGSPICE )
|head .paramdata LOCAL mem
<$$ ." * Generated by iSPICE on " .TIME$ ." -- do not edit"
CR
CR ." .control"
CR ." unset ltspice"
CR ." unset dotstep"
CR ." set numthreads=1
CR ." set ispice = " #|params 0<> 1 AND .
CR ." "
." let spiceidx = $SPICEIDX ; "
." let ntasks=" #|tasks ."#"
." let ncpus=" #|cpus ."#"
." let nparams=" #|params ."#"
." let nresults=" #|results ."#"
#|params
IF CR ." compose p values "
#|tasks 0 ?DO CR ." + "
#|params 0 ?DO mem DF@+ TO mem
F.N2+_
LOOP
LOOP
CR #|params 1 > IF ." reshape p[" #|tasks
0DEC.R ." ][" #|params
0DEC.R ." ]"
ENDIF
ENDIF
CR ." let ignore = 0"
CR ." let buf = 0"
CR ." let done = 0"
CR ." let ix = spiceidx"
CR ." compose arg values " #|tasks #|results * .
#|results 0DEC.R ." ix 0 0.0"
CR ." compose status values ncpus spiceidx"
CR ." dowhile ix < ntasks"
#|params 0 ?DO CR #|params 1 > IF ." let buf = p[ix][" I
0DEC.R ." ]"
ELSE ." let buf = p[ix]"
ENDIF
CR ." alterparam " |head .pnames I CSTR[] .$
." = $&buf"
LOOP
#|params IF CR ." mc_source" ENDIF
CR ." " $SIM @+ 1 /STRING TYPE
#|results 0 ?DO CR ." let arg[3] = " I ."#"
CR ." " I (meashead) TYPE
." arg[4] " I (measbody) TYPE
CR ." let ignore=setresult(arg) "
LOOP
CR ." let ix = ix + ncpus"
CR ." let arg[2] = ix"
CR ." write " RAWDATA-NAME
NO-EXTENSION
S" _{$spiceidx}{.raw}"
$+ TYPE
#|tasks IF CR ." set appendwrite" ENDIF
CR ." end"
CR ." let done = setfinish(status)"
CR ." quit"
CR ." .endc"
$$>
SCRIPTFILE-NAME DUMP-TO-FILE
CR ." Please manually add the following lines to `" cktfile .$ ." .sp`"
CR
CR ." .LIBRARY basic.lib basicstuff"
CR ." .OPTION savecurrents"
CR ." .INC " cktfile .$ ." .iscript"
CR ; PRIVATE
( This mixes Forth with the SPICE shell script language )
Result:
* Generated by iSPICE on 23:19:11, December 9, 2024 -- do not edit
control
unset ltspice
unset dotstep
set numthreads=1 $ make sure spinit has this too; we can't overrule
spinit!
set ispice = 0
let spiceidx = $SPICEIDX ; let ntasks=1; let ncpus=8;
let nparams=0; let nresults=2;
let ignore = 0
let buf = 0
let done = 0
let ix = spiceidx
compose arg values 2 2 ix 0 0.0
compose status values ncpus spiceidx
dowhile ix < ntasks
TRAN 30u 30ms 0 30u
let arg[3] = 0;
meas tran arg[4] AVG @i1[current]
let ignore=setresult(arg)
let arg[3] = 1;
meas tran arg[4] AVG @i2[current]
let ignore=setresult(arg)
let ix = ix + ncpus
let arg[2] = ix
write f:/2jsource_test_{$spiceidx}{.raw}
set appendwrite
end
let done = setfinish(status)
quit
endc
-marcel--
In article <fce9942b8d6e52702b330d5edcde5b4f@www.novabbs.com>,[..]
mhx <mhx@iae.nl> wrote:
That doesn't convince I could do this myself.
On 19/05/2025 2:49 am, Hans Bezemer wrote:
...
Second - I've consulted my script, and nowhere do I use the word "redirection". I *do* state, however: "That means I have to *reuse* as many tokens as possible."
What I mean is: why should I change my source to:
D <# #S ROT SIGN #> fid WRITE-FILE
When I can continue to use a perfectly capable: .
In my case that would be: (.) WRITE
where (.) is a kernel function and WRITE is a library function with >appropriate error handling:
123 (.) write invalid handle error ... aborting
Using that library I could define DISK as mentioned previously and do:
DISK 123 . CONSOLE
but as any exception msg would go to the file, redirection seems more
trouble than worth.
However, the FILE wordset isn't simple. It's an entirely new API you
have to get familiar with. It might be easy to map when your underlying >implementation relies on C, it might be easy to map if you have your
own, internal API that happens to fit nicely on that idea (or simply be
very versatile) - but I doubt it's trivial to map if you have to build
it up from the ground.
An still then - since it has virtually no relationship with console I/OSo, no. A little ingenuity solves that to great benefit.
(like TYPE, ACCEPT, ., .", etc.) you have to learn like a completely >different language to use it. So IMHO it fails on the "simplicity" >qualification.
I don't think it's too hard to map the Forth FILE word set on the C file
API. I may do that later if I feel like it. Now - and here we curve back
to my idea of the Forth philosophy - C is not Forth. An idea derived
from the C philosophy is inherently un-Forth-like. Local variables are
part of the stack frame concept - and hence inherently un-Forth-like.
The argument you can "bolt on" all kinds of C facilities is not anAgreed. Now bolt on a driver to access a modern disk drive.
argument for bolting them on, it's merely an example of and a tribute to >Forth's extensibility.
Hans BezemerLast time a heard it was a measure of distance.
BTW, I have no idea what an inch is - let alone seven of them.
On 20/05/2025 2:13 am, Hans Bezemer wrote:
On 19-05-2025 15:22, dxf wrote:
Those are console functions which traditionally went to serial ports and bear little
resemblance to disk file I/O. For implementer it's not simpler - it's a layer on top
of DOS functions. Even as an end-user I'm not sure I'd like it. How does one handle
seeks, read and writing to the same file etc? The ANS functions were designed to
handle random access. Console functions were not.
Originally, yeah - that was all. And then we enter the wondrous world of "feature requests". So a few more calls were added, like delete-file, reposition-file and the likes.
If you read the documentation you will see that some I/O devices are out of bounds. So we devised tiny little macros for that:
#define UDEV(a) if(((a)<=COUT)||((a)>=MAXDEVS))throw(M4BADDEV)
That's how we handle things around here.
I think we both felt some simplification of file-handling at the application >programmer level was desirable. For me it's been quite a while since I've >used e.g. READ-FILE directly. The ubiquitous 'filecopy' application for me >would look like this:
: OPENFILES ( -- )
cr .ifile ." -> " .ofile
r/o openin r/w makeout cr
;
: (RUN) ( -- )
openfiles
begin pad 128 read dup while write repeat 2drop
closefiles
;
I believe the 4tH manual illustrates something similar.
I don't have to worry about overwrite checks, user interrupt, error messages >and so on as it's handled under the hood. Was it all necessary? Is it >'anti-Forth'? Folks can decide for themselves.
On 20-05-2025 04:45, dxf wrote:
I think we both felt some simplification of file-handling at the application >> programmer level was desirable. For me it's been quite a while since I've >> used e.g. READ-FILE directly. <SNIP>
I believe the 4tH manual illustrates something similar.
As I stated before, there were several requirements coming together in
this design. First, the desire to minimize the number of tokens required
for an I/O system. Second, to design an API which fitted (my idea of)
Forth better. Third, one that made a transition from the previous 4tH
I/O system as painless as possible.
So - yes, you got that right: as simple and as intuitive possible. I
must compliment you on your concise analysis - this is almost exactly as
I tend to write 4tH: you open your files, put the handles on the stack,
do your I/O and use those same handles to close the files. It's
literally coded like that in the "CONVERT" template (See YT: >https://youtu.be/73fDmCh9Mio).
I don't have to worry about overwrite checks, user interrupt, error messages >> and so on as it's handled under the hood. Was it all necessary? Is it
'anti-Forth'? Folks can decide for themselves.
In a way, yeah. Opening a files returns an error code - but the rest of
the API - especially the output words, don't. The reason for that is
I've rarely seen errors in that regard. If you can open a file
successfully, you normally can write to it - at least, that's my
experience. Also, closing files very rarely results in an error. That's
why these parts of the API don't return error codes. Note - I'm not
saying it can't happen. I'm just saying I've only seen it happen very
rarely. So why bug the programmer with endlessly checking error codes?
That doesn't mean no error detection is performed. It is - but it THROWs
an error when things go wrong. If you wanna catch it, fine. If not, fine
too. The system will take care of matters anyway. As you state - it's up
to the user to decide.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 505 |
Nodes: | 16 (2 / 14) |
Uptime: | 44:57:16 |
Calls: | 9,919 |
Calls today: | 6 |
Files: | 13,801 |
Messages: | 6,347,274 |