X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=src%2Fforth.jl;h=890cf241e66d5eee8f4fc9913f5345f50bb43480;hb=ebff3ca5a9b2dd5a6608b696e7862aa7264f6682;hp=57fda1b3a18a7d156e26c075d2d920819602a4bf;hpb=4db66d36d79a44ae2c32443c06b3ddad84cae531;p=forth.jl.git diff --git a/src/forth.jl b/src/forth.jl index 57fda1b..890cf24 100644 --- a/src/forth.jl +++ b/src/forth.jl @@ -16,16 +16,16 @@ primNames = Array{ASCIIString,1}() # Built-in variables nextVarAddr = 1 -H = nextVarAddr; nextVarAddr += 1 # Next free memory address -FORTH = nextVarAddr; nextVarAddr += 1 # LFA of latest word in system dict -CURRENT = nextVarAddr; nextVarAddr += 1 # Current compilation dict +H = nextVarAddr; nextVarAddr += 1 # Next free memory address +FORTH_LATEST = nextVarAddr; nextVarAddr += 1 # FORTH dict latest +CURRENT = nextVarAddr; nextVarAddr += 1 # Current compilation dict RSP0 = nextVarAddr # bottom of RS PSP0 = RSP0 + size_RS # bottom of PS TIB = PSP0 + size_PS # address of terminal input buffer mem[H] = TIB + size_TIB # location of bottom of dictionary -mem[FORTH] = 0 # no previous definition -mem[CURRENT] = FORTH # Compile words to system dict initially +mem[FORTH_LATEST] = 0 # zero FORTH dict latest (no previous def) +mem[CURRENT] = FORTH_LATEST-1 # Compile words to system dict initially DICT = mem[H] # Save bottom of dictionary as constant @@ -109,21 +109,27 @@ F_IMMED = 32 F_HIDDEN = 64 NFA_MARK = 128 +function dictWrite(ints::Array{Int64,1}) + mem[mem[H]:(mem[H]+length(ints)-1)] = ints + mem[H] += length(ints) +end +dictWrite(int::Int64) = dictWrite([int]) +dictWriteString(string::ASCIIString) = dictWrite([Int64(c) for c in string]) + function createHeader(name::AbstractString, flags::Int64) - mem[mem[H]] = mem[mem[CURRENT]] - mem[mem[CURRENT]] = mem[H] + mem[mem[H]] = mem[mem[CURRENT]+1] + mem[mem[CURRENT]+1] = mem[H] mem[H] += 1 - mem[mem[H]] = length(name) | flags | NFA_MARK; mem[H] += 1 - putString(name, mem[H]); mem[H] += length(name) + dictWrite(length(name) | flags | NFA_MARK) + dictWriteString(name) end function defPrimWord(name::AbstractString, f::Function; flags::Int64=0) createHeader(name, flags) codeWordAddr = mem[H] - mem[codeWordAddr] = defPrim(f, name=name) - mem[H] += 1 + dictWrite(defPrim(f, name=name)) return codeWordAddr end @@ -132,13 +138,9 @@ function defWord(name::AbstractString, wordAddrs::Array{Int64,1}; flags::Int64=0 createHeader(name, flags) addr = mem[H] - mem[mem[H]] = DOCOL - mem[H] += 1 + dictWrite(DOCOL) - for wordAddr in wordAddrs - mem[mem[H]] = wordAddr - mem[H] += 1 - end + dictWrite(wordAddrs) return addr end @@ -159,8 +161,8 @@ function defNewVar(name::AbstractString, initial::Array{Int64,1}; flags::Int64=0 codeWordAddr = mem[H] varAddr = mem[H] + 1 - mem[mem[H]] = DOVAR; mem[H] += 1 - mem[mem[H]:(mem[H]+length(initial)-1)] = initial; mem[H] += length(initial) + dictWrite(DOVAR) + dictWrite(initial) return varAddr, codeWordAddr end @@ -173,8 +175,8 @@ function defConst(name::AbstractString, val::Int64; flags::Int64=0) codeWordAddr = mem[H] - mem[mem[H]] = DOCON; mem[H] += 1 - mem[mem[H]] = val; mem[H] += 1 + dictWrite(DOCON) + dictWrite(val) return codeWordAddr end @@ -211,7 +213,6 @@ end) # Dictionary entries for core built-in variables, constants H_CFA = defExistingVar("H", H) -#LATEST_CFA = defExistingVar("LATEST", LATEST) PSP0_CFA = defConst("PSP0", PSP0) RSP0_CFA = defConst("RSP0", RSP0) @@ -695,7 +696,7 @@ end) # Dictionary searches -LFATOCFA_CFA = defPrimWord("LFA>CFA", () -> begin +FROMLINK_CFA = defPrimWord("LINK>", () -> begin addr = popPS() lenAndFlags = mem[addr+1] @@ -706,10 +707,21 @@ LFATOCFA_CFA = defPrimWord("LFA>CFA", () -> begin return NEXT end) -TOBODY_CFA = defWord(">BODY", [INCR_CFA, EXIT_CFA]) +createHeader("FORTH", 0) +FORTH_CFA = mem[H] +dictWrite(defPrim(() -> begin + mem[CONTEXT] = reg.W + return NEXT +end, name="FORTH")) +dictWrite(0) # cell for latest -FORTH_CFA = defExistingVar("FORTH", FORTH) -CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 100)) +CURRENT_CFA = defExistingVar("CURRENT", CURRENT) + +# Switch to new FORTH vocabulary cfa +mem[FORTH_CFA+1] = mem[mem[CURRENT]+1] +mem[CURRENT] = FORTH_CFA + +CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 10)) mem[CONTEXT] = FORTH_CFA NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1) @@ -720,16 +732,16 @@ FIND_CFA = defPrimWord("FIND", () -> begin wordLen = mem[countedAddr] word = lowercase(getString(wordAddr, wordLen)) - context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT])] + context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT]-1)] lenAndFlags = 0 lfa = 0 for vocabCFA in reverse(context) - callPrim(mem[vocabCFA]) - lfa = popPS() + lfa = vocabCFA+1 + + while (lfa = mem[lfa]) > 0 - while lfa > 0 lenAndFlags = mem[lfa+1] len = lenAndFlags & F_LENMASK hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN @@ -738,14 +750,11 @@ FIND_CFA = defPrimWord("FIND", () -> begin continue end - thisAddr = latest+2 - thisWord = lowercase(getString(thisAddr, len)) + thisWord = lowercase(getString(lfa+2, len)) - if lowercase(thisWord) == lowercase(word) + if thisWord == word break end - - lfa = mem[lfa] end if lfa>0 @@ -755,7 +764,7 @@ FIND_CFA = defPrimWord("FIND", () -> begin if lfa > 0 pushPS(lfa) - callPrim(mem[LFATOCFA_CFA]) + callPrim(mem[FROMLINK_CFA]) if (lenAndFlags & F_IMMED) == F_IMMED pushPS(1) else @@ -889,8 +898,8 @@ end, name="DODOES") DOES_HELPER_CFA = defPrimWord("(DOES>)", () -> begin - pushPS(mem[mem[CURRENT]]) - callPrim(mem[LFATOCFA_CFA]) + pushPS(mem[mem[CURRENT]+1]) + callPrim(mem[FROMLINK_CFA]) cfa = popPS() runtimeAddr = popPS() @@ -901,7 +910,7 @@ DOES_HELPER_CFA = defPrimWord("(DOES>)", () -> begin end)), name="doesPrim") return NEXT -end, flags=F_IMMED) +end, flags=F_IMMED | F_HIDDEN) DOES_CFA = defWord("DOES>", [LIT_CFA, LIT_CFA, COMMA_CFA, HERE_CFA, LIT_CFA, 3, ADD_CFA, COMMA_CFA, @@ -919,7 +928,7 @@ RBRAC_CFA = defPrimWord("]", () -> begin end, flags=F_IMMED) HIDDEN_CFA = defPrimWord("HIDDEN", () -> begin - lenAndFlagsAddr = mem[mem[CURRENT]] + 1 + lenAndFlagsAddr = mem[mem[CURRENT]+1] + 1 mem[lenAndFlagsAddr] = mem[lenAndFlagsAddr] $ F_HIDDEN return NEXT end) @@ -939,7 +948,7 @@ SEMICOLON_CFA = defWord(";", EXIT_CFA], flags=F_IMMED) IMMEDIATE_CFA = defPrimWord("IMMEDIATE", () -> begin - lenAndFlagsAddr = mem[mem[CURRENT]] + 1 + lenAndFlagsAddr = mem[mem[CURRENT]+1] + 1 mem[lenAndFlagsAddr] = mem[lenAndFlagsAddr] $ F_IMMED return NEXT end, flags=F_IMMED)