On to constants.
authorTim Vaughan <tgvaughan@gmail.com>
Sun, 10 Apr 2016 01:57:16 +0000 (13:57 +1200)
committerTim Vaughan <tgvaughan@gmail.com>
Sun, 10 Apr 2016 01:57:16 +0000 (13:57 +1200)
src/forth.jl

index 60646ff..f35d212 100644 (file)
 module forth
 
-
 RS = Array{Int64, 1}(1024)
-RSP = 1
+RSP = 0
 
 PS = Array{Int64, 1}(1024)
-PSP = 1
+PSP =0
 
 IP = 0
 W = 0
 X = 0
 
-jmp = nothing
+jmp = 0
 
 primitives = Array{Expr,1}()
-memory = Array{Int64,1}()
-headers = Array{Tuple{AbstractString, Int64},1}()
+memory = Array{Int64,1}(64*1024)
+LATEST = 0
+HERE = 1
+
+# Intperpreter state
+
+STATE = 0
+
+# Current radix
+
+BASE = 10
+
+# Stack manipulation macros
+
+function pushRS(val::Int64)
+    global RSP
+    RS[RSP += 1] = val
+end
+
+function popRS()
+    global RSP
+    val = RS[RSP]
+    RSP -= 1
+    return val
+end
+
+function pushPS(val::Int64)
+    global PSP
+    PS[PSP += 1] = val
+end
+
+function popPS()
+    global PSP
+    val = PS[PSP]
+    PSP -= 1
+    return val
+end
+
+# Primitive creation functions
+
+function defPrim(name::AbstractString, expr::Expr)
+    global HERE, LATEST
+
+    memory[HERE] = LATEST
+    LATEST = HERE
+    HERE += 1
+
+    memory[HERE] = length(name); HERE += 1
+    memory[HERE:(HERE+length(name)-1)] = [Int(c) for c in name]; HERE += length(name)
 
-function addPrim(name::AbstractString, expr::Expr)
     push!(primitives, expr)
-    push!(memory, -length(primitives))
-    push!(headers, (name, length(memory)))
-    
-    return expr
+    memory[HERE] = -length(primitives)
+    codeword = HERE
+    HERE += 1
+
+    return codeword
+end
+
+function defVar(name::AbstractString, var::Expr)
+    defPrim(name, Expr(:call, :pushPS, var))
 end
 
-NEXT = addPrim("next", :(begin
+# Threading Primitives
+
+NEXT = defPrim("NEXT", :(begin
     W = memory[IP]
     IP += 1
     X = memory[W]
-    jmp = primitives[-X]
+    jmp = X
 end))
 
-DOCOL = addPrim("docol", :(begin
-    push!(RS, IP)
+DOCOL = defPrim("DOCOL", :(begin
+    pushRS(IP)
     IP = W + 1
     jmp = NEXT
 end))
 
-EXIT = addPrim("exit", :(begin
-    IP = pop!(RS)
+EXIT = defPrim("EXIT", :(begin
+    IP = popRS()
     jmp = NEXT
 end))
 
 
+# Basic forth primitives
+
+DROP = defPrim("DROP", :(begin
+    popPS()
+end))
+
+SWAP = defPrim("SWAP", :(begin
+    PS[PSP], PS[PSP-1] = PS[PSP-1], PS[PS]
+end))
+
+DUP = defPrim("DUP", :(begin
+    pushPS(PS[PSP])
+end))
+
+LIT = defPrim("LIT", :(begin
+    pushPS(memory[IP])
+    IP += 1
+end))
+
+# Memory primitives
+
+STORE = defPrim("!", :(begin
+    addr = popPS()
+    dat = popPS()
+    memory[addr] = dat
+end))
+
+FETCH = defPrim("@", :(begin
+    addr = popPS()
+    pushPS(memory[addr])
+end))
+
+ADDSTORE = defPrim("+!", :(begin
+    addr = popPS()
+    toAdd = popPS()
+    memory[addr] += toAdd
+end))
+
+SUBSTORE = defPrim("-!", :(begin
+    addr = popPS()
+    toSub = popPS()
+    memory[addr] -= toSub
+end))
+
+
+# Built-in variables
+
+defVar("STATE", :STATE)
+defVar("HERE", :HERE)
+defVar("LATEST", :LATEST)
+defVAR("PSP", :PSP)
+defVAR("BASE", :BASE)
+
+# Constants
+
 
 
 # VM loop
 jmp = NEXT
 function runVM()
     while true
-        eval(jmp)
+        eval(primitives[-memory[jmp]])
     end
 end