X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=src%2Fforth.jl;h=f10ea045cedc74258f737254a55e0cce0746c3a7;hb=e57561fe2d6e29350b0bfb580d7129910ece9689;hp=c5c7175c8d73a397beeb912005cb8de05a332335;hpb=3c35d5caec5303e84c5de9dde74759f38280a3d3;p=forth.jl.git diff --git a/src/forth.jl b/src/forth.jl index c5c7175..f10ea04 100644 --- a/src/forth.jl +++ b/src/forth.jl @@ -13,19 +13,19 @@ mem = Array{Int64,1}(size_mem) primitives = Array{Function,1}() primNames = Array{ASCIIString,1}() -# Built-in variables +# Memory geography and 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 @@ -84,6 +84,8 @@ function putString(str::ASCIIString, addr::Int64) mem[addr:(addr+length(str)-1)] = [Int64(c) for c in str] end +stringAsInts(str::ASCIIString) = [Int(c) for c in collect(str)] + # Primitive creation and calling functions function defPrim(f::Function; name="nameless") @@ -117,8 +119,8 @@ 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 dictWrite(length(name) | flags | NFA_MARK) @@ -213,8 +215,6 @@ end) # Dictionary entries for core built-in variables, constants H_CFA = defExistingVar("H", H) -FORTH_CFA = defExistingVar("FORTH", FORTH) -CURRENT_CFA = defExistingVar("CURRENT", CURRENT) PSP0_CFA = defConst("PSP0", PSP0) RSP0_CFA = defConst("RSP0", RSP0) @@ -709,44 +709,49 @@ FROMLINK_CFA = defPrimWord("LINK>", () -> begin return NEXT end) -CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 100)) -mem[CONTEXT] = FORTH_CFA NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1) -FIND_CFA = defPrimWord("FIND", () -> begin +createHeader("FORTH", 0) +FORTH_CFA = mem[H] +dictWrite(defPrim(() -> begin + mem[CONTEXT + mem[NUMCONTEXT] - 1] = reg.W + return NEXT +end, name="FORTH")) +dictWrite(0) # cell for latest + +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 +FINDVOCAB_CFA = defPrimWord("FINDVOCAB", () -> begin + vocabCFA = popPS() countedAddr = popPS() + wordAddr = countedAddr + 1 wordLen = mem[countedAddr] word = lowercase(getString(wordAddr, wordLen)) - context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT]-1)] - + lfa = vocabCFA+1 lenAndFlags = 0 - lfa = 0 - - for vocabCFA in reverse(context) - callPrim(mem[vocabCFA]) - lfa = popPS() - while (lfa = mem[lfa]) > 0 + while (lfa = mem[lfa]) > 0 - lenAndFlags = mem[lfa+1] - len = lenAndFlags & F_LENMASK - hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN + lenAndFlags = mem[lfa+1] + len = lenAndFlags & F_LENMASK + hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN - if hidden || len != wordLen - continue - end - - thisWord = lowercase(getString(lfa+2, len)) - - if thisWord == word - break - end + if hidden || len != wordLen + continue end - if lfa>0 + thisWord = lowercase(getString(lfa+2, len)) + + if thisWord == word break end end @@ -767,6 +772,31 @@ FIND_CFA = defPrimWord("FIND", () -> begin return NEXT end) +FIND_CFA = defPrimWord("FIND", () -> begin + + countedAddr = popPS() + context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT]-1)] + + for vocabCFA in reverse(context) + pushPS(countedAddr) + pushPS(vocabCFA) + callPrim(mem[FINDVOCAB_CFA]) + + callPrim(mem[DUP_CFA]) + if popPS() != 0 + return NEXT + else + popPS() + popPS() + end + end + + pushPS(countedAddr) + pushPS(0) + + return NEXT +end) + # Branching @@ -887,7 +917,7 @@ end, name="DODOES") DOES_HELPER_CFA = defPrimWord("(DOES>)", () -> begin - pushPS(mem[mem[CURRENT]]) + pushPS(mem[mem[CURRENT]+1]) callPrim(mem[FROMLINK_CFA]) cfa = popPS() @@ -899,7 +929,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, @@ -917,7 +947,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) @@ -937,7 +967,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) @@ -982,8 +1012,11 @@ INTERPRET_CFA = defWord("INTERPRET", EXIT_CFA]) PROMPT_CFA = defPrimWord("PROMPT", () -> begin - if (mem[STATE] == 0 && currentSource() == STDIN) - println(" ok") + if currentSource() == STDIN + if mem[STATE] == 0 + print(" ok") + end + println() end return NEXT