,---------------. | Contributions | `---------------´ ,------------------------------------------ | 2025-08-01 16:01:48 EricBlake wrote: | referenceImplementation - Cross-reference to the suggested implementation | see: https://forth-standard.org/standard/core/CASE#contribution-391 `------------------------------------------ The standard already includes a reference implementation for CASE OF ENDOF ENDCASE, but it it tucked away in annex A Rationale instead of the more traditional annex E used by most other reference implementations; hence it does not show up when browsing to this page online. So maybe that makes this more of a web page request than yet another reference implementation - but to make life easier for the next reader: https://forth-standard.org/standard/rationale#paragraph.A.3.2.3.2 ,------------------------------------------ | 2025-08-01 21:33:04 EricBlake wrote: | requestClarification - May OF modify the enclosing case-sys on the control stack? | see: https://forth-standard.org/standard/core/OF#contribution-392 `------------------------------------------ The stack diagram for OF compilation, `( C: -- of-sys )`, implies that it can only add an _of-sys_, even though presumably the intent is that OF should never be called outside of a CASE/ENDCASE structure and thus there should always be a _case-sys_ somewhere higher on the control stack (whether or not that is also part of the data stack). On the other hand, ENDOF is clear that the _case-sys_ must be adjacent to the _of-sys_ (at least in terms of the control stack), and that it can be modified, since it specifies `( C: case-sys1 of-sys -- case-sys2 )`. And yet, the standard also includes a sample implementation of OF that _does_ modify the enclosing _case-sys_: https://forth-standard.org/standard/rationale#paragraph.A.3.2.3.2, when it gives `: OF ( #of -- orig #of+1 / x -- )`. Viewing the reference in context, it is clear that it implements _case-sys_ as a variable length structure consisting of 0 or more _orig_ and one u (and in fact, where the representation may be split across the data stack for u and the control stack for the array of _orig_). If OF is permitted to modify the _case-sys_, then one could view that implementation as having an _of-sys_ that occupies zero cells. And the entire reason that the reference implementation modifies _case-sys_ in OF is because it is careful to use >R and R> to move #of out of the was so before doing any work that manipulates the control stack, in case the POSTPONE ELSE of ENDOF is using 1 CS_ROLL, and regardless of whether the control stack shares the data stack. See also the enlightening discussion on whether LEAVE may modify its enclosing _do-sys_; https://forth-standard.org/standard/core/LEAVE#contribution-185; to which the committee replied that it is not compliant for LEAVE to modify the control stack (because there, the standard mandated `( -- )` rather than permitting `( C: do-sys1 i*x -- do-sys2 i*x )`, even though such an implementation would be unlikely to trip up any production program. I'm left scratching my head as to how to portably implement an OF that only appends an _of-sys_, and then ENDOF that merges the _of-sys_ into the adjacent _case-sys_, without requiring carnal knowledge of whether the control stack shares the data stack. Trying to use of CS_PICK and CS_ROLL, even with the addition of CS_DROP https://forth-standard.org/proposals/cs-drop-revised-2019-08-22-#reply-1370, doesn't help; those are specified to operate on _dest_ and _orig_ without any correlation to how they might fare on _case-sys_ or _of-sys_ in the mix. That said, on a simple a system where _orig_ and _dest_ are one cell each, and where the control stack resides on the data stack, a solution with the same variable-length _case-sys_ (namely, _orig_*n n) is trivial: Just move the +1 out of OF and into ENDOF; and at that point you might as well rely on SWAP instead of >R and R>: ``` : OF ( C: -- of-sys ) ( runtime: x1 x2 -- | x1 ) POSTPONE OVER POSTPONE = ( runtime: x1 flag ) POSTPONE IF ( C: of-sys ) ( runtime: x1 ) \ where of-sys and orig are identical POSTPONE DROP ( runtime: -- ) ; IMMEDIATE : ENDOF ( C: case-sys1 of-sys -- case-sys2 ) POSTPONE ELSE ( C: orig*n n orig1 -- orig*n n orig2 ) \ convert of-sys to orig2, where case-sys is a variable-length orig*n n SWAP ( C: orig*n orig2 n ) \ abuse carnal knowledge of relation between n and orig2 1+ ( C: orig*[n+1] n+1 ) \ case-sys2 is now one cell larger than case-sys1 ; IMMEDIATE ``` ,---------. | Replies | `---------´ ,------------------------------------------ | 2025-07-31 09:43:47 AntonErtl replies: | requestClarification - Must the xt returned by DEFER@ have the same value as the one passed to DEFER!, or merely the same behavior? | see: https://forth-standard.org/standard/core/DEFERFetch#reply-1464 `------------------------------------------ About "encode the difference between interpretation and compilation semantics". For immediate words, there is no difference. If a Forth system supports arbitrary combinations of interpretation and compilation semantics (e.g., with Gforth's `interpet/compile:`), the same xt can represent the interpretation semantics of one word and the compilation semantics of another word. E.g.: ```` : foo ." foo" ; : bar ." bar" ; ' foo ' bar interpret/compile: foobar ```` Here the interpretation semantics of `bar` has the same behaviour as the compilation semantics of `foobar`. But actually, when you use `s" foobar" find-name name>compile` to access the compilation semantics of `foobar`, the result is the same as you get from `' bar ' execute`. So, I don't see a point in encoding "the difference between interpretation and compilation semantics". Any behaviour of a word can be both. ,------------------------------------------ | 2025-07-31 10:31:50 AntonErtl replies: | requestClarification - 3.2.1.1 vs. Double-cell integer behavior on unusual integer architectures | see: https://forth-standard.org/standard/usage#reply-1465 `------------------------------------------ The question is what the goal of the next Forth standard should be. 1) Should it make it easy to implement Forth on the most exotic platforms? 2) Should it standardize common practice among mainstream systems? 3) Should it standardize common practice used by Forth programs? My take is that 3 is the most important of these goals. In the present case we have the common practice among mainstream systems that all bits in one cell (for singles) and, for doubles, two cells are used. Which properties that such an implementation has are used by how many programs? I don't know, and I actually don't have an easy way to test existing programs for determining such questions. In any case, when I write a program using doubles, that's the mental model I use, so the program could acquire an environmental dependency on such an implementation at any point. Given this situation, I don't see a good reason not to standardize such a model. Concerning supporting Forth systems for exotic platforms, Forth-94 has aimed at that, and Forth-2012 still contains the same rules as far as number representations are concerned. So Forth-2012 may be the right standard for exotic platforms. ,------------------------------------------ | 2025-07-31 16:50:19 GerryJackson replies: | testcase - Compilation of a VALUE child word should not inline its current value | see: https://forth-standard.org/standard/core/VALUE#reply-1466 `------------------------------------------ While it would be easy to add the tests you suggest I don't think it's a good idea. You made an error with your 'optimisation' which such tests would have detected, but there are many possibilities that Forth implementations and optimisation of compiled code can actually give the wrong answer (not just for the case you report). It would not be cost effective, if not impossible, to predict what code compiler developers could generate incorrectly other than the behaviour specified in the standard. ,------------------------------------------ | 2025-08-01 05:49:00 AntonErtl replies: | testcase - Compilation of a VALUE child word should not inline its current value | see: https://forth-standard.org/standard/core/VALUE#reply-1467 `------------------------------------------ Yes, it's not possible to test for everything. In this case the test is against a bug that has actually existed. Such bugs have a tendency to reappear (known as regression), and therefore such tests are added to test suites as regression tests. Also, system implementors can implement the same bug independently: Just two years ago Francois Laagel discovered the same bug (IIRC incorrect handling of counted-loop parameters upon `throw`) in the 64-bit versions of two major Forth systems that did not have this bug in their 32-bit versions. ,------------------------------------------ | 2025-08-01 11:39:15 GerryJackson replies: | testcase - Compilation of a VALUE child word should not inline its current value | see: https://forth-standard.org/standard/core/VALUE#reply-1468 `------------------------------------------ OK, I've added the suggested tests to file coreexttest.fth ,------------------------------------------ | 2025-08-01 11:48:07 GerryJackson replies: | testcase - Compilation of a VALUE child word should not inline its current value | see: https://forth-standard.org/standard/core/VALUE#reply-1469 `------------------------------------------ I meant to add I've modified the file on the GitHub repository only. Presumably the person responsible for the forth-standard.org website will have to update the 'Testing' section of the VALUE specification. For their information the tests I've added are: After the existing T{ VAL1 -> 222 }T Add: T{ 444 TO VAL1 -> }T T{ VD1 -> 444 }T