Harder than I thought...
authorTim Vaughan <tgvaughan@gmail.com>
Mon, 4 Apr 2016 11:28:31 +0000 (23:28 +1200)
committerTim Vaughan <tgvaughan@gmail.com>
Mon, 4 Apr 2016 11:28:31 +0000 (23:28 +1200)
src/forth.jl

index 46c3c9c..7f5756e 100644 (file)
@@ -1,40 +1,67 @@
 module forth
 
+instream = STDIN
+
 currentLine = ""
 currentPos = 0
 
-function nextLine()
-    if eof(STDIN)
-        return false
+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
-        currentLine = readLine()
-        currentPos = 1
-        return true
+        return ""
     end
 end
 
-function readPattern(pattern::Regex)
-    m = match(pattern, currentLine)
-    pos += length(m.match)
-    return m.match
+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))
+end
+
 function interpretPrimitive()
     if haskey(dict, word)
         dict[word]()
         return true
     else
         return false
+    end
 end
 interpretNonPrimitive() = false
 interpretNumber() = false
 
 modes["interpret"] = () -> begin
-    getWord()
-    
+    getWordOrNewline()
+
     if ! (interpretPrimitive() ||
         interpretNonPrimitive() ||
         interpretNumber())
@@ -44,10 +71,23 @@ end
 
 function repl()
 
-    mode = "interpret"
+    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()
+
 end