Simple implementation for very few limited subset of forth in haskell
feel free to add more features by contributing.
Program parses and evaluates all expressions using the following structure:
type Program = [Expr]
type Stack = [Int]
type Row = (String, Program)
type Table = [Row]
data Evaluator = Evaluator {
program :: Program,
stack :: Stack,
table :: Table
} deriving ShowA full compiled code will populate Program and Table with expressions:
- Program: All expressions compiled, a list of expressions
- Table: Store compiled words, a list of tuple string expressions
data Expr =
Lit Int
| Word String -- word definition
| Add
| Sub
| Mul
| Div
| Dup
| Swap
| Over
| Drop
| Dot
| Emit
| Equal
| Cr
| Lf
deriving ShowTo evaluate a full compiled Program and Table use:
eval :: Evaluator -> IO Evaluatoreval get a single Evalutator data and recursively runs all expressions using Program and Table
by pushing/poping values from top of the Stack, and produces side effects for commands like Dot and Emit.
This following program outputs 'forth' in the standard output:
ghci> :l forth.hs
ghci> let source = ": f 102 ; : o 111 ; : r 114 ; : t 116 ; : h 104 ; : out f emit o emit r emit t emit h emit ; out 10 emit"
ghci> let Right (prog, table) = parseTokens source []
ghci> eval (Evaluator prog [] table)
forth
Evaluator {program = [], stack = [], table = [("out",[Emit,Word "h",Emit,Word "t",Emit,Word "r",Emit,Word "o",Emit,Word "f"]),("h",[Lit 104]),("t",[Lit 116]),("r",[Lit 114]),("o",[Lit 111]),("f",[Lit 102])]}Call main to start an interactive repl:
ghci> :l forth.hs
ghci> main
: three 3 ;
ok
: four 4 ;
ok
three four * .
12 okInside GHCI load forth.hs and run hello.4fh to print 'hello, world':
ghci> :l forth.ts
ghci> run4fh "hello.4fh"
hello, world