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 = +-----------------------+
26 # | System Variables |
27 # +-----------------------+
29 # +-----------------------+
31 # +-----------------------+
32 # | Terminal Input Buffer |
33 # +-----------------------+
35 # +-----------------------+
37 # Note that all words (user-defined, primitive, variables, etc) are included in
40 # Simple linear addressing is used with one exception: references to primitive code
41 # blocks, which are represented as anonymous functions, appear the negative index
42 # into the primitives array which contains only these functions.
44 memory = Array{Int64,1}(size_memory)
45 primitives = Array{Function,1}()
49 # Stack manipulation functions
51 function pushRS(val::Int64)
63 function pushPS(val::Int64)
65 memory[PSP += 1] = val
75 # Primitive creation and calling functions
77 function defPrim(name::AbstractString, f::Function)
84 memory[here] = length(name); here += 1
85 memory[here:(here+length(name)-1)] = [Int(c) for c in name]; here += length(name)
88 memory[here] = -length(primitives)
91 return -length(primitives)
94 callPrim(addr::Int64) = primitives[-addr]()
96 function defSysVar(name::AbstractString, varAddr::Int64)
103 memory[here] = length(name); here += 1
104 memory[here:(here+length(name)-1)] = [Int(c) for c in name]; here += length(name)
106 push!(primitives, eval(:(() -> begin
110 memory[here] = -length(primitives)
116 function defConst(name
118 # Threading Primitives
120 NEXT = defPrim("NEXT", () -> begin
127 DOCOL = defPrim("DOCOL", () -> begin
133 EXIT = defPrim("EXIT", () -> begin
139 # Basic forth primitives
141 DROP = defPrim("DROP", () -> begin
146 SWAP = defPrim("SWAP", () -> begin
147 PS[PSP], PS[PSP-1] = PS[PSP-1], PS[PS]
151 DUP = defPrim("DUP", () -> begin
156 LIT = defPrim("LIT", () -> begin
164 STORE = defPrim("!", quote
171 FETCH = defPrim("@", quote
177 ADDSTORE = defPrim("+!", quote
180 memory[addr] += toAdd
184 SUBSTORE = defPrim("-!", quote
187 memory[addr] -= toSub
197 defConst("VERSION", 1)
198 defConst("DOCOL", DOCOL)
202 TOR = defPrim(">R", () -> begin
207 FROMR = defPrim("R>", () -> begin
212 RSPFETCH = defPrim("RSP@", () -> begin
217 RSPSTORE = defPrim("RSP!", () -> begin
222 RDROP = defPrim("RDROP", () -> begin
229 PSPFETCH = defPrim("PSP@", () -> begin
234 PSPSTORE = defPrim("PSP!", () -> begin
242 defVar("#TIB", :numtib)
245 KEY = defPrim("KEY", () -> begin
253 EMIT = defPrim("EMIT", () -> begin
258 WORD = defPrim("WORD", () -> begin
263 NUMBER = defPrim("NUMBER", () -> begin
271 while (jmp = callPrim(jmp)) != 0 end