7 size_RS = 1024 # Return stack size
8 size_PS = 1024 # Parameter stack size
9 size_TIB = 4096 # Terminal input buffer size
12 RSP = 0 # Return stack pointer
13 PSP =0 # Parameter/data stack pointer
14 IP = 0 # Instruction pointer
15 W = 0 # Working register
16 X = 0 # Extra register
20 here = PSP0 + size_PS + size_TIB # location of bottom of dictionary
21 latest = 0 # no previous definition
23 # The following array constitutes the memory of the VM. It has the following geography:
25 # memory = +-----------------------+
27 # +-----------------------+
29 # +-----------------------+
30 # | Terminal Input Buffer |
31 # +-----------------------+
33 # +-----------------------+
35 # Note that all words (user-defined, primitive, variables, etc) are included in
38 # Simple linear addressing is used with one exception: references to primitive code
39 # blocks, which are represented as anonymous functions, appear the negative index
40 # into the primitives array which contains only these functions.
42 memory = Array{Int64,1}(size_memory)
43 primitives = Array{Function,1}()
46 # Stack manipulation functions
48 function pushRS(val::Int64)
60 function pushPS(val::Int64)
62 memory[PSP += 1] = val
72 # Primitive creation and calling functions
74 function defPrim(name::AbstractString, f::Function)
81 memory[here] = length(name); here += 1
82 memory[here:(here+length(name)-1)] = [Int(c) for c in name]; here += length(name)
85 memory[here] = -length(primitives)
88 return -length(primitives)
91 callPrim(addr::Int64) = primitives[-addr]()
93 function defVar(name::AbstractString, val::Int64)
100 memory[here] = length(name); here += 1
101 memory[here:(here+length(name)-1)] = [Int(c) for c in name]; here += length(name)
103 push!(primitives, () -> begin
111 # Threading Primitives
113 NEXT = defPrim("NEXT", () -> begin
120 DOCOL = defPrim("DOCOL", () -> begin
126 EXIT = defPrim("EXIT", () -> begin
132 # Basic forth primitives
134 DROP = defPrim("DROP", () -> begin
139 SWAP = defPrim("SWAP", () -> begin
140 PS[PSP], PS[PSP-1] = PS[PSP-1], PS[PS]
144 DUP = defPrim("DUP", () -> begin
149 LIT = defPrim("LIT", () -> begin
157 STORE = defPrim("!", quote
164 FETCH = defPrim("@", quote
170 ADDSTORE = defPrim("+!", quote
173 memory[addr] += toAdd
177 SUBSTORE = defPrim("-!", quote
180 memory[addr] -= toSub
187 defVar("STATE", :state)
188 defVar("HERE", :here)
189 defVar("LATEST", :latest)
190 defVar("BASE", :base)
194 defConst("VERSION", 1)
195 defConst("DOCOL", DOCOL)
199 TOR = defPrim(">R", () -> begin
204 FROMR = defPrim("R>", () -> begin
209 RSPFETCH = defPrim("RSP@", () -> begin
214 RSPSTORE = defPrim("RSP!", () -> begin
219 RDROP = defPrim("RDROP", () -> begin
226 PSPFETCH = defPrim("PSP@", () -> begin
231 PSPSTORE = defPrim("PSP!", () -> begin
239 defVar("#TIB", :numtib)
242 KEY = defPrim("KEY", () -> begin
250 EMIT = defPrim("EMIT", () -> begin
255 WORD = defPrim("WORD", () -> begin
260 NUMBER = defPrim("NUMBER", () -> begin
268 while (jmp = callPrim(jmp)) != 0 end