Foundations

Assertions

We will often want to check if certain conditions are true, halting if they are not.

assertion support +≡
: assert ( n -- )
    0= if abort then ;

Linked Lists

In several places in this program, singly linked lists are useful. As we are interested primarily in inserting in elements at the end of a list (or are indifferent as to the order). We will standardize on a list root with this structure:

We will need a word to create list roots in a variable:

utility words +≡
: linked-list
    create 0 , 0 , ;

In allocating memory for lists, we will assume sufficient memory is available.

utility words +≡
: allocate' ( n -- a )
    allocate 0= assert ;

We will also the allocated memory for simplicity.

utility words +≡
: zero ( a n -- )
    0 fill ;
: allocate0 ( n -- a )
    dup allocate' swap 2dup zero drop ;

Support adding a new link to the end of a chain.

utility words +≡
: chain-new ( n -- a )
    1+ cells allocate0 ;
: chain-fillout ( .. a n -- a )
    0 do dup i 1+ cells + swap >r ! r> loop ;
: chain-link ( ..n -- a )
    dup chain-new swap chain-fillout ;
: chain-first ( ..n head[t] -- )
    >r chain-link r> 2dup ! cell+ ! ;
: chain-rest ( ..n head[t] -- )
    >r chain-link r> 2dup cell+ @ ! cell+ ! ;
: chain ( ..n head[t] -- )
    dup @ if chain-rest else chain-first then ;

And walking down the list.

utility words +≡
: ->next ( a -- a' ) @ ;

Ordinary Strings

We will need to clone strings occasionally.

utility words +≡
: $clone ( $ - $ )
    dup allocate 0= assert swap 2dup >r >r move r> r> ;

Stack Maneuvers

We will also need to duplicate three items off the stack.

utility words +≡
: 3dup ( xyz -- xyzxyz )
    dup 2over rot ;

File Writing

post atom utility words +≡
: file!-dangle ( A A -- fileid )
    atom-string@ r/w bin create-file 0= assert
    swap over >r atom-string@ r> write-file 0= assert
    dup flush-file 0= assert
;
: file! ( A A -- )
    file!-dangle
    close-file 0= assert
;
: file!-tmp ( A A -- fileid )
    file!-dangle
    dup 0 s>d rot reposition-file 0= assert
;