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 }