Skip to content

Latest commit

 

History

History
261 lines (202 loc) · 4.11 KB

tutorial-of-forth.org

File metadata and controls

261 lines (202 loc) · 4.11 KB

tutorial of forth

note

>< function application

non-named function

:noname ." kkk kkk kkk" cr ;
dup execute execute

>< data type

name

global name

  • variable ( [word form stdin] -> address )
variable var1
var1 .
47 var1 !
var1 @ .

17 constant seventeen
seventeen .

global memory

create
  • makes a new dictionary entry The new name is a Forth subroutine that will return the address of the next available space in memory.
create global-memory-1
global-memory-1 .
here .

here .
16 allot
here .

( cells as cell * )
10 cells allot

create global-memory-2 10 cells allot

: field-2-6 ( -> address ) global-memory-2 5 cells + ;

233 field-2-6 !
field-2-6 @


: variable  create   1 cells  allot ;
: variable  create   0  ,  ;

variable var1
var1 .
47 var1 !
var1 @ .
create … does>
  • to write subroutines (“constructors”) that create custom data structures
  • to implement VARIABLE in forth we use create to implement CONSTANT in forth we use create … does>
  • CREATE define word that return address DOES> append function body to the word function body will be apply after the address get returned
17 create seventeen ,
seventeen @ .

: cc ( number [word from stdin] -> [define word] )
    create ,
    does> @
;

17 cc svteen
svteen .



: cs ( number [word from stdin] -> [define word] )
    create ,
  does> cr
    @ . ." cs testing does>" cr
;

17 cs svts
svts

compiler

comma

here .
233 ,
here .
here 1 cells - @ .


here .
1 c, 1 c, 1 c, 1 c,
1 c, 1 c, 1 c, 1 c,
hex
here 1 cells - @ . ( 1 01 01 01 01 01 01 01 )
decimal

>< colon

control

bool

-1 as true 0 as false thus bitwise INVERT can turn false to true and true true to false

branch

: not-zero-crying
    0 =  invert  if
        cr   ." not zero!"
    then
;

0 not-zero-crying
7 not-zero-crying

( interpreted version )
false [if]
    anything you want to say
[then]

recurse

: tuck
  ( a b -> b a b )
  swap  over
;

: gcd
  ( a b -> gcd )
  ?dup  if
    tuck  mod  recurse
  then
;

begin until

: countdown ( n -- )
    begin
        cr
        dup . 1 - dup 0 =
    until
    drop
;

10 countdown


: endless
    begin
        xxx
        false
    until
;

>< begin … while … repeat

do loop

\ Counted Loops

\ C:
\   for(i=0;i<10;i++) {
\     foo();
\   }

\ AmForth:
\ 10 0 do
\     foo
\ loop

\ If the loop increment is not 1,
\ Forth uses the word +loop instead of loop:

\ C:
\   for(i=0;i<10;i+2) {
\     foo();
\   }

\ AmForth:
\ 10 0 do
\     foo 2
\ +loop

: by-ones ( n -- )
    0 tuck do
        cr dup . 1 +
    loop
    drop
;

20 by-ones

: by-twos ( n -- )
    0 tuck do
        cr dup . 2 +
    2 +loop
    drop
;

20 by-twos

: by-twos ( n -- )
    0 do
        cr i .
    2 +loop
;

20 by-twos

: countdown
    0 swap do
        cr i .
    -1 +loop
;

20 countdown

\ one may also nest loops
\ and access the index of the outer loop
\ from the inner loop
\ using the word j

: nested ( n m -- )
    cr
    0 do  dup ( n n -- )
        0 do  cr  j .  i .
        loop
    loop
    drop
;

2 3  nested