X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=src%2Fforth.jl;h=9df99d08d103aca667075911fa5012e0e5fcbe76;hb=69aba7543145b983179ba7998d06a6459cc28a1a;hp=9668025d1c83b1b119c4d0b88995f2c9eba51305;hpb=9bfbc52aa2ba873acd40fada868bf26b3e26d8ae;p=forth.jl.git diff --git a/src/forth.jl b/src/forth.jl index 9668025..9df99d0 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") @@ -583,6 +585,14 @@ end) sources = Array{Any,1}() currentSource() = sources[length(sources)] +CLOSEFILES_CFA = defPrimWord("CLOSEFILES", () -> begin + while currentSource() != STDIN + close(pop!(sources)) + end + + return NEXT +end) + EOF_CFA = defPrimWord("\x04", () -> begin if currentSource() != STDIN close(pop!(sources)) @@ -638,8 +648,8 @@ function getLineFromSTDIN() elseif key == '\b' if !isempty(line) + print("\b\033[K") line = line[1:length(line)-1] - print("\b \b") end elseif key == '\e' @@ -654,6 +664,9 @@ function getLineFromSTDIN() end end + elseif key == '\t' + # Currently do nothing + else print(key) line = string(line, key) @@ -726,39 +739,30 @@ mem[CURRENT] = FORTH_CFA CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 10)) mem[CONTEXT] = FORTH_CFA -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 + 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 @@ -779,6 +783,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 @@ -994,8 +1023,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 @@ -1010,7 +1042,7 @@ QUIT_CFA = defWord("QUIT", BRANCH_CFA,-4]) ABORT_CFA = defWord("ABORT", - [PSP0_CFA, PSPSTORE_CFA, QUIT_CFA]) + [CLOSEFILES_CFA, PSP0_CFA, PSPSTORE_CFA, QUIT_CFA]) BYE_CFA = defPrimWord("BYE", () -> begin println("\nBye!")