Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 43 |
Nodes: | 6 (0 / 6) |
Uptime: | 94:23:58 |
Calls: | 290 |
Calls today: | 1 |
Files: | 904 |
Messages: | 76,378 |
On 2024-08-11 17:35, albert@spenarnc.xs4all.nl wrote:
I come across a tetris game, and there were bricks defined in
this way:
: DEF-BRICK CREATE 4 0 DO
' EXECUTE 0 DO DUP I CHARS + C@ C, LOOP DROP >> REFILL DROP
LOOP
DOES> ROT 4 * ROT + 2* CHARS + ;
DEF-BRICK BRICK1 S" "
S" ###### "
S" ## "
S" "
Apparently the data field of bricks are filled in some mysterious
way by DEF-BRICK but that is not the subject.
It does some parsing from the input stream, which is kind of
tricky. As REFILL is not present in lina's core, you must
do "-traditional- WANTED" , but that still is not the issue.
I made S" " such that it ALLOT's the string at HERE, to
prevent problems with going out of scope, even in interpret mode.
(Only 256,000,000,000 -10 bytes left).
This doesn't sit well with the definition of BRICK1 ,
that sees its data area grabbed.
You are probably not surprised that tetris doesn't work.
The question is, is it legal to store these temporary strings
in the dictionary in this way?
Strings that are stored relatively to the HERE address may become
invalid after:
- a definition is created via a defining word;
- definitions are compiled with : or :NONAME;
- data space is allocated using ALLOT, `,` (comma),
`C,` (c-comma), or ALIGN.
— as "3.3.3.6 Other transient regions"
<https://forth-standard.org/standard/usage#usage:transient> says.
All affected transition regions shall be listed. If a region is not
listed as affected, than it is not affected by allocating data space memory.
The section "11.3.4 Other transient regions" ><https://forth-standard.org/standard/file#file:buffers> says:
| The system provides transient buffers for S" and S\" strings.
| These buffers shall be no less than 80 characters in length,
| and there shall be at least two buffers. The system should be
| able to store two strings defined by sequential use of
| S" or S\". RAM-limited systems may have environmental
| restrictions on the number of buffers and their lifetimes.
Since this doesn't say that the buffer my become invalid after some
memory allocation, the buffer shall not become invalid after any memory >allocation (by default).
In the same time, a Forth system is allowed to limit the buffer lifetime
(for example, till the next memory allocation), and document it as an >environmental restriction.
[ It was sufficient to replace S" with S"' in order to make it run:
: S"' &" PARSE ;
]
--
Groetjes Albert
Ruvim
On 2024-08-11 17:35, albert@spenarnc.xs4all.nl wrote:
I come across a tetris game, and there were bricks defined in
this way:
: DEF-BRICK CREATE 4 0 DO
' EXECUTE 0 DO DUP I CHARS + C@ C, LOOP DROP >> REFILL DROP
LOOP
DOES> ROT 4 * ROT + 2* CHARS + ;
DEF-BRICK BRICK1 S" "
S" ###### "
S" ## "
S" "
Apparently the data field of bricks are filled in some mysterious
way by DEF-BRICK but that is not the subject.
It does some parsing from the input stream, which is kind of
tricky. As REFILL is not present in lina's core, you must
do "-traditional- WANTED" , but that still is not the issue.
I made S" " such that it ALLOT's the string at HERE,
This is not allowed, without any options.
The alloted data space regions shall be contiguous unless "definitions
are added to or removed from the dictionary between allocations"
(3.3.3.2), or the function of `INCLUDED` is performed (11.6.1.1718, >11.6.2.1714). No other conditions are mentioned anywhere.
to prevent problems with going out of scope, even in interpret mode.
(Only 256,000,000,000 -10 bytes left).
This doesn't sit well with the definition of BRICK1 ,
that sees its data area grabbed.
You are probably not surprised that tetris doesn't work.
The question is, is it legal to store these temporary strings
in the dictionary in this way?
[ It was sufficient to replace S" with S"' in order to make it run:
: S"' &" PARSE ;
]
--
Ruvim
In article <v9cfp9$364en$1@dont-email.me>,is way?
Ruvim <ruvim.pinka@gmail.com> wrote:
Strings that are stored relatively to the HERE address may become
invalid after:
- a definition is created via a defining word;
- definitions are compiled with : or :NONAME;
- data space is allocated using ALLOT, `,` (comma),
`C,` (c-comma), or ALIGN.
— as "3.3.3.6 Other transient regions"
Not relevant. My "transient" region is permanent. That I have
permission to invalidate doesn't affect me.
<https://forth-standard.org/standard/usage#usage:transient> says.
All affected transition regions shall be listed. If a region is not
listed as affected, than it is not affected by allocating data space memory.
My regions are not affected. So again this is not relevant.
The section "11.3.4 Other transient regions"
<https://forth-standard.org/standard/file#file:buffers> says:
| The system provides transient buffers for S" and S\" strings.
| These buffers shall be no less than 80 characters in length,
| and there shall be at least two buffers. The system should be
| able to store two strings defined by sequential use of
| S" or S\". RAM-limited systems may have environmental
| restrictions on the number of buffers and their lifetimes.
A permanent buffer can count as transient.
Since this doesn't say that the buffer my become invalid after some
memory allocation, the buffer shall not become invalid after any memory
allocation (by default).
That is putting restriction to my buffer.
In the same time, a Forth system is allowed to limit the buffer lifetime
(for example, till the next memory allocation), and document it as an
environmental restriction.
Lots of talk of whether the buffers become invalid.
My buffers never become invalid. That is not the point.
The standard talks about transient region. My regions are permanent
and there are other ways to handle S" , say by using ALLOCATE.
To call a region transient and then restrict how transient they are,
make a region not really temporary. So in this respect I am in the clear. Note that as S" is in a definition, the string is bound to be permanent.
So I think the program is not portable, because what I do is perfectly
legal.
I can't make out what you think.
[ It was sufficient to replace S" with S"' in order to make it run:
: S"' &" PARSE ;
]
Okay let's say it out loud. Classic Forth is not fit for handling strings.
A denotation that generates a constant string "blablabla" that has
a status as a number is long overdue.
The mindset of formulating standards is so 70's.
On 2024-08-12 13:31, albert@spenarnc.xs4all.nl wrote:
In article <v9ch3d$364en$2@dont-email.me>,[...]
Ruvim <ruvim.pinka@gmail.com> wrote:
On 2024-08-11 17:35, albert@spenarnc.xs4all.nl wrote:
I made S" " such that it ALLOT's the string at HERE,
This is not allowed, without any options.
The alloted data space regions shall be contiguous unless "definitions
are added to or removed from the dictionary between allocations"
(3.3.3.2), or the function of `INCLUDED` is performed (11.6.1.1718,
11.6.2.1714). No other conditions are mentioned anywhere.
That settles it. Note that it applies to interpret mode only,
during a definition being permanent is not an issue because it is in a
definition.
This is a defect ("bug") in S" in ciforth.
The only solution is to make S" state smart:
: S" STATE @ IF POSTPONE " ELSE &" PARSE ; IMMEDIATE
This implementation implies an environmental restriction: the string
returned by the interpretation semantics of `S"` is valid until a
subsequent invocation of `REFILL`, because the returned string is
located in the input buffer.
[ Before it was an alias for the "-as-a-prefix without the
prefix flag.
: S" POSTPONE " ; IMMEDIATE
In this implementation the interpretation semantics are incorrect, right?
It sticks to the design rule for ciforth that only denotations,
generalisation of numbers, are allowed to be state smart. ]
--
Ruvim
On 13/08/2024 5:34 am, albert@spenarnc.xs4all.nl wrote:
...
In my book the code should be
" "
"###### "
" ## "
" "
DEF-BRICK BRICK1
Instead of
DEF-BRICK BRICK1 S" "
S" ###### "
S" ## "
S" "
The code (untested) could be
: DEF-BRICK CREATE
2>R 2>R 2>R 2>R
2R> ,, 2R> ,, 2R> ,, 2R> ,,
DOES> ... ;
OTOH it's no less difficult to write...
: M" [CHAR] " PARSE HERE OVER ALLOT SWAP MOVE ;
: DEF-BRICK CREATE DOES> ROT 4 * ROT + 2* CHARS + ;
DEF-BRICK BRICK1 M" "
M" ###### "
M" ## "
M" "
On 14/08/2024 08:03, Anton Ertl wrote:
However, if we adopt Gerry Jackson's attitude and make every transient
region permanent, creating a new permanent word (in a separate
section) for every parsed number, string, etc. is fine, and ticking
that word is fine, too. For most programs, the space taken by the
recognized words is proportional to the size of the source code, which
is acceptable on desktops with GBs of RAM. However, programs that use
EVALUATE a lot will need more recognized-word storage. A contrived
example is:
: foo 1000000000 0 ?do s" 123" evaluate drop loop ; foo
I wasn't clear enough when I suggested making transient areas
'permanent'. Currently transient areas are overwritten either by the
user or the system when it decides to re-use the transient region for >something else. If we take the <# buffer as an example, I meant that the
user would declare the memory to be used for that buffer once and that
would be used thereafter. It's permanent in the sense that the
allocation is permanent, not the contents - the system would not be
allowed to corrupt it. THe user would be free to re-use it or to make
the contents permanent by declaring another bit of memory to be used for
the buffer. If the user ALLOCATEd the memory it could later be FREEd by
the user. The user manages it not the system.
--
Gerry
However, if we adopt Gerry Jackson's attitude and make every transient
region permanent, creating a new permanent word (in a separate
section) for every parsed number, string, etc. is fine, and ticking
that word is fine, too. For most programs, the space taken by the
recognized words is proportional to the size of the source code, which
is acceptable on desktops with GBs of RAM. However, programs that use EVALUATE a lot will need more recognized-word storage. A contrived
example is:
: foo 1000000000 0 ?do s" 123" evaluate drop loop ; foo
On 15/08/2024 5:46 am, minforth wrote:
On Wed, 14 Aug 2024 18:49:45 +0000, albert@spenarnc.xs4all.nl wrote:
Ticking a constant or constant string makes no sense.
Try
' +INF
It takes forever.
Some folks think this works :)
' God
On 13-08-2024 06:07, dxf wrote:
On 13/08/2024 5:34 am, albert@spenarnc.xs4all.nl wrote:
...
In my book the code should be
" "
"###### "
" ## "
" "
DEF-BRICK BRICK1
Instead of
DEF-BRICK BRICK1 S" "
S" ###### "
S" ## "
S" "
The code (untested) could be
: DEF-BRICK CREATE
2>R 2>R 2>R 2>R
2R> ,, 2R> ,, 2R> ,, 2R> ,,
DOES> ... ;
OTOH it's no less difficult to write...
: M" [CHAR] " PARSE HERE OVER ALLOT SWAP MOVE ;
: DEF-BRICK CREATE DOES> ROT 4 * ROT + 2* CHARS + ;
DEF-BRICK BRICK1 M" "
M" ###### "
M" ## "
M" "
In 4tH, the easiest solution would be:
: BRICK@ ROT + @C SWAP 2* CHARS + ;
CREATE BRICK1
," "
," ###### "
," ## "
," "
DOES> BRICK@ ;
I could throw a bit of preprocessor magic in the mix, so it would--
resemble your solution even closer, but I guess you can do without ;-)
Hans Bezemer
On 22/08/2024 8:59 pm, albert@spenarnc.xs4all.nl wrote:
In article <nnd$274f6c32$10db022f@ea48fe6bf4bc59ed>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 13-08-2024 06:07, dxf wrote:
On 13/08/2024 5:34 am, albert@spenarnc.xs4all.nl wrote:
...
In my book the code should be
" "
"###### "
" ## "
" "
DEF-BRICK BRICK1
Instead of
DEF-BRICK BRICK1 S" "
S" ###### "
S" ## "
S" "
The code (untested) could be
: DEF-BRICK CREATE
2>R 2>R 2>R 2>R
2R> ,, 2R> ,, 2R> ,, 2R> ,,
DOES> ... ;
OTOH it's no less difficult to write...
: M" [CHAR] " PARSE HERE OVER ALLOT SWAP MOVE ;
: DEF-BRICK CREATE DOES> ROT 4 * ROT + 2* CHARS + ;
DEF-BRICK BRICK1 M" "
M" ###### "
M" ## "
M" "
In 4tH, the easiest solution would be:
: BRICK@ ROT + @C SWAP 2* CHARS + ;
CREATE BRICK1
," "
," ###### "
," ## "
," "
DOES> BRICK@ ;
I dislike the use of parsing here by ," . It happens to work
because ," doesn't destroy the concatenation of HERE.
So you couldn't check the solution without digging into the 4TH
documentation.
In these case parsing is more or less advantageous because it allows
easier represent the bricks. The introduction of an auxiliary word M"
that is easily understood and checked is far superior using ," .
...
For the general case that's true. OTOH 4tH is free to exploit what it has. >The original ANS-Forth version tried using S" but it got complicated due
to the dual-action word. If standard compliance is the goal then options
are limited. OTOH a Gforth user not caring about compliance could exploit >what he had and define things more succinctly:
: M" \"-parse mem, ;
(assuming he knew these words existed)