Folding

Foldability is perhaps the most puzzling feature of Mecrisp-Stellaris Forth, hopefully this article helps to clarify it.

x-foldable

Are flags which tells the compiler how many constant inputs are necessary for a definition to produce deterministic outputs on the stack already at compile time.

Flag

Description

0-foldable:

constants variables [’] [char]

1-foldable:

?dup drop negate

2-foldable:

+ - * swap nip

3-foldable:

rot

4-foldable:

d+ d- 2swap

Sometimes, for very simple definitions, the RA cores can automatically determine that something is foldable, but for a complicated piece like the sine function, declaring it as 2-foldable will help to remove a lot of cycles when a double meets a sine at compile time.

Foldability is for anything which works on the stack without any side effects, and generates constant outputs when it encounters a specified number of constant inputs. Mostly mathematical functions, bit mask tools, stack jugglers and the like.

Folding Example

: sqrt ( u -- u^1/2 )
  [
  $2040 h, \   movs r0, #0x40
  $0600 h, \   lsls r0, #24
  $2100 h, \   movs r1, #0
  $000A h, \ 1:movs r2, r1
  $4302 h, \   orrs r2, r0
  $0849 h, \   lsrs r1, #1
  $4296 h, \   cmp r6, r2
  $D301 h, \   blo 2f
  $1AB6 h, \   subs r6, r2
  $4301 h, \   orrs r1, r0
  $0880 h, \ 2:lsrs r0, #2
  $D1F6 h, \   bne 1b
  $000E h, \   movs r6, r1
  ]
  1-foldable
;

Compiled Code With Folding

see sqrt-of-9-1-foldable

2000043C: 3F04  subs r7 #4
2000043E: 603E  str r6 [ r7 #0 ]
20000440: 2603  movs r6 #3
20000442: 4770  bx lr

Compiled Code Without Folding

see sqrt-of-9

2000045C: 3F04  subs r7 #4
2000045E: 603E  str r6 [ r7 #0 ]
20000460: 2609  movs r6 #9
20000462: B500  push { lr }
20000464: F7FF  bl  20000400  --> sqrt
20000466: FFCC
20000468: BD00  pop { pc }