Noodlings of a Forth beginner #523
Replies: 6 comments 18 replies
-
Looks nice and tidy! |
Beta Was this translation helpful? Give feedback.
-
Rather than spam topics, I'll post my noodlings here. Here's a Game of Life I ported to durex and just about noodled into paste: 1
\ conway's game of life.
\ for durexforth on the c64.
\ also tested with gforth.
marker ---life---
( see line 1 ) value tests
$ffff 0< constant 16bit
: \( tests if cr hex here u. latest
u. decimal depth . postpone .(
else '.' emit postpone ( then ;
\( syntax )
: ?\ ( 10) if postpone \ then ;
: \c 16bit 0= ?\ ; immediate \ c64
: \g 16bit ?\ ; immediate \ gforth
: \t tests 0= ?\ ; immediate \ testing
: !! ( 10) 0= abort" fail" '.' emit ;
: d= ( 41) rot = -rot = and ;
: t= ( 61) >r rot >r d= r> r> = and ;
\ ( 41) means ( a b c d -- e )
\t 1 !! 2 3 + 5 = !! \ test assert
\t 1 2 1 2 d= !! 1 2 3 1 2 3 t= !!
\( mach )
\c -1 $d40e ! $80 $d412 c! \ init sid
\c : noise ( 01) $d41b c@ \ and read
\c $d41b c@ 8 lshift or ;
\c : lcg ( 11) $7abd * $1b0f + ;
\c : v ( 00) ---life--- v ;
\g : lcg ( 11) $5851f42d4c957f2d *
\g $14057b7ef767814f + ;
\g : noise ( 01) utime + here + lcg ;
\( pure )
: nop ( 00) ;
: pow2 ( 11) 1 swap lshift ;
: %max ( 11) -1 1 rshift 50 */ ;
: lif ( 11) if '#' else '.' then ;
: near ( 12) 2 + dup 3 - ;
: rule ( cur nbors -- next )
2 - ?dup if nip 1 = 1 and then ;
\t 8 pow2 256 = !!
\t \c 25 %max $3fff = !!
\t 6 near 8 5 d= !! \ neighbor bounds
\t 1 2 rule 1 = !! 0 3 rule 1 = !!
\t 1 3 rule 1 = !! 1 5 rule 0 = !!
\( vals )
\ call a life cell a 'lif'.
\ x mod wid, y mod hgt would simulate
\ repeating grid, but 2div 1mul * 11
\ indexes per lif per gen, too much.
0 value wlog \ so restrict to pow2
0 value x& \ dimens and precalc
0 value y& \ bitmasks to mod with.
0 value bck \ already drawn grid.
0 value frn \ next grid to draw.
' nop value 'draw \ exec'd on store.
( lif x y -- lif x y )
: life! ( wlog hlog bck frn -- )
to frn to bck 2dup + pow2 frn
swap 0 fill pow2 1- to y&
dup to wlog pow2 1- to x& ;
\t : 84p! 3 2 pad pad 32 + life! ;
\t 84p! y& 3 = !! x& 7 = !! wlog 3 = !!
\( basic )
: cols ( 02) x& 1+ 0 ;
: rows ( 02) y& 1+ 0 ;
: flip ( 00) frn bck to frn to bck ;
: ?cr ( 10) if cr then ;
\g : ?home ( 10) ?cr ;
\c : ?home ( 10) if 19 emit then ;
: put ( lif x y -- lif x y )
2dup or 0= ?home >r
2dup 0= ?cr lif emit r> ; \ to 'draw
\t 84p! cols 8 0 d= !! rows 4 0 d= !!
\t bck pad = !! flip frn pad = !!
\t 1 2 3 put 1 2 3 t= !!
\( index )
: offs ( x y -- offset )
>r x& and r> y& and wlog lshift or ;
: bck@ ( 21) offs bck + c@ ;
: frn! ( 30) 'draw execute
offs frn + >r 1 and r> c! ;
\ 1 lif = 1 byte. i wrote bit-addr'ed
\ ver but it was slooow. todo asm?
\t 84p! 2 3 offs 26 = !!
\t -5 11 offs 27 = !!
\t 1 2 3 frn! flip 2 3 bck@ 1 = !!
\( store )
: seeded ( density seed1 -- seed2 )
rows do cols do lcg 2dup u>
i j frn! loop loop nip ;
: pct ( 10) %max noise seeded drop ;
: step ( 00) flip rows do cols do
i j bck@ 0 j near do j near do
i j bck@ + loop loop over - rule
i j frn! loop loop ;
\t 84p! 50 %max 42 seeded drop flip
\t \g 1 0 bck@ !! 0 0 bck@ 0= !!
\t \c 0 1 bck@ !! 1 1 bck@ 0= !!
\t step flip .( todo )
\( user )
: glider ( 00) 1 1 0 frn! 1 2 1 frn!
1 0 2 frn! 1 1 2 frn! 1 2 2 frn! ;
create buf 9 1+ pow2 allot
: buf! ( 20) 2dup + pow2
buf + buf life! ;
: small ( 00) 3 3 buf! ;
: wide ( 00) 5 3 buf! ;
: medium ( 00) 4 4 buf! ;
: big ( 00) 5 4 buf! ;
\g : kik ( 01) 0 ;
\c : kik ( 01) 0 key? if key + then ;
: go ( 00) begin step kik until ;
: gens ( 10) 0 ?do step kik
if unloop exit then loop ;
\( intro )
\g (
: help ."
conway's game of life.
some words and phrases
help [this text] v [edit program]
words [everything available]
small medium big
20 pct glider 3 gens go
examples to try
small glider 5 gens
big 33 pct go
" ;
\g )
\( ok. key?) \t key drop
small glider ' put to 'draw
\c help
\g 5 gens big 33 pct go |
Beta Was this translation helpful? Give feedback.
-
Continuing a Youtube comment thread. Ultimately the branch proves faster than futzing with computing addresses and the like. hex
marker ---
: v [ 0 lda,# tax, ] --- v ;
: rvs c7 c! ;
: rndf d41b c@ 80 < ;
: tri IF a9 9b ELSE df 97 THEN ;
: one dup rvs rndf tri emit emit ;
: row 0= #40 0 DO 0= one LOOP ;
: go 0 BEGIN row AGAIN ;
-1 d40e ! 80 d412 c! \ sid3 noise
0c d021 c! 15 d018 c! \ bg, gfx cset
go Context from the video: this prints a pattern of triangles I think resembles a mountain range. It derives from 10print but I'd like to call it "Ian Mountains" after the original author. |
Beta Was this translation helpful? Give feedback.
-
A couple noodles today, the first is definitely more practical. : .name name>string type space ;
:noname more .name 1 ;
: words page literal dowords ;
:noname ( xt nt -- xt 1 )
2dup swap execute
IF more .name ELSE drop THEN 1 ;
: wordset ( xt -- ) ( xt: nt -- flag )
page literal dowords drop ;
\ nametoken range predicates (v4)
: nt parse-name find-name ;
nt does> nt -branch nt :noname
: mine? literal < ;
: asm? literal literal within ;
: base? dup mine? swap asm? or 0= ;
: mywords ['] mine? wordset ;
: asmwords ['] asm? wordset ;
: basewords ['] base? wordset ;
hide mine? hide asm? hide base?
The second one started with the thought that the extra load/store pair in : cmv, tuck + lda,x + sta,x ;
: mv, 2dup lsb cmv, msb cmv, ;
: nipdup [ 1 0 mv, ] ; \ ab-bb
: drpdup [ 0 1 mv, ] ; \ ab-aa
: >nipdup> [ 2 1 mv, ] ; \ abc-bbc
: >drpdup> [ 1 2 mv, ] ; \ abc-aac
: drpovr [ 0 2 mv, ] ; \ abc-aba
: >nip>tck [ 2 0 mv, ] ; \ abc-cbc
: nipovr nipdup drpovr ; \ abc-aca
: >nip> >nipdup> nipdup drop ;
: nipnip >nip>tck 2drop ;
: ovrswp [ dex, ] drpdup >drpdup> ;
: 2pck [ dex, 0 3 mv, ] ;
: 3dup 2pck 2pck 2pck ; I started to write |
Beta Was this translation helpful? Give feedback.
-
I was thinking about transient compile-time-only constants and came up with this, haven't tested it yet: latest
( ... main program ... )
here 4000 allot
: eq create , immediate
does> @ postpone literal ;
40 eq w 25 eq h 1000 eq wh
( ... more constants ... )
to here
( ... use w h wh ... )
to latest |
Beta Was this translation helpful? Give feedback.
-
I wrote these fast, control-code-safe printing loops for my editor: : 1em [ w lda,(y) $a1 cmp,# 10 bcs,
$7f cmp,# 4 bcs, bl cmp,# 2 bcs,
'?' lda,# iny, $e716 jmp, ] ;
: 39em [ lsb lda,x w sta,
msb lda,x w 1+ sta, 0 ldy,# ]
1em [ 39 cpy,# -7 bne, ] ;
: lines 1- 0 ?DO 39em 1em 40 + LOOP
39em drop ; It's fun to use them to browse through memory: : at-xy xr ! yr ! $e50c sys ;
: bb dup 0 0 at-xy 25 lines
999 + 0 22 at-xy ;
$2e2e 0 bb The $2e2e on the bottom of the stack shows up as two dots near the beginning of zeropage. Press [down]bb[return] to continue paging forward. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
As requested, here's my
compare
from #520. See the standard.And tests:
For anyone interested. Probably not suitable for inclusion in durexForth as-is.
Not sure if this should be added to #428? Probably relevant at least.
Beta Was this translation helpful? Give feedback.
All reactions