module forth
-instream = STDIN
-
-currentLine = ""
-currentPos = 0
-
-function readPattern(pattern::Regex)
-
- if currentPos<1 || currentPos>length(currentLine)
- if eof(instream)
- return ""
- else
- global currentLine = readline(instream)
- global currentPos = 1
- end
- end
-
- m = match(pattern, currentLine[currentPos:length(currentLine)])
- if m != nothing
- global currentPos += length(m.match)
- return m.match
- else
- return ""
- end
-end
-
-readSpaces() = readPattern(r"^([ \t]*)")
-readWord() = readPattern(r"^([^\s]+)")
-readNewline() = readPattern(r"^(\n)")
-readRestOfLine() = readPattern(r"^([^\n]*)")
-
-word = ""
-function getWordOrNewline()
- global word = readWord()
- if word == ""
- global word = readNewline()
- end
-end
-
-modes = Dict{AbstractString,Function}()
-mode = ""
-
-dict = Dict{AbstractString, Function}()
-dict["%J"] = () -> begin
- rol = readRestOfLine()
- println("Evaluating '$rol'")
- eval(parse(rol))
+RS = Array{Int, 1}()
+DS = Array{Int, 1}()
+
+IP = 0
+W = 0
+X = 0
+jmp = nothing
+
+primitives = Array{Expr,1}()
+memory = Array{Int64,1}()
+headers = Array{Tuple{AbstractString, Int64},1}()
+
+function addPrim(name::AbstractString, expr::Expr)
+ push!(primitives, expr)
+ push!(memory, -length(primitives))
+ push!(headers, (name, length(memory)))
+
+ return expr
end
-function interpretPrimitive()
- if haskey(dict, word)
- dict[word]()
- return true
- else
- return false
- end
-end
-interpretNonPrimitive() = false
-interpretNumber() = false
-
-modes["interpret"] = () -> begin
- getWordOrNewline()
-
- if ! (interpretPrimitive() ||
- interpretNonPrimitive() ||
- interpretNumber())
- println("Error: unknown word '$word'.")
- end
-end
-
-function repl()
-
- global mode = "interpret"
- idx = 1
- while mode != "stop"
- modes[mode]()
- end
-end
-
-# Bootstrapping interpreter
-
-firstProg = """%J dict["\\n"] = () -> nothing
-%J dict["\\n"] = () -> nothing
-%J dict[""] = () -> global mode = "stop"
-%J global DS = []
-%J global RS = []
-"""
-
-instream = IOBuffer(firstProg)
-repl()
+NEXT = addPrim("next", :(begin
+ W = memory[IP]
+ IP += 1
+ X = memory[W]
+ jmp = primitives[-X]
+end))
+
+DOCOL = addPrim("docol", :(begin
+ push!(RS, IP)
+ IP = W + 1
+ jmp = NEXT
+end))
+
+EXIT = addPrim("exit", :(begin
+ IP = pop!(RS)
+ jmp = NEXT
+end))
+
+# VM loop
+#jmp = NEXT
+#while true
+# eval(jmp)
+#end
end