fifol http://www.iijlab.net/~ew/fifol.html
Eiiti Wada wada@u-tokyo.ac.jp
language fifol
fifol (first in first out language) is similar to PostScript.
fifol is a queue machine while PostScript is a stack machine.
Operations are made for items removed from the front end of the current fifo
and the result is inserted to the rear end.
Data types:
int, bool, proc, fifo
Operators:
current fifo before operator current fifo after
front rear front rear
[...] int [... int]
[...] bool [... bool]
[...] proc [... proc]
[any ...] pop [...]
[any ...] dup [... any any] (shallow copy)
[any0 any1 ...] exch [... any1 any0]
[any ...] rotate(rot) [... any]
[...] newfifo [... []]
[[..] any ...] fifopush [... [.. any]]
[[any ..] ...] fifopop [... [..] any]
[[..] ...] switch [.. [...]]
[int0 int1 ...] add [... int] where int = int0 + int1
[int0 int1 ...] sub [... int] where int = int0 - int1
[int0 int1 ...] mul [... int] where int = int0 * int1
[int0 int1 ...] div [... int] where int = int0 / int1
[int0 int1 ...] mod [... int] where int = int0 % int1
[int0 ...] abs [... int] where int = abs(int0)
[int0 ...] neg [... int] where int = - int0
[int0 int1 ...] eq [... bool]
where bool = int0 == int1? true : false
[int0 int1 ...] ne [... bool]
where bool = int0 != int1? true : false
[int0 int1 ...] ge [... bool]
where bool = int0 >= int1? true : false
[int0 int1 ...] gt [... bool]
where bool = int0 > int1? true : false
[int0 int1 ...] le [... bool]
where bool = int0 <= int1? true : false
[int0 int1 ...] lt [... bool]
where bool = int0 < int1? true : false
[int0 int1 ...] and [... int] where int = int0 & int1
[bool0 bool1 ...] and [... bool] where bool = bool0 && bool1
[int0 int1 ...] or [... int] where int = int0 | int1
[bool0 bool1 ...] or [... bool] where bool = bool0 || bool1
[int0 int1 ...] xor [... int] where int = int0 ^ int1
[bool0 bool1 ...] xor [... bool] where bool = bool0 ^^ bool1
[int0 ...] not [... int] where int = ~int0
[bool0 ...] not [... bool] where bool = !bool0
[true proc ...] if [...] call proc
[false proc ...] if [...]
[true proc0 proc1 ...] ifelse [...] call proc0
[false proc0 proc1 ...] ifelse [...] call proc1
[proc ...] loop [...] execute proc repeatedly
[...] exit [...] return from the innermost loop
[any ...] = [...] <output any>
[...] fifo [...] <output [...]>
examples
ex0: arithemtic expression
+
/ \
* *
/ \ / \
a b c d
a b c d mul mul add =
simulation:
[] a
[a] b
[a b] c
[a b c] d
[a b c d] mul
[c d a*b] mul
[a*b c*d] add
[a*b+c*d] = <output a*b+c*d>
[]
ex1: print integer from 0 to 9
{dup 10 rotate gt {pop exit} rotate if dup = 1 add} 0 loop
simulation:
[] {dup 10 rotate ge {pop exit} rotate if dup = 1 add}
[{dup 10 rotate ge {pop exit} rotate if dup = 1 add}] 0
[{dup 10 rotate ge {pop exit} rotate if dup = 1 add} 0] loop
[0] dup
[0 0] 10
[0 0 10] rotate
[0 10 0] ge
[0 false] {pop exit}
[0 false {pop exit}] rotate
[false {pop exit} 0] if
[0] dup
[0 0] = <output 0>
[0] 1
[0 1] add
[1] dup
[1 1] 10
[1 1 10] rotate
[1 10 1] ge
[1 false] {pop exit}
[1 false {pop exit}] rotate
[false {pop exit} 1] if
[1] dup
[1 1] = <output 1>
...
[9] 1
[9 1] add
[10] dup
[10 10] 10
[10 10 10] rotate
[10 10 10] ge
[10 true] {pop exit}
[10 true {pop exit}] rotate
[true {pop exit} 10] if
[10] pop
[] exit
[]
ex2: print prime numbers less than 100
{100 dup lt {pop exit) rot if {dup dup exch dup rot exch mul exch lt
{pop dup = exit} exch if dup dup rot exch mod 0 exch eq
{rot pop exit} exch if 1 rot add} rot 2 loop 1 add} 2 loop
simulation: testing if 7 is prime
[6] 1
[6 1] add
[7] 100
[7 100] dup
[100 7 7] lt
[7 false] {pop exit}
[7 false {pop exit}] rot
[false {pop exit} 7] if
[7] {dup dup exch dup rot exch mul exch lt {pop dup = exit}
exch if dup dup rot exch mod 0 exch eq {rot pop exit} exch if 1 rot add}
[7 {dup dup exch dup rot exch mul exch lt {pop dup = exit}
exch if dup dup rot exch mod 0 exch eq {rot pop exit} exch if 1 rot add}] rot
[{dup dup exch dup rot exch mul exch lt {pop dup = exit}
exch if dup dup rot exch mod 0 exch eq {rot pop exit} exch if 1 rot add} 7] 2
[{dup dup exch dup rot exch mul exch lt {pop dup = exit}
exch if dup dup rot exch mod 0 exch eq {rot pop exit} exch if 1 rot add} 7 2]
loop
[7 2] dup ;test with 2
[2 7 7] dup
[7 7 2 2] exch
[2 2 7 7] dup
[2 7 7 2 2] rot
[7 7 2 2 2] exch
[2 2 2 7 7] mul
[2 7 7 4] exch
[7 4 7 2] lt ;7 > 2 * 2
[7 2 false] {pop dup = exit}
[7 2 false {pop dup = exit}] exch
[false {pop dup = exit} 2 7] if
[2 7] dup
[7 2 2] dup
[2 2 7 7] rot
[2 7 7 2] exch
[7 2 7 2] mod
[7 2 1] 0
[7 2 1 0] exch
[1 0 2 7] eq ;7 % 2 != 0
[2 7 false] {rot pop exit}
[2 7 false {rot pop exit}] exch
[false {rot pop exit} 7 2] if
[7 2] 1
[7 2 1] rot
[2 1 7] add
[7 3] dup ;test with 3
[3 7 7] dup
[7 7 3 3] exch
[3 3 7 7] dup
[3 7 7 3 3] rot
[7 7 3 3 3] exch
[3 3 3 7 7] mul
[3 7 7 9] exch
[7 9 7 3] lt ;7 < 3 * 3
[7 3 true] {pop dup = exit}
[7 3 true {pop dup = exit}] exch
[true {pop dup = exit} 3 7] if
[3 7] pop
[7] dup
[7 7] = <output 7>
[7] exit
[7] 1
[7 1] add ;test next integer for primarity
ex3: print the contents of fifo in reverse order
newfifo 0 fifopush 1 fifopush 2 fifopush 3 fifopush -1 fifopush
{fifopop rot dup -1 exch eq {exit} exch if
{fifopop exch dup -1 exch rot eq {exit} exch rot if fifopush rot}
rot rot loop rot = rot fifopush} rot loop pop pop
simulation:
[3 -1 [0 1 2]] = <output 3>
[-1 [0 1 2]] rot
[[0 1 2] -1] fifopush ;-1 is nil
[[0 1 2 -1]] fifopop ;finding 2, i.e. item before -1
[[1 2 -1] 0] rot
[0 [1 2 -1]] dup
[[1 2 -1] 0 0] -1
[[1 2 -1] 0 0 -1] exch
[0 -1 0 [1 2 -1]] eq
[0 [1 2 -1] false] {exit} ;true for [[-1]], test end of program
[0 [1 2 -1] false {exit}] exch
[false {exit} [1 2 -1] 0] if
[[1 2 -1] 0] {fifopop exch dup -1 exch rot eq {exit} exch rot if fifopush rot}
[[1 2 -1] 0 {fifopop exch dup -1 exch rot eq {exit} exch rot if fifopush rot}]
rot
[0 {fifopop exch dup -1 exch rot eq {exit} exch rot if fifopush rot} [1 2 -1]]
rot
[{fifopop exch dup -1 exch rot eq {exit} exch rot if fifopush rot} [1 2 -1] 0]
loop
[[1 2 -1] 0] fifopop
[0 [2 -1] 1] exch
[1 [2 -1] 0] dup
[[2 -1] 0 1 1] -1
[[2 -1] 0 1 1 -1] exch
[1 1 -1 0 [2 -1]] rot
[1 -1 0 [2 -1] 1] eq
[0 [2 -1] 1 false] {exit}
[0 [2 -1] 1 false {exit}] exch
[1 false {exit} [2 -1] 0] rot
[false {exit} [2 -1] 0 1] if
[[2 -1] 0 1] fifopush
[1 [2 -1 0]] rot
[[2 -1 0] 1] fifopop
[1 [-1 0] 2] exch
[2 [-1 0] 1] dup
[[-1 0] 1 2 2] -1
[[-1 0] 1 2 2 -1] exch
[2 2 -1 1 [-1 0]] rot
[2 -1 1 [-1 0] 2] eq
[1 [-1 0] 2 false] {exit}
[1 [-1 0] 2 false {exit}] exch
[2 false {exit} [-1 0] 1] rot
[false {exit} [-1 0] 1 2] if
[[-1 0] 1 2] fifopush
[2 [-1 0 1]] rot
[[-1 0 1] 2] fifopop
[2 [0 1] -1] exch
[-1 [0 1] 2] dup
[[0 1] 2 -1 -1] -1
[[0 1] 2 -1 -1 -1] exch
[-1 -1 -1 2 [0 1]] rot
[-1 -1 2 [0 1] -1] eq
[2 [0 1] -1 true] {exit}
[2 [0 1] -1 true {exit}] exch
[-1 true {exit} [0 1] 2] rot
[true {exit} [0 1] 2 -1] if
[[0 1] 2 -1] exit
[[0 1] 2 -1] rot
[2 -1 [0 1]] = <output 2>
end