,---------------. | Contributions | `---------------´ ,------------------------------------------ | 2024-02-05 15:46:57 ruv wrote: | requestClarification - An ambiguous condition in LSHIFT | see: https://forth-standard.org/standard/core/LSHIFT#contribution-335 `------------------------------------------ 6.1.1805 says: > An ambiguous condition exists if _u_ is greater than or equal to the number of bits in a cell. Why does this ambiguous condition exist? Do we have implementations that produce some side effects or other result than `0` if _u_ is greater than or equal to the number of bits in a cell? Rationale. The result of a single shift by _u_ bits should be always equivalent of _u_ sequential shifts by 1 bit, regardless of _u_. Then, could this ambiguous conditions be removed? ,---------. | Replies | `---------´ ,------------------------------------------ | 2024-01-31 12:21:58 ruv replies: | referenceImplementation - Possible Reference Implementation | see: https://forth-standard.org/standard/core/VARIABLE#reply-1184 `------------------------------------------ @lmr writes: > one can't actually input `<` and `>` right before or after a non-whitespace char within triple-backtick sections _with the current web front-end_ Yes, it's a known problem, see [Issue #54](https://github.com/GeraldWodni/forth-standard.org/issues/54) in the project on GitHub. ,------------------------------------------ | 2024-01-31 12:35:34 ruv replies: | requestClarification - loopsys in data? | see: https://forth-standard.org/standard/core/DO#reply-1185 `------------------------------------------ > Would it be conforming for an implementation to generate a new loopsys in _data_ space for every `DO` ever compiled Usually, a _loop-sys_ is created in run-time. An implementation may allocate data space while performing the compilation semantics for `DO`, but it is not allowed to allocate data space while performing the run-time semantics for `DO`. If you allocate a slot for _loop-sys_ at compile time, it will not work correctly in run-time when recursion occurs (directly or indirectly) — the slot will be overwritten and not restored. ,------------------------------------------ | 2024-01-31 13:28:17 ruv replies: | requestClarification - are colon-defs supposed to be compiled in data space? | see: https://forth-standard.org/standard/core/Colon#reply-1186 `------------------------------------------ > are colon-definitions supposed to be compiled in data space (addressable by `@`, `!` etc)? It is not supposed, but allowed. Under the hood, an implementation may allocate data space during compilation. [3.3.3.2 Contiguous regions](https://forth-standard.org/standard/usage#usage:contiguous) says: «an implementation is free to allocate data space for use by code» On the other hand, a program is only allowed to access the address units that are either explicitly allocated by the program, or provided by the system as variables, text-literal regions, input buffers, and other transient regions — see [3.3.3 Data space](https://forth-standard.org/standard/usage#usage:dataspace). Also, the section [4.1.2 Ambiguous conditions](https://forth-standard.org/standard/doc#doc:ambiguous) says that an ambiguous condition exists if a program addresses a region not listed in [3.3.3 Data space](https://forth-standard.org/standard/usage#usage:dataspace). ,------------------------------------------ | 2024-01-31 14:45:46 ruv replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1187 `------------------------------------------ The following test case ``` : x]] postpone ]] ; immediate : to, [ 123 . x]] to [[ 456 . ] ; ``` is expected to print "123 456" during compilation, but it prints only "123" in your implementation. Thus, `state` should not be used, but another variable should be used to hold "postponing" mode. Anyway, I prefer to implement `]]` as a parsing word. ,------------------------------------------ | 2024-01-31 15:58:07 ruv replies: | referenceImplementation - Implementing COMPILE, via EXECUTE | see: https://forth-standard.org/standard/core/COMPILEComma#reply-1188 `------------------------------------------ In general, reference implementations do not need to avoid recursive dependencies (when several words uses each other, directly or indirectly), since they actually are not connected with each other. «They are supplied solely for the purpose of providing a detailed understanding of a definitions requirement» ([E.1](https://forth-standard.org/standard/implement#section.E.1)). See also my another [comment](https://forth-standard.org/standard/string/CMOVE?hideDiff#reply-724). ,------------------------------------------ | 2024-01-31 16:54:43 lmr replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1189 `------------------------------------------ > `: x]] postpone ]] ; immediate` > `to, [ 123 . x]] to [[ 456 . ] ;` > is expected to print "123 456" during compilation, but it prints only "123" in your implementation. GForth and VFX print the same. Are you assuming a `]] ...[[` that saves & pops the previous `STATE`, as opposed to just switching `STATE` to -2 / -1? In any case this is shaky ground: `]]` and `[[` are not actually in the spec. Also, postponing `TO` is flagged as an ambiguous condition in this standard. GForth only says "Postpone state ends when `[[` is recognized" (not how it ends) and I can't completely follow what `]]` does using `SEE`. In VFX `SEE` seems to show a simple `MOV` just like for `]`. I made `]]` compile-only specifically to skim over this issue, but as your example shows this is easily bypassed. I also used a parsing definition before in my implementation, but Anton's [evil smartness](http://www.euroforth.org/ef98/ertl98.pdf) paper made me think about possibilities. ,------------------------------------------ | 2024-01-31 18:32:54 ruv replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1190 `------------------------------------------ > postponing `TO` is flagged as an ambiguous condition in this standard. I think this ambiguous condition will be removed as being outdated, since `postpone` can be implemented via `find-name` and `name>compile`, or via classic `find`, so that it works correctly when applied to `to`, regardless of how `to` is implemented (see links below). In my test case we can use `postpone if` — it does not matter. > GForth and VFX print the same. [...] In any case this is shaky ground: `]]` and `[[` are not actually in the spec. Yes. So I'm not appealing to the spec, but to **reasonable expectations**. Anyway, due to absent of a specification, it's better not to provide a reference implementation for these words. > I also used a parsing definition before in my implementation, but Anton's evil smartness paper made me think about possibilities. Anton implemented `]]` as a parsing word: https://theforth.net/package/compat/current-view/macros.fs Re state-smartness is evil, — It's only evil when you try to do optimization implementing incorrect execution semantics, or when you rely on incorrect "postpone". See my posts [How POSTPONE should work](https://github.com/ForthHub/discussion/discussions/105) and [About POSTPONE semantics in edge cases](https://github.com/ForthHub/discussion/discussions/103). ,------------------------------------------ | 2024-01-31 19:20:17 lmr replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1191 `------------------------------------------ > not appealing to the spec, but to reasonable expectations. Just so we're on the same page, you expect `]]` to push the current `STATE` and `[[` to pop it (e.g. from the control stack), which is *not what GForth or VFX* currently do? This is easy to implement, but it seems it's not current practice (i.e., you get just 123 from `[ ... 123 . ]] IF/TO/whatever [[ 456 . ...` in GForth and VFX) > absent of a specification, it's better not to I agree, and `POSTPONE?ACTION` (and references to it) can be dropped. I thought it would be interesting to see what this "action-preparing + `EXECUTE`" implementation strategy could achieve. > Anton implemented ]] as a parsing word That is of course possible, and it's basically what I've used before (except string `COMPARE` can be replaced with comparing name-tokens after `FIND-NAME`). But if you try `SEE ]]` in "current" GForth you will see a recognizer-stack-based implementation, and if you try it in VFX you will see something that is probably `#-2 STATE !`. I think both strategies re-use the text-interpreter `PARSE-NAME WHILE` loop and `QUIT`'s `REFILL WHILE` loop (as opposed to having `]]` loop over `PARSE-NAME` and maybe `REFILL`, depending on whether `]]` is multi-line or not). I was referring to the part of the "evil smartness paper" (5.4) that talks about having a separate postpone-xt in addition to interpret-xt and compile-xt (though I haven't actually done that). ,------------------------------------------ | 2024-01-31 19:38:28 lmr replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1192 `------------------------------------------ > `: to, [ 123 . x]] to [[ 456 . ] ;` There's another, more serious divergence from "existing practice" here: with "current" `]]` semantics, `to,` will compile a `]` into the current definition. The word using `to,` will in turn switch `STATE` when called. You can `SEE to,` in GForth. ,------------------------------------------ | 2024-01-31 20:37:24 lmr replies: | requestClarification - loopsys in data? | see: https://forth-standard.org/standard/core/DO#reply-1193 `------------------------------------------ > If you allocate a slot for loop-sys at compile time, it will not work correctly in run-time when recursion occurs (directly or indirectly) — the slot will be overwritten and not restored. That's it. This means `DO` introduces the equivalent of subroutine-local variables, which must be stored on the "call stack" (return stack in Forth) for recursion to work, just like in other languages. ,------------------------------------------ | 2024-01-31 21:34:30 ruv replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1194 `------------------------------------------ > you expect `]]` to push the current STATE and `[[` to pop it (e.g. from the control stack), This is an implementation detail. And I don't expect any implementation details. I expect the behavior shown in the test case. Regarding implementations. Saving the current STATE and then restoring it will *only* work if `]]` is a parsing word or if `postpone` is implemented incorrectly. Thus, if `]]` is not a parsing word, it probably should not change `STATE` at all. It should change another variable, e.g. `PSTATE`. Regarding the interface for `]]`. Why do you prefer the variant without parsing to the variant with parsing? > I was referring to the part of the "evil smartness paper" (5.4) that talks about having a separate postpone-xt in addition to interpret-xt and compile-xt (though I haven't actually done that). Ah, I see. It is also compatible with parsing `]]`. But this approach is not compatible with existing practice of defining immediate parsing words. I implemented postponing mode in the frame of compilation, and it does not require postpone-xt or compile-xt at all, and usual immediate parsing words (including comments) work as expected. See [c-state](https://github.com/ruv/forth-on-forth/blob/master/c-state.readme.txt) in my GitHub repo. ----- > There's another, more serious divergence from "existing practice" here: with "current" `]]` semantics, `to,` will compile a `]` into the current definition. The word using `to,` will in turn switch `STATE` when called. You can `SEE to,` in GForth. Then the word `]]` in VFX and Gforth is broken in edge cases. There is no any obvious formal reason why it should not work as expected. A more formal test case: ``` : lit, postpone literal ; : x]] postpone ]] ; t{ : xif, [ 123 lit, x]] if [[ 456 lit, ] ; -> }t t{ : foo [ xif, ( 123 orig 456 ) lit, ] then [ lit, ] ; -> }t t{ 0 foo 1 foo -> 123 456 123 }t ``` This test case is passed in my system. ,------------------------------------------ | 2024-01-31 22:44:27 lmr replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1195 `------------------------------------------ > I expect the behavior shown in the test case OK so you expect `: ... [ ]] [[` to return to `STATE` 0. Then let me ask you this: do you also expect `: ... [ [ ]` to return to `STATE` 0? If (presumably not), why? > Why do you prefer the variant without parsing to the variant with parsing I'm trying to avoid a parallel `INTERPRET` (and parallel `QUIT`). Centralizing all parsing and all execution (as in my code above, by first stacking up XTs and then calling a single `EXECUTE`) would (vaguley speaking) seem to make it easier to hook up a debugger, profiler, optimizer, doc generator etc. > usual immediate parsing words (including comments) work as expected I see that you prefer it this way, but it's debatable what (for instance) `]] s" s" [[` should do. Or if comments like `]] \ : [[` should act as comments. I guess I prefer the "postpone each `PARSE-NAME`'d word separately" behavior (along with "`[[ ]] [ ]` don't nest" behavior), because otherwise it becomes harder to reason about code. ,------------------------------------------ | 2024-01-31 23:49:56 ruv replies: | referenceImplementation - INTERPRET | see: https://forth-standard.org/standard/core/QUIT#reply-1196 `------------------------------------------ > so you expect `: ... [ ]] [[ ` to return to `STATE` 0. I think, interpretation semantics are not defined for `]]`, so this code is ambiguous. That's why I defined `x]]`. If they are defined to postpone each containing word, than yes, the state after `[[` should be 0 in this case. It's similar to quotations `[: ... ;]` — interpretation semantics are not defined for it, but the reasonable interpretation semantics for this construct are similar to `:noname ... ;`, and `state` is 0 after `;]`. For example: ``` : foo [ [: ." test passed ;] execute ] ." foo end" ; \ it should print "test passed" foo \ it should print "foo end" ``` > do you also expect `: ... [ [ ] ` to return to `STATE` 0? If (presumably not), why? Interpretation semantics are not defined for `[` (see [6.1.2500 `[`](https://forth-standard.org/standard/core/Bracket)), but the expected behavior is to do nothing in interpretation state (and this word is usually implemented like this). Thus, the expected behavior is that `state` is non-zero after `]`. ``` : ... [ \ leave-compilation [ \ do nothing (due to interpretation state) ] \ enter-compilation \ state is non-zero ; ``` ----- > I guess I prefer the "postpone each `PARSE-NAME`'d word separately" behavior Me too, for `]] ... [[`. A more advanced construct should use another name. ,------------------------------------------ | 2024-02-02 12:07:43 ruv replies: | requestClarification - WORD and the text interpreter | see: https://forth-standard.org/standard/core/WORD#reply-1197 `------------------------------------------ > As for users writing their own text interpreter and the result still being a standard system: > - there is no consensus that the Forth standard should support writing a user-defined text interpreter, If the standard will specify Recognizer API, it will support writing a user-defined text interpreter de facto. > There is currently no way to plug a user-defined text interpreter into the system, so your user-defined text interpreter will not change how the system parses. In many use cases a user-defined text interpreter is just called to translate a string or a part of the input source, and then it returns control to the caller. Forth code that is translated may use `WORD` in its turn. The main idea is the following. If the user wants to use the word `WORD`, he should be warned that other components or libraries can also use this word (including the text interpreter that translates user's code), so the result is transient. Probably, a better choice is to use `PARSE` or `PARSE-NAME`. ,------------------------------------------ | 2024-02-05 16:12:39 ruv replies: | requestClarification - An ambiguous condition in LSHIFT | see: https://forth-standard.org/standard/core/LSHIFT#reply-1198 `------------------------------------------ Well, I just checked. Systems typically consider only the low-order bits of _u_ corresponding to the cell size, and ignore the high-order bits. So this ambiguous condition probably cannot be eliminated.