6.2.2405 VALUE CORE EXT

( x "<spaces>name" -- )

Skip leading space delimiters. Parse name delimited by a space. Create a definition for name with the execution semantics defined below, with an initial value equal to x.

name is referred to as a "value".

name Execution:

( -- x )

Place x on the stack. The value of x is that given when name was created, until the phrase x TO name is executed, causing a new value of x to be assigned to name.

TO name Run-time:

( x -- )

Assign the value x to name.

See:

Rationale:

Typical use:
0 VALUE data

: EXCHANGE ( n1 -- n2 ) data SWAP TO data ;

EXCHANGE leaves n1 in data and returns the prior value n2.

Testing:

T{  111 VALUE v1 -> }T
T{ -999 VALUE v2 -> }T
T{ v1 ->  111 }T
T{ v2 -> -999 }T
T{ 222 TO v1 -> }T
T{ v1 -> 222 }T

T{ : vd1 v1 ; -> }T
T{ vd1 -> 222 }T

T{ : vd2 TO v2 ; -> }T
T{ v2 -> -999 }T
T{ -333 vd2 -> }T
T{ v2 -> -333 }T
T{ v1 ->  222 }T

ContributeContributions

EricBlakeavatar of EricBlake [387] Compilation of a VALUE child word should not inline its current valueSuggested Testcase2025-07-26 18:27:56

The existing tests of VALUE do not exercise what happens if a value word is compiled, its contents then changed with TO, and then that earlier compilation is executed.

I was working on an optimizing version of COMPILE, in my implementation, and noticed (along with other LITERAL/LIT, behaviors) that when compiling a word that is a child of CONSTANT or VALUE, I could inline the value produced by executing those child words at compilation time, and nearly made the mistake of doing the same for children of VARIABLE. The current testsuite did not flag my mistake, even though it is not in line with traditional semantics. Therefore, I suggest adding this after the existing tests:

T{ 333 TO v1 -> }T
T{ vd1 -> 333 }T

to prove that vd1 was compiled with a reference to the dynamic contents of v1, and not to the inline value that v1 happened to have at the time vd1 was defined.

GerryJacksonavatar of GerryJackson

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.

AntonErtlavatar of AntonErtl

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.

GerryJacksonavatar of GerryJackson

OK, I've added the suggested tests to file coreexttest.fth

GerryJacksonavatar of GerryJackson

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

AntonErtlavatar of AntonErtl

This website currently reflects Forth-2012, and AFAIK the tests come from the Forth-2012 document (which took them out of the test suite around 2012). When we release the next standard, the document and the tests in there will be updated (hopefully in some automated way). And maybe we will do the tests on this website directly from the test suite at some point. In any case, if you want to use up-to-date tests, go to the source.

Reply New Version