Skip to content

Commit 6382afe

Browse files
committed
Add ROLL 2ROT words.
1 parent 478b8e7 commit 6382afe

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ all can be in the future.
827827

828828
# Standard Double extension words
829829

830+
* `2ROT`
830831
* `2VALUE`
831832
* `DU<`
832833

pkg/forth/builtin/03_double.f

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,7 @@
9494
POSTPONE @
9595
POSTPONE ;
9696
;
97+
98+
: 2ROT
99+
5 ROLL 5 ROLL
100+
;

pkg/forth/primitive.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,6 +2094,76 @@ func PrimitiveSetup(vm *VirtualMachine) error {
20942094
},
20952095
},
20962096
},
2097+
{
2098+
name: "ROLL",
2099+
flag: Flag{
2100+
isPure: true,
2101+
},
2102+
goFunc: func(vm *VirtualMachine, entry *DictionaryEntry) error {
2103+
n, err := vm.Stack.PopNumber()
2104+
if err != nil {
2105+
return PopError(err, entry)
2106+
}
2107+
shifts := int(n)
2108+
values := make([]Cell, shifts)
2109+
for i := 0; i < int(n); i++ {
2110+
j := shifts - i - 1
2111+
cell, err := vm.Stack.Pop()
2112+
if err != nil {
2113+
return PopError(err, entry)
2114+
}
2115+
values[j] = cell
2116+
}
2117+
top, err := vm.Stack.Pop()
2118+
if err != nil {
2119+
return PopError(err, entry)
2120+
}
2121+
for _, c := range values {
2122+
err = vm.Stack.Push(c)
2123+
if err != nil {
2124+
return PushError(err, entry)
2125+
}
2126+
}
2127+
err = vm.Stack.Push(top)
2128+
if err != nil {
2129+
return PushError(err, entry)
2130+
}
2131+
return nil
2132+
},
2133+
ulpAsm: PrimitiveUlp{
2134+
Asm: []string{
2135+
"ld r0, r3, 0",
2136+
"add r2, r3, r0",
2137+
"ld r1, r2, 1",
2138+
"st r1, r3, 0",
2139+
"__roll_0:",
2140+
"add r2, r3, r0",
2141+
"ld r1, r2, 0",
2142+
"st r1, r2, 1",
2143+
"sub r0, r0, 1",
2144+
"jumpr __roll_0, -1, lt",
2145+
"add r3, r3, 1",
2146+
},
2147+
Next: TokenNextNormal,
2148+
},
2149+
ulpAsmSrt: PrimitiveUlpSrt{
2150+
Asm: []string{
2151+
"st r2, r3, -1",
2152+
"ld r0, r3, 0",
2153+
"add r2, r3, r0",
2154+
"ld r1, r2, 1",
2155+
"st r1, r3, 0",
2156+
"__roll_0:",
2157+
"add r2, r3, r0",
2158+
"ld r1, r2, 0",
2159+
"st r1, r2, 1",
2160+
"sub r0, r0, 1",
2161+
"jumpr __roll_0, -1, lt",
2162+
"ld r2, r3, -1",
2163+
"add r3, r3, 1",
2164+
},
2165+
},
2166+
},
20972167
{
20982168
name: "DROP",
20992169
flag: Flag{

pkg/forth/suite_test.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,14 @@ func TestCoreExtensionSuite(t *testing.T) {
15091509
},
15101510
// REFILL not implemented
15111511
// RESTORE-INPUT not implemented
1512-
// ROLL not implemented
1512+
{
1513+
name: "ROLL",
1514+
code: `
1515+
T{ 1 2 3 2 ROLL -> 2 3 1 }T
1516+
T{ 1 2 1 ROLL -> 2 1 }T
1517+
T{ 4 5 6 0 ROLL -> 4 5 6 }T
1518+
`,
1519+
},
15131520
// S\" not implemented
15141521
// SAVE-INPUT not implemented
15151522
// SOURCE-ID not implemented
@@ -1887,7 +1894,13 @@ func TestDoubleSuite(t *testing.T) {
18871894

18881895
func TestDoubleExtensionSuite(t *testing.T) {
18891896
tests := []suiteTest{
1890-
// 2ROT not implemented
1897+
{
1898+
name: "2ROT",
1899+
code: `
1900+
T{ 1. 2. 3. 2ROT -> 2. 3. 1. }T
1901+
T{ MAX-2INT MIN-2INT 1. 2ROT -> MIN-2INT 1. MAX-2INT }T
1902+
`,
1903+
},
18911904
{
18921905
name: "2VALUE",
18931906
setup: `

0 commit comments

Comments
 (0)