http://www.quirkster.com/forth/fgp.html
I've been doing the development using GNU Forth. I'd be curious to
know how fast the playouts are in a compiled Forth.
I have heard rumors of two other attempts: a paper by Prof. Ting was
in the Sept. 1983 Dr. Dobbs, and some early work by Chuck Moore was
mentioned in this newsgroup a few years ago. Does anyone know where I
could find either of these sources online?
Ian Osgood
> The success of a Monte Carlo programming technique called UCT at the
> last Computer Olympiad has spurred me to write a simple Go player in
> Forth. You can find my work here:
> http://www.quirkster.com/forth/fgp.html
> I've been doing the development using GNU Forth. I'd be curious to
> know how fast the playouts are in a compiled Forth.
Where? How? What ;-?
> I have heard rumors of two other attempts: a paper by Prof. Ting was
> in the Sept. 1983 Dr. Dobbs, and some early work by Chuck Moore was
> mentioned in this newsgroup a few years ago. Does anyone know where I
> could find either of these sources online?
The latter one, I don't know. Why not ask Chuck himself?
A few nits:
* All lower case: can't test on eForth64 directly.
* go-test
\ include ../timer.frt ( not needed? )
\ { xt } ( 2* ) non-standard local syntax
* go-bitmap
\ 1 cells constant cell ( undefined )
\ 'O ( should be 'O' or [char] O )
\ I don't understand the usefulness of the following:
hex
create central
55 , 45 , 54 , 65 , 56 , 46 , 44 , 64 , 66 ,
35 , 34 , 33 , 43 , 53 , 63 , 73 , 74 , 75 ,
76 , 77 , 67 , 57 , 47 , 37 , 36 , 25 , 24 ,
23 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 83 ,
84 , 85 , 86 , 87 , 88 , 78 , 68 , 58 , 48 ,
38 , 28 , 27 , 26 , 51 , 41 , 31 , 21 , 12 ,
13 , 14 , 15 , 16 , 17 , 18 , 92 , 93 , 94 ,
95 , 96 , 97 , 98 , 89 , 79 , 69 , 59 , 49 ,
39 , 29 , 81 , 71 , 61 , 11 , 91 , 19 , 99 ,
does> ( i -- x y ) swap cells + @ 10 /mod ;
decimal
\ I guess it's nice gForth knows what you mean :-)
\ : best-playout { N -- x y } ( non-standard locals )
FORTH> CR test
bd OK
-1 81
. @ . . . . . O .
@ . . @ . . . . O
. . @ O @ . . . .
. . O . O . . . .
. . . O . . . . .
. . . . . . . . .
. . . . . . . . .
@ . . . . . . . O
. @ . . . . . O . | Black(@) to move, ko:0
atari? 0
. @ . . . . . O .
@ . . @ . . . . O
. . @ . @ . . . .
. . O @ O . . . .
. . . O . . . . .
. . . . . . . . .
. . . . . . . . .
@ . . . . . . . O
. @ . . . . . O . | White(O) to move, ko:-1
-1
ok
Instant result, this isn't much of a test?
-marcel
-------------------------------------------------------------
Go, unfortunately with iForthisms: in 1992 I was still young.
-------------------------------------------------------------
\ /dfwforth/examples/games/go.frt
(*
* LANGUAGE : ANS Forth
* PROJECT : Forth Environments
* DESCRIPTION : Game of GO
* CATEGORY : Example
* AUTHOR : C.H. Ting, Dr. Dobb's Toolbook of Forth; page 28.
* LAST CHANGE : October 4, 1992, Marcel Hendrix
*)
REVISION -go "ÄÄÄ The Game of GO Version 0.00 ÄÄÄ"
PRIVATES
DOC Notes
(*
I do not play GO, so I don't know if this game works :-)
dr. Ting notices that because of the recursion used, blocks of more than
100 connected stones can lead to a system crash.
(xForth allows setting up custom stacks, see for instance ACKERMAN.FRT)
*)
ENDDOC
0 VALUE color PRIVATE
0 VALUE liberty PRIVATE
1 =: black PRIVATE
2 =: white PRIVATE
CREATE map PRIVATE #362 ALLOT
: ?OUT DUP 0< OVER #360 > OR ; PRIVATE
: ?STONE map + C@ ; PRIVATE \ <index> --- <code>
: NORTH #19 - ; PRIVATE \ <n1> --- <n2>
: SOUTH #19 + ; PRIVATE \ <n1> --- <n2>
: EAST DUP #19 MOD #18 = IF DROP #1000 \ <n1> --- <n2>
ELSE 1+
ENDIF ; PRIVATE
: WEST DUP #19 MOD IF 1- \ <n1> --- <n2>
ELSE DROP #1000
ENDIF ; PRIVATE
: MARK map + DUP C@ #128 OR \ <index> --- <>
SWAP C! ; PRIVATE
: COUNTS RECURSIVE
?OUT IF DROP EXIT ENDIF
DUP ?STONE
color = IF DUP MARK
DUP NORTH COUNTS
DUP EAST COUNTS
DUP SOUTH COUNTS
WEST COUNTS
ELSE DUP ?STONE 0= IF MARK 1 +TO liberty
ELSE DROP
ENDIF
ENDIF ; PRIVATE
#361. ==: LIMITS PRIVATE
: BK ." ±±" ; PRIVATE
: WT >INVERSE< ." " >INVERSE< ; PRIVATE
: CROSS ." .." ; PRIVATE
: IND 2 SPACES #19 0 DO I 2 .R LOOP ; PRIVATE
: BOARD HOME IND
LIMITS DO
I #19 /MOD SWAP 0= IF CR 2 .R ELSE DROP ENDIF
I ?STONE 3 AND DUP 0= IF CROSS DROP
ELSE black = IF BK ELSE WT ENDIF
ENDIF
LOOP ; PRIVATE
: PLACE map + C! ; PRIVATE \ <code> <n> --- <>
: GOBASE #19 BASE ! ; PRIVATE
: HANDICAP [ GOBASE ]
33 39 3F 93 99 9F F3 F9 FF
9 0 DO black SWAP PLACE LOOP
[ DECIMAL ] ; PRIVATE
: CLRMAP map #362 ERASE ; PRIVATE
: KSTONE map + C0! ; PRIVATE \ <n> --- <>
: PUT SWAP DO color map I + C! LOOP ; PRIVATE
: KMARK map + DUP C@ #64 OR SWAP C! ; PRIVATE
: REMOVE RECURSIVE \ <n> --- <>
?OUT IF DROP EXIT ENDIF
DUP ?STONE #67 AND color
= IF DUP KMARK
DUP NORTH REMOVE
DUP EAST REMOVE
DUP SOUTH REMOVE
DUP WEST REMOVE
KSTONE
ELSE DROP
ENDIF ; PRIVATE
: UNMARK map #361 OVER + \ <pattern> --- <>
SWAP DO
I C@ OVER = IF I C@ 3 AND I C!
ENDIF
LOOP
DROP ; PRIVATE
: DESIGNATE LIMITS DO
I ?STONE #128 = IF black I PLACE LEAVE
ENDIF
LOOP ; PRIVATE
0 VALUE best-move PRIVATE
0 VALUE best-liberties PRIVATE
0 VALUE best-count PRIVATE
: LOOKAHEAD color >S \ <move> --- <liberties>
black OVER PLACE
black TO color CLEAR liberty
#128 UNMARK #129 UNMARK
DUP COUNTS KSTONE
S> TO color liberty ; PRIVATE
: EVAL OVER LOOKAHEAD >S S \ <move> <liberty> --- <>
best-count 1 MAX >
OVER best-liberties <=
AND IF TO best-liberties TO best-move S> TO best-count
ELSE 2DROP -S
ENDIF ; PRIVATE
CREATE pattern PRIVATE
$1010 , $14 , $44 , $1400 , $4400 , $1001 ,
$0110 , $404 , $401 , $101 , $104 , $1010 ,
: ?RANGE CREATE PRIVATE , \ <> --- <>
DOES> @EXECUTE \ <> --- <code>
?OUT IF DROP black
ELSE ?STONE 3 AND
ENDIF ; PRIVATE
' NORTH ?RANGE ?N
' SOUTH ?RANGE ?S
' WEST ?RANGE ?W
' EAST ?RANGE ?E
: +4* 0 8 0 DO 2 LSHIFT + \ <n8> .. <n1> --- <n>
LOOP ; PRIVATE
: PNORTH DUP ?N IF DROP 0 EXIT ENDIF \ <move> --- <pattern>
>S
S NORTH ?E
S ?E
S NORTH EAST DUP ?E SWAP ?N
S NORTH ?W
S ?W
S> NORTH WEST DUP ?W SWAP ?N
+4* ; PRIVATE
: PEAST DUP ?E IF DROP 0 EXIT ENDIF \ <move> --- <pattern>
>S
S EAST ?S
S ?S
S EAST SOUTH DUP ?S SWAP ?E
S EAST ?N
S ?N
S> EAST NORTH DUP ?N SWAP ?E
+4* ; PRIVATE
: PSOUTH DUP ?S IF DROP 0 EXIT ENDIF \ <move> --- <pattern>
>S
S SOUTH ?E
S ?E
S SOUTH EAST DUP ?E SWAP ?S
S SOUTH ?W
S ?W
S> SOUTH WEST DUP ?W SWAP ?S
+4* ; PRIVATE
: PWEST DUP ?W IF DROP 0 EXIT ENDIF \ <move> --- <pattern>
>S
S WEST ?S
S ?S
S WEST SOUTH DUP ?E SWAP ?W
S WEST ?N
S ?N
S> WEST NORTH DUP ?N SWAP ?W
+4* ; PRIVATE
: FIX DUP ROT AND ; PRIVATE \ <n> <mask> --- <mask> <bool>
: MATCH DUP 0= ?EXIT \ <pattern> --- <flag>
FALSE
#12 0 DO OVER
I pattern []CELL @
FIX = IF DROP TRUE LEAVE
ENDIF
LOOP
NIP ; PRIVATE
: EVPAT 1 TO best-count 2 EVAL ; PRIVATE
: PATS LIMITS DO
I ?STONE white AND 0= ?LEAVE
I PNORTH MATCH IF I NORTH EVPAT LEAVE ENDIF
I PEAST MATCH IF I EAST EVPAT LEAVE ENDIF
I PSOUTH MATCH IF I SOUTH EVPAT LEAVE ENDIF
I PWEST MATCH IF I WEST EVPAT LEAVE ENDIF
LOOP ; PRIVATE
0 VALUE ?stop PRIVATE
: STOP CLEAR ?stop ; PRIVATE
: UNMARKS #129 UNMARK #130 UNMARK TO color ; \ <color> --- <>
PRIVATE
: EXAMINE #128 UNMARK CLEAR liberty \ <> --- <liberty>
COUNTS liberty ; PRIVATE
: WCHO 0
#341 #19 DO
I #19 MOD ?DUP IF #18 - IF I ?STONE
#128 = IF I ENDIF
ENDIF
ENDIF
LOOP ; PRIVATE
: CHO BEGIN ?DUP WHILE liberty EVAL REPEAT ; PRIVATE
: ?CHO best-liberties liberty >= ; PRIVATE
: BCHO 0 LIMITS DO I ?STONE #128 = IF I ENDIF LOOP ; PRIVATE
: WEFFECT black UNMARKS #360 TO best-liberties
LIMITS DO
I ?STONE black
= IF I EXAMINE
0= IF I REMOVE
ELSE liberty 3 < IF ?CHO IF WCHO CHO ENDIF
ENDIF
ENDIF
ENDIF
LOOP ; PRIVATE
: BEFFECT white UNMARKS
LIMITS DO
I ?STONE white
= IF I EXAMINE
1 = IF DESIGNATE I REMOVE STOP LEAVE
ELSE ?CHO IF BCHO CHO ENDIF
ENDIF
ENDIF
LOOP ; PRIVATE
: GET# PAD #19 ACCEPT \ <> --- <n>
PAD SWAP NUMBER?
1 <> ABORT" huh" ; PRIVATE
: ?MOVE BEGIN CR ." Your move: " EOL
GET# DUP .
?OUT IF ." range? " DROP 0
ELSE DUP ?STONE 3 AND
0= IF white SWAP PLACE 1
ELSE ." occupied." DROP 0
ENDIF
ENDIF
UNTIL ; PRIVATE
: .BEST 3 SPACES
best-move DEC.
best-count DEC.
best-liberties DEC. ; PRIVATE
: RESUME BEGIN BOARD ?MOVE
TRUE TO ?stop CLEAR best-count
WEFFECT .BEST BEFFECT .BEST
?stop IF PATS black best-move .BEST PLACE
ENDIF
AGAIN ;
: MAIN CLS GOBASE CLRMAP HANDICAP RESUME ;
:ABOUT CR ." Type MAIN to start, RESUME to continue." CR ;
.ABOUT -go CR
DEPRIVE
(* End of Source *)
On Jul 16, 3:53 pm, m...@iae.nl (Marcel Hendrix) wrote:
> Ian Osgood <i...@quirkster.com> writes Re: Forth Go Program
>
> > The success of a Monte Carlo programming technique called UCT at the
> > last Computer Olympiad has spurred me to write a simple Go player in
> > Forth. You can find my work here:
> > http://www.quirkster.com/forth/fgp.html
> > I've been doing the development using GNU Forth. I'd be curious to
> > know how fast the playouts are in a compiled Forth.
>
> Where? How? What ;-?
Sorry, I forget that the source is not enough sometimes. :-)
include go-bitmap.f
go \ will report P playouts per N seconds
x y mv \ place a stone. x,y=[1..9], where 1 1 is at top left
of .board
P TO playout-limit \ change max playouts and time to think (seconds)
N to time-limit
> A few nits:
>
> * All lower case: can't test on eForth64 directly.
Do you know of a tool for converting ANS Forth keywords to uppercase?
> * go-test
> \ include ../timer.frt ( not needed? )
Just has this utility which I use frequently.
: time: ( "word" -- )
utime 2>R ' EXECUTE utime 2R> D-
<# # # # # # # [char] . HOLD #S #> TYPE ." seconds" ;
> \ { xt } ( 2* ) non-standard local syntax
So standardize it already! ;-)
> \ 1 cells constant cell ( undefined )
> \ : best-playout { N -- x y } ( non-standard locals )
RfD: add CELL and CELL- to the standard.
> \ 'O ( should be 'O' or [char] O )
OK. BTW, GNU Forth 'O' is different:
'O . 'O' . \ 79 20263
> \ I don't understand the usefulness of the following:
> hex
> create central
> 55 , 45 , 54 , 65 , 56 , 46 , 44 , 64 , 66 ,
> 35 , 34 , 33 , 43 , 53 , 63 , 73 , 74 , 75 ,
> 76 , 77 , 67 , 57 , 47 , 37 , 36 , 25 , 24 ,
> 23 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 83 ,
> 84 , 85 , 86 , 87 , 88 , 78 , 68 , 58 , 48 ,
> 38 , 28 , 27 , 26 , 51 , 41 , 31 , 21 , 12 ,
> 13 , 14 , 15 , 16 , 17 , 18 , 92 , 93 , 94 ,
> 95 , 96 , 97 , 98 , 89 , 79 , 69 , 59 , 49 ,
> 39 , 29 , 81 , 71 , 61 , 11 , 91 , 19 , 99 ,
> does> ( i -- x y ) swap cells + @ 10 /mod ;
> decimal
> \ I guess it's nice gForth knows what you mean :-)
Hah! It is funny that GNU Forth allows this! Of course, it should be:
: coordinate-table create does> ( i -- x y ) swap cells + @ 10 /mod ;
coordinate-table central 55 , ( etc.)
In fact, I'll do the same for the row bitcount table.
> FORTH> CR test
[correct output omitted]
> Instant result, this isn't much of a test?
Just fine for a unit test (which passed).
> -marcel
>
> -------------------------------------------------------------
> Go, unfortunately with iForthisms: in 1992 I was still young.
> -------------------------------------------------------------
> \ /dfwforth/examples/games/go.frt
>
> (*
> * LANGUAGE : ANS Forth
> * PROJECT : Forth Environments
> * DESCRIPTION : Game of GO
> * CATEGORY : Example
> * AUTHOR : C.H. Ting, Dr. Dobb's Toolbook of Forth; page 28.
> * LAST CHANGE : October 4, 1992, Marcel Hendrix
> *)
Thanks! I'll take a look at it. Is this mostly Prof. Ting's work
ported to iForth?
(BTW, your line profiler was again very useful.)
Ian Osgood
go many
( or : x begin go again ; x )
It starts of with
FORTH> go 400 playouts in 1 seconds
Best move: (winrate:28/44 mv: 6 8 ) 63408 bytes used
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . @ . . .
. . . . . . . . . | White(O) to move ok
FORTH> go 400 playouts in 1 seconds
Best move: (winrate:22/31 mv: 4 5 ) 81576 bytes used
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . O . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . @ . . .
. . . . . . . . . | Black(@) to move ok
... ( unfortunately .. )
400 playouts in 163 milliseconds
Best move: (winrate:2/2 mv: 0 0 ) 9624 bytes used
O O O . O . O O O
O O O O O O O O .
. O . O . O . O O
O O O O O O O O O
O . O O . O O . .
O O O O . O O O O
O O O O . O O O O
O O O O O O O . O
O . O . O . O O O | White(O) to move
Caught exception 0xc0000005
ACCESS VIOLATION
instruction pointer = $467191
EAX = $0000042A EBX = $00471FC7
ECX = $0000002C EDX = $0000000F
ESI = $005329C0 EDI = $0000042A
EBP = $00443FC4 ESP = $09C07A08
hardware exception in ``/STRING''+$00000049
**** STACK DUMP ****
MOVE (+$00000057)
$0044C480 (4506752)
hist-push (+$0000001D)
pass (+$0000001E)
random-candidate (+$00000136)
playout (+$00000030)
uct-playout (+$0000006F)
uct-playout (+$0000004B)
uct-playout (+$0000004B)
uct-playout (+$0000004B)
FORTH> playout-limit . 400 ok
FORTH> 4000 to playout-limit ok
FORTH> EDIT ok
FORTH> reset ok
FORTH> go 4000 playouts in 6857 milliseconds
Best move: (winrate:127/246 mv: 3 5 ) 934848 bytes used
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . @ . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . . | White(O) to move ok
-marcel
Could it be that with a faster gforth also 'bytes used' goes up
and a Forth/program/buffer limit is exceeded? It didn't help
to start with gforth-fast -m 8 M or gforth-fast -r 1M -d 1M -m 8M .
My first idea would be to expect a return stack error, but gForth
would have caught that?
-marcel
--
( Intel PIV 3 GHz, Windows XP )
( gforth )
C:\Program Files\gforth>gforth
Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
include go-bitmap.frt
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . . | Black(@) to move
ok
go 400 playouts in 3177 milliseconds
Best move: (winrate:25/39 mv: 6 7 ) 74928 bytes used
( gforth-fast )
C:\Program Files\gforth>gforth-fast
Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
include go-bitmap.frt
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . . | Black(@) to move
ok
go
*the terminal*:2: Invalid memory address
go
^^
Backtrace:
> go many
> ( or : x begin go again ; x )
Yes, this needs to test an end condition (two passes in a row). The
existing pass counter is only for the playouts; a test similar to is-
ko? which checks for three consecutive repeated board positions in the
history stack would be appropriate for detecting end-of-game at the
top level.
> FORTH> go 4000 playouts in 6857 milliseconds
> Best move: (winrate:127/246 mv: 3 5 ) 934848 bytes used
Nice! That is ten times faster than gforth or gforth-fast on my system
(2.3GHz Core2Duo).
I uploaded a new version of go-bitmap.f with your suggestions.
Ian Osgood
That comes from a bug in gcc-2.95 on i386. Transcendental functions
destroy the TOS register. Either compile Gforth with a different gcc,
or work around the bug as follows:
time ~/gforth/gforth-fast -e ": flog 0 flog drop ; : fsqrt 0 fsqrt drop ;" go-bitmap.f -e "go bye"
It does not happen with the debugging gforth because that does not
keep the TOS in a register.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2007: http://www.complang.tuwien.ac.at/anton/euroforth2007/
It's about 1.86 times faster than gforth-fast on a 3GHz Xeon 5160.
To be fair, I also compared with iForth on the same machine:
[c8:~/forth-bench:9439] time ~/gforth-amd64/gforth-fast go-bitmap.f -e "4000 to playout-limit 1000 to time-limit reset go bye" >/dev/null
real 0m13.342s
user 0m12.745s
sys 0m0.160s
[c8:~/forth-bench:9440] time iforth "include go-bitmap.f 4000 to playout-limit 1000 to time-limit reset go bye" >/dev/null
real 0m4.916s
user 0m4.784s
sys 0m0.020s
I.e., a factor of 2.66.
Speedups on Gforth could come from using struct fields for
implementing words like
: n>next @ ;
: n>child CELL+ @ ;
: n>visits 2 CELLS + @ ;
: n>wins 3 CELLS + @ ;
: n>move 4 CELLS + 2@ ;
or at least using LITERAL
tr a-z A-Z <go-bitmap.f
But I think Marcel should just fix eForth64.
>: time: ( "word" -- )
> utime 2>R ' EXECUTE utime 2R> D-
> <# # # # # # # [char] . HOLD #S #> TYPE ." seconds" ;
Instead of using UTIME (wallclock time) I recommend CPUTIME D+ (CPU
time) or CPUTIME 2DROP (user time).
>> \ { xt } ( 2* ) non-standard local syntax
>> \ : best-playout { N -- x y } ( non-standard locals )
>
>So standardize it already! ;-)
The users of the few systems that don't implement { yet can INCLUDE
http://www.complang.tuwien.ac.at/forth/anslocal.fs, which is good
enough for the usage above.
>RfD: add CELL and CELL- to the new standard. I seem to use them in
>every program I write.
Go ahead. CELL/ might also be interesting.
>> \ 'O ( should be 'O' or [char] O )
>
>OK. (BTW, in GNU Forth 0.6.2:
> 'O . ( 79) 'O' . ( 20263)
In the development version, both of these versions return 79.
> Ian Osgood <ia...@quirkster.com> writes:
>>On Jul 16, 9:42 pm, m...@iae.nl (Marcel Hendrix) wrote:
>>> FORTH> go 4000 playouts in 6857 milliseconds
>>> Best move: (winrate:127/246 mv: 3 5 ) 934848 bytes used
>>
>>Nice! That is ten times faster than gforth or gforth-fast on my system
>>(2.3GHz Core2Duo).
>It's about 1.86 times faster than gforth-fast on a 3GHz Xeon 5160.
> To be fair, I also compared with iForth on the same machine:
[..]
> I.e., a factor of 2.66.
gForth is doing Really Good. It's the first time I see it come so near
to VfxForth:
( gforth-fast with flog and fsqrt fixes )
go 4000 playouts in 15369 milliseconds
Best move: (winrate:104/193 mv: 5 4 ) 1025856 bytes used
( VfxForth )
go 4000 playouts in 9968 milliseconds
Best move: (winrate:178/337 mv: 5 5 ) 1039128 bytes used
-marcel
This will convert _everything_ including comments...
my .01999...
--
Cesar Rabak
Sure, and that's as it should be: If someone prefers to use a system
that requires standard Forth words to be in upper case, then he sure
prefers the comments to be in upper case, too. Moreover, he can still
look at the source code for reading the comments *and* the code in a
readable form.
A more serious problem would be file names; on many OSs they are case
sensitive, so they should not be upper cased.
I had plans to write a tool that would, for every included file, write
out a version that has all word name uses changed to the case used in
the definition, and to define all standard names in upper case. Using
this tool would turn a program requiring case insensitivity into a
program without this environmental dependency. I never got around to
it, and nowadays I think that it makes more sense to standardize on
being able to use standard names in lower case.
OK, if this is your desire. I find more readable to keep comments with
capitalized words when starting phrases, proper nouns, etc., and
writting in lower case.
So I found reasonable to warn!
> Moreover, he can still
> look at the source code for reading the comments *and* the code in a
> readable form.
>
> A more serious problem would be file names; on many OSs they are case
> sensitive, so they should not be upper cased.
Yes.
>
> I had plans to write a tool that would, for every included file, write
> out a version that has all word name uses changed to the case used in
> the definition, and to define all standard names in upper case. Using
> this tool would turn a program requiring case insensitivity into a
> program without this environmental dependency. I never got around to
> it, and nowadays I think that it makes more sense to standardize on
> being able to use standard names in lower case.
Except if you go a long list of words, a quick approach (say up to one
to two thousand wordsš, would be to write a script in AWK, Perl, Python
or Ruby which would post process your source file.
In present technology {desk,lap}tops even for large Forth source files
should have acceptable performance.
I understand the details of a such script would be OT here, so I leave
as a suggestion.
HTH
--
Cesar Rabak
[1] Which could be collected during a period in the shop where the
script would be put in production use.
I realize I can help you with the Ting if you'll email me offline.
Best, Charles
> I had plans to write a tool that would, for every included file, write
> out a version that has all word name uses changed to the case used in
> the definition, and to define all standard names in upper case. Using
> this tool would turn a program requiring case insensitivity into a
> program without this environmental dependency. I never got around to
> it, and nowadays I think that it makes more sense to standardize on
> being able to use standard names in lower case.
>
I think I've mentioned before the program "ansify" by Ulrich Hoffman,
which does uppercase standard words. Here I quote the preamble to the
version I happen to have:
<quote>
\ Convert ANSI Forth standard definition names from lower to upper case.
\ $Id: ansify.seq,v 1.3 1994/09/22 13:10:37 uho Exp $
\ This file contains code to convert ANSI Forth source code
\ with standard definition names written in lower case (environmental
\ dependency) to source code with standard definition names written in
\ UPPER case. It thus helps porting ANSI Forth code written for case
\ insensitive systems to case sensitive systems.
\ This code can be used and copied free of charge. All rights reserved.
\ Comments, hints and bug reports are welcome. Please email
\ to
\ u...@pizzicato.deceiver.org
\ or
\ u...@informatik.uni-kiel.d400.de
\ Ulrich Hoffmann
\ Sehestedter Strasse 26
\ 24340 Eckernfoerde
\ Germany
\ Thanks to J.Plewe for his helpful hints.
\
</quote>
I expect it must be findable on the web or I could provide copies by email
(or I could post the whole file, if that wouldn't be a waste of
bandwidth).
I do agree that standardizing lower case standard words is a good idea.
regards to all cgm
> I expect it must be findable on the web or I could provide copies by email
> (or I could post the whole file, if that wouldn't be a waste of
> bandwidth).
It can be found with ( sorry, can't give a decent reference for technical reasons )
http://www.google.com/custom?num=100&hl=en&lr=&safe=off&client=pub-9448921371862747&cof=L%3Ahttp%3A%2F%2Fquartus.net%2Fq.jpg%3BLH%3A48%3BLW%3A44%3BLP%3A1%3BBGC%3A%23FFFFFF%3BT%3A%23000000%3BLC%3A%230000CC%3BVLC%3A%230000CC%3BALC%3A%230000CC%3BGALT%3A%23008000%3BGFNT%3A%23000000%3BGIMP%3A%23000000%3BDIV%3A%230000CC%3BLBGC%3A%23FFFFFF%3BAH%3Acenter%3BS%3Ahttp%3A%2F%2Fquartus.net%2Fforth%3BCX%3AQuartus%252Enet%2520Forth%2520Search%2520Engine%3B&q=ansify&cx=008193674707816620280%3A1qayaf_i0fw
at: http://win32forth.sourceforge.net/downloads.htm
It works really well, because in essence it redefines all standard Forth
words to either print in uppercase ( e.g. DUP ) or execute their default
behavior ( e.g. \ ). Unrecognized words are simply echoed, but that
behavior can be tuned on a per word basis.
-marcel
> Nice! That is ten times faster than gforth or gforth-fast on my system
> (2.3GHz Core2Duo).
> I uploaded a new version of go-bitmap.f with your suggestions.
I am *very* happy to report that eForth64 runs your new go-bitmap
flawlessly (Your program is very complex, so I was dreading quite a few hard
to find new compiler bugs.). There were only two problems:
1. 2, was interpreted as 2. because 2, is not defined (an eForth64 extension
of double-number behavior), so the recursion crashed initially
2. the default dictionary was too small (64-bits and 1 MB allotable space
doesn't work well for your use of , :-)
I now get 3968 playouts in 10000 milliseconds, which is only 50% worse
than iForth and equivalent to almost eactly the same as VFX (both on an Intel
PIV 3 GHz).
-marcel
Not really. Nor do I desire to uppercase the code.
> I find more readable to keep comments with
>capitalized words when starting phrases, proper nouns, etc., and
>writting in lower case.
Sure, and I would suggest to go to the source for that. The converted
version is useful only for running on some deficient Forth systems,
not for reading (and that goes for versions converted with more
discriminating tools, too).
>> I had plans to write a tool that would, for every included file, write
>> out a version that has all word name uses changed to the case used in
>> the definition, and to define all standard names in upper case. Using
>> this tool would turn a program requiring case insensitivity into a
>> program without this environmental dependency. I never got around to
>> it, and nowadays I think that it makes more sense to standardize on
>> being able to use standard names in lower case.
>
>Except if you go a long list of words, a quick approach (say up to one
>to two thousand wordsš, would be to write a script in AWK, Perl, Python
>or Ruby which would post process your source file.
There are only ~300 words in the standard, these should be enough.
However, a tool that does not interpret the FORTH SOURCE will convert
WORDS in comments, resulting in comments that look like this sentence.
The tool by Ulrich Hoffmann probably does quite well by interpreting
at least some of the parsing words, and that may be good enough;
something like this should also be possible in other languages.
My idea, however, was to hook directly into the text interpreter. Of
course such a tool would not be portable.
I see. I second your thoughts on non needing to uppercase code as well.
>> I find more readable to keep comments with
>> capitalized words when starting phrases, proper nouns, etc., and
>> writting in lower case.
>
> Sure, and I would suggest to go to the source for that. The converted
> version is useful only for running on some deficient Forth systems,
> not for reading (and that goes for versions converted with more
> discriminating tools, too).
OK. I think what you're suggesting is a kind of processing where only
code is uppercased and sent to Forth system. I was considering
processing the source itself.
>
>>> I had plans to write a tool that would, for every included file, write
>>> out a version that has all word name uses changed to the case used in
>>> the definition, and to define all standard names in upper case. Using
>>> this tool would turn a program requiring case insensitivity into a
>>> program without this environmental dependency. I never got around to
>>> it, and nowadays I think that it makes more sense to standardize on
>>> being able to use standard names in lower case.
>> Except if you go a long list of words, a quick approach (say up to one
>> to two thousand wordsš, would be to write a script in AWK, Perl, Python
>> or Ruby which would post process your source file.
>
> There are only ~300 words in the standard, these should be enough.
OK. I was afraid of a Forth system with more defined words, or a
repository of a big shop.
>
> However, a tool that does not interpret the FORTH SOURCE will convert
> WORDS in comments, resulting in comments that look like this sentence.
Separating comments from source code is somewhat trivial in those
languages where you make a simple state machine ("in comment", "out
comment") and act accordingly. So this would be not the issue, I think,
it may become a second style decision as it will be the school willing
the words to be uppercase in comments and some are used in ordinary
English, and then that requires a very advanced semantic analysis to a
short script to chew ;-)
>
> The tool by Ulrich Hoffmann probably does quite well by interpreting
> at least some of the parsing words, and that may be good enough;
> something like this should also be possible in other languages.
>
> My idea, however, was to hook directly into the text interpreter. Of
> course such a tool would not be portable.
I see. We do something in this corner of world with a specific Emacs
mode. It is as portable as Emacs gets :-)
--
Cesar Rabak