6.1.2070 R@ r-fetch CORE

Interpretation:

Interpretation semantics for this word are undefined.

Execution:

( -- x ) ( R: x -- x )

Copy x from the return stack to the data stack.

See:

Testing:

ContributeContributions

poggingfishavatar of poggingfish [240] Suggested reference implementation2022-06-20 17:40:33

: R@ R> dup >R ;

ruvavatar of ruv

: R@ R> dup >R ;

This variant is incorrect.

Implementation dependent variants:

: r@ ( -- x ) ( R: x addr -- x addr ) r> r> tuck >r >r ;
: r@ ( -- x ) ( R: x addr -- x addr ) 2r> over >r >r ;

These variants are not standard compliant since they conflicts with 3.2.3.3 Return stack and they will not work on some systems (nevertheless, it's acceptable for reference implementations).

A portable variant (standard compliant):

: r@ postpone r> postpone dup postpone >r ; immediate

ruvavatar of ruv

: R@ R> dup >R ;

This variant is incorrect.

Well, actually this variant can be used in some systems (i.e., it's implementation dependent too), namely for systems in which nest-sys always takes 0 cells (see initiation semantics for colon and noname) . While the implementation dependent variants provided by me are for systems in which nest-sys always takes 1 cell (majority of Forth systems without an optimizing compiler).

But all variants in which r@ is defined as an ordinary word don't support some expected equivalences. Namely, it means that the compilation semantics for such r@ can be performed by applying execute to its xt as ['] r@ compile,, and then the following test case will fail:

: execute >r r@ execute r> drop ;
: compile, postpone literal postpone execute ;
: [execute] execute ; immediate
bl word r@ ' find ] [execute] [ nip -1 = [if]
  t{ :noname 123 >r [ ' r@ compile, ] r> drop ; execute -> 123 }t
[else]
  .( The test-case is not applicable to this Forth system ) cr
[then]

So I would consider such implementations as incorrect.

As a real life example, Gforth 0.7.9_20220428 fails this testcase.

ruvavatar of ruv

the compilation semantics for such r@ can be performed

by applying execute to its xt

It's a typo. It should be read as: "by applying compile, to its xt"

AntonErtlavatar of AntonErtl

Concerning

: r@ postpone r> postpone dup postpone >r ; immediate

This definition has other than default compilation semantics, while the standard r@ has default compilation semantics. This makes a difference for [compile].

ruvavatar of ruv

This definition has other than default compilation semantics,

Now I can't agree on that, since a program cannot detect other than default compilation semantics for this r@.

If the compilation semantics for a word are to appends its execution semantics — then these compilation semantics are equivalent to a default (see 3.4.3.3 Compilation semantics), i.e. they cannot be operationally distinguishable.

A program can test that the compilation semantics for this r@ are to append the execution semantics that are specified in the glossary entry.

In the same time, a program don't have other way to test the execution semantics for r@, since a system is allowed to not provide an execution token that identifies the execution semantics for r@ at all, since interpretation semantics for r@ are undefined by the standard. In other words, no xt may be considered as an identifier of the execution semantics for r@ that are specified in the glossary entry.

This makes a difference for [compile].

Yes, we discussed that. It's a built-in problem of the word [compile] by design. And it's one of reasons why this word will be removed from the standard (destandardized).


BTW, my test case contains several shortcomings:

  1. Tick can be applied to the name r@ only if find in interpretation state and in compilation state returns the same values for this name (so it should be checked before use Tick in this case).
  2. Instead of Tick, the result of find in compilation state can be used (and than no need for the double check).
  3. word returns a counted string in a transient buffer that may be invalid after parsing next lexeme.

A better variant:

: execute >r r@ execute r> drop ;

: []compile' ( t "ccc" -- t )
  state @ 0= -14 and throw
  bl word find dup 0= -13 and throw 1 =
  if execute else postpone literal postpone execute then
; immediate

t{ :noname 123 >r []compile' r@  r> drop ; execute -> 123 }t

ruvavatar of ruv

: r@ postpone r> postpone dup postpone >r ; immediate

This definition has other than default compilation semantics,

a program cannot detect other than default compilation semantics for this r@.

On the other hand, in some cases a program can conclude that this word is an immediate word: if find returns the same ( xt 1 ) independently on STATE, then the word is immediate (but the converse does not hold). By that, the program has actually obtained an xt for r@, but this xt doesn't identify the execution semantics specified in the glossary entry, and this is allowed (due to the corresponding condition in 4.1.2 Ambiguous conditions).

So under the hood this r@ can be treated a as a word having other than default compilation semantics, but as a black box, this implementation meets the specification.


If r@ is implemented as an ordinary word, a program can also obtain the xt of this word during text interpreting. But, to perform the compilation semantics for r@, in this case the program should rely that this xt identifies the execution semantics specified in the glossary entry. And this approach doesn't work in edge cases.

Reply New Version