X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=src%2Fforth.jl;h=f10ea045cedc74258f737254a55e0cce0746c3a7;hb=e57561fe2d6e29350b0bfb580d7129910ece9689;hp=890cf241e66d5eee8f4fc9913f5345f50bb43480;hpb=ebff3ca5a9b2dd5a6608b696e7862aa7264f6682;p=forth.jl.git diff --git a/src/forth.jl b/src/forth.jl index 890cf24..f10ea04 100644 --- a/src/forth.jl +++ b/src/forth.jl @@ -13,7 +13,7 @@ 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 @@ -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") @@ -707,10 +709,12 @@ FROMLINK_CFA = defPrimWord("LINK>", () -> begin return NEXT end) +NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1) + createHeader("FORTH", 0) FORTH_CFA = mem[H] dictWrite(defPrim(() -> begin - mem[CONTEXT] = reg.W + mem[CONTEXT + mem[NUMCONTEXT] - 1] = reg.W return NEXT end, name="FORTH")) dictWrite(0) # cell for latest @@ -723,41 +727,31 @@ mem[CURRENT] = FORTH_CFA CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 10)) mem[CONTEXT] = FORTH_CFA -NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1) - -FIND_CFA = defPrimWord("FIND", () -> begin +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) - lfa = vocabCFA+1 - - while (lfa = mem[lfa]) > 0 - - lenAndFlags = mem[lfa+1] - len = lenAndFlags & F_LENMASK - hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN - - if hidden || len != wordLen - continue - end + while (lfa = mem[lfa]) > 0 - thisWord = lowercase(getString(lfa+2, len)) + lenAndFlags = mem[lfa+1] + len = lenAndFlags & F_LENMASK + hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN - 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 @@ -778,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 @@ -993,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