Harder than I thought...
[forth.jl.git] / src / forth.jl
1 module forth
2
3 instream = STDIN
4
5 currentLine = ""
6 currentPos = 0
7
8 function readPattern(pattern::Regex)
9
10     if currentPos<1 || currentPos>length(currentLine)
11         if eof(instream)
12             return ""
13         else
14             global currentLine = readline(instream)
15             global currentPos = 1
16         end
17     end
18
19     m = match(pattern, currentLine[currentPos:length(currentLine)])
20     if m != nothing
21         global currentPos += length(m.match)
22         return m.match
23     else
24         return ""
25     end
26 end
27
28 readSpaces() = readPattern(r"^([ \t]*)")
29 readWord() = readPattern(r"^([^\s]+)")
30 readNewline() = readPattern(r"^(\n)")
31 readRestOfLine() = readPattern(r"^([^\n]*)")
32
33 word = ""
34 function getWordOrNewline()
35     global word = readWord()
36     if word == ""
37         global word = readNewline()
38     end
39 end
40
41 modes = Dict{AbstractString,Function}()
42 mode = ""
43
44 dict = Dict{AbstractString, Function}()
45 dict["%J"] = () -> begin
46     rol = readRestOfLine()
47     println("Evaluating '$rol'")
48     eval(parse(rol))
49 end
50
51 function interpretPrimitive()
52     if haskey(dict, word)
53         dict[word]()
54         return true
55     else
56         return false
57     end
58 end
59 interpretNonPrimitive() = false
60 interpretNumber() = false
61
62 modes["interpret"] = () -> begin
63     getWordOrNewline()
64
65     if ! (interpretPrimitive() ||
66         interpretNonPrimitive() ||
67         interpretNumber())
68         println("Error: unknown word '$word'.")
69     end
70 end
71
72 function repl()
73
74     global mode = "interpret"
75     idx = 1
76     while mode != "stop"
77         modes[mode]()
78     end
79 end
80
81 # Bootstrapping interpreter
82
83 firstProg = """%J dict["\\n"] = () -> nothing
84 %J dict["\\n"] = () -> nothing
85 %J dict[""] = () -> global mode = "stop"
86 %J global DS = []
87 %J global RS = []
88 """
89
90 instream = IOBuffer(firstProg)
91 repl()
92
93 end