SirWumpus / post4

Post4 is an indirect threaded Forth dialect written in C.
BSD 2-Clause "Simplified" License
4 stars 1 forks source link

`INCLUDE-FILE` shall close fileid #55

Open ruv opened 6 days ago

ruv commented 6 days ago

https://github.com/SirWumpus/post4/blob/75a26404bd67d386cebd8014d90f576cc915948e/src/post4.p4#L2052-L2056

The above definition assumes that INCLUDE-FILE does not close the file, but it shall close it: When the end of the file is reached, close the file and restore the input source specification to its saved value. (11.6.1.1717 INCLUDE-FILE).

Either this definition is incorrect, or INCLUDE-FILE, which does not close the file at the end, is incorrect.

SirWumpus commented 6 days ago

INCLUDE-FILE is incorrect WRT the current definition. However, one could argue that the definition is badly defined. IMO if you OPEN-FILE, then it is your responsibility to CLOSE-FILE too; INCLUDE-FILE should not have this side effect.

What if fid given to INCLUDE-FILE were a non-blocking pipe or socket then read() would return 0 (assumes 0 is taken to mean soft EOF), but more input might be sent; only when the writer closes their write-end is a EOF signalled/returned. So IMO INCLUDE-FILE should NOT have the side-effect of closing its input. (Pretty sure Forth people would jump up and down at that.)

ruv commented 6 days ago

IMO if you OPEN-FILE, then it is your responsibility to CLOSE-FILE too; INCLUDE-FILE should not have this side effect.

Agreed, and I think so too (though not so critically). But such a specification change for INCLUDE-FILE is not backwards compatible. So, I would use another word, e.g. INTERPRET-FILE, which does not close the handle. And provide INCLUDE-FILE for programs:

: include-file ( i*x fileid -- j*x )
  dup >r ['] interpret-file catch r> close-file swap throw throw
;

On the other hand, in some cases one side opens a handle, and another side closes the handle. For example, in a plausible HTTP server, the listener obtains a socket and passes it to a worker, and the worker conducts the "conversation" and then closes the socket (instead of returning it to the listener).

SirWumpus commented 6 days ago

INTERPRET-FILE or EVAL-FILE sounds like a nice alternative.

Huh? ... throw throw ? You're messing with my head again.


On the other hand, in some cases one side opens a handle, and another side closes the handle. For example, in a plausible HTTP server, the listener obtains a socket and passes it to a worker, and the worker conducts the "conversation" and then closes the socket (instead of returning it to the listener).

Sort of. An HTTP server would close the write-end of the socket to signal EOF to the client (reader). In bi-directional socket, either write-end can be closed, signalling to the other end an EOF (for request/response complete or error).

With a bi-directional pipe, you still close the write-end and wait for return input.

ruv commented 6 days ago

Huh? ... throw throw ? You're messing with my head again.

We have two iors: from catch and from close-file, and we prefer to re-throw the first one, and if it's zero, we throw the second (if it's zero than we just exit):

: include-file ( i*x fileid -- j*x )
  dup >r ['] interpret-file catch ( ior1|0 ) r> close-file ( ior1|0  ior2|0 )
  swap ( ior2|0  ior1|0 ) throw ( ior2|0 ) throw
;

(NB: in these stack diagrams I only indicate the top one or two parameters)

SirWumpus commented 6 days ago

Oh.

Some times I wonder if you're not some Technomage in disguise with Forth as your language of incantations.