Getting somewhere.
[forth.jl.git] / src / forth.jl
index 7f5756e..67dd77d 100644 (file)
@@ -1,93 +1,47 @@
 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