From: Tim Vaughan Date: Tue, 31 May 2016 21:46:12 +0000 (+1200) Subject: Broken draft of vocab implementation. X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=commitdiff_plain;h=4db66d36d79a44ae2c32443c06b3ddad84cae531;p=forth.jl.git Broken draft of vocab implementation. --- diff --git a/src/forth.jl b/src/forth.jl index 89c4c0d..57fda1b 100644 --- a/src/forth.jl +++ b/src/forth.jl @@ -17,13 +17,15 @@ primNames = Array{ASCIIString,1}() nextVarAddr = 1 H = nextVarAddr; nextVarAddr += 1 # Next free memory address -LATEST = nextVarAddr; nextVarAddr += 1 # LFA of latest word in systetm dict +FORTH = nextVarAddr; nextVarAddr += 1 # LFA of latest word in system dict +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[LATEST] = 0 # no previous definition +mem[FORTH] = 0 # no previous definition +mem[CURRENT] = FORTH # Compile words to system dict initially DICT = mem[H] # Save bottom of dictionary as constant @@ -108,8 +110,8 @@ F_HIDDEN = 64 NFA_MARK = 128 function createHeader(name::AbstractString, flags::Int64) - mem[mem[H]] = mem[LATEST] - mem[LATEST] = mem[H] + mem[mem[H]] = mem[mem[CURRENT]] + mem[mem[CURRENT]] = mem[H] mem[H] += 1 mem[mem[H]] = length(name) | flags | NFA_MARK; mem[H] += 1 @@ -209,7 +211,7 @@ end) # Dictionary entries for core built-in variables, constants H_CFA = defExistingVar("H", H) -LATEST_CFA = defExistingVar("LATEST", LATEST) +#LATEST_CFA = defExistingVar("LATEST", LATEST) PSP0_CFA = defConst("PSP0", PSP0) RSP0_CFA = defConst("RSP0", RSP0) @@ -693,7 +695,7 @@ end) # Dictionary searches -TOCFA_CFA = defPrimWord(">CFA", () -> begin +LFATOCFA_CFA = defPrimWord("LFA>CFA", () -> begin addr = popPS() lenAndFlags = mem[addr+1] @@ -706,6 +708,11 @@ end) TOBODY_CFA = defWord(">BODY", [INCR_CFA, EXIT_CFA]) +FORTH_CFA = defExistingVar("FORTH", FORTH) +CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 100)) +mem[CONTEXT] = FORTH_CFA +NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1) + FIND_CFA = defPrimWord("FIND", () -> begin countedAddr = popPS() @@ -713,30 +720,42 @@ FIND_CFA = defPrimWord("FIND", () -> begin wordLen = mem[countedAddr] word = lowercase(getString(wordAddr, wordLen)) - latest = LATEST + context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT])] + lenAndFlags = 0 - - i = 0 - while (latest = mem[latest]) > 0 - lenAndFlags = mem[latest+1] - len = lenAndFlags & F_LENMASK - hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN - - if hidden || len != wordLen - continue + lfa = 0 + + for vocabCFA in reverse(context) + callPrim(mem[vocabCFA]) + lfa = popPS() + + while lfa > 0 + lenAndFlags = mem[lfa+1] + len = lenAndFlags & F_LENMASK + hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN + + if hidden || len != wordLen + continue + end + + thisAddr = latest+2 + thisWord = lowercase(getString(thisAddr, len)) + + if lowercase(thisWord) == lowercase(word) + break + end + + lfa = mem[lfa] end - - thisAddr = latest+2 - thisWord = lowercase(getString(thisAddr, len)) - if lowercase(thisWord) == lowercase(word) + if lfa>0 break end end - if latest > 0 - pushPS(latest) - callPrim(mem[TOCFA_CFA]) + if lfa > 0 + pushPS(lfa) + callPrim(mem[LFATOCFA_CFA]) if (lenAndFlags & F_IMMED) == F_IMMED pushPS(1) else @@ -870,8 +889,8 @@ end, name="DODOES") DOES_HELPER_CFA = defPrimWord("(DOES>)", () -> begin - pushPS(mem[LATEST]) - callPrim(mem[TOCFA_CFA]) + pushPS(mem[mem[CURRENT]]) + callPrim(mem[LFATOCFA_CFA]) cfa = popPS() runtimeAddr = popPS() @@ -900,7 +919,7 @@ RBRAC_CFA = defPrimWord("]", () -> begin end, flags=F_IMMED) HIDDEN_CFA = defPrimWord("HIDDEN", () -> begin - lenAndFlagsAddr = mem[LATEST] + 1 + lenAndFlagsAddr = mem[mem[CURRENT]] + 1 mem[lenAndFlagsAddr] = mem[lenAndFlagsAddr] $ F_HIDDEN return NEXT end) @@ -920,7 +939,7 @@ SEMICOLON_CFA = defWord(";", EXIT_CFA], flags=F_IMMED) IMMEDIATE_CFA = defPrimWord("IMMEDIATE", () -> begin - lenAndFlagsAddr = mem[LATEST] + 1 + lenAndFlagsAddr = mem[mem[CURRENT]] + 1 mem[lenAndFlagsAddr] = mem[lenAndFlagsAddr] $ F_IMMED return NEXT end, flags=F_IMMED) diff --git a/src/lib_1_basic.4th b/src/lib_1_basic.4th index 90fad63..dc8c584 100644 --- a/src/lib_1_basic.4th +++ b/src/lib_1_basic.4th @@ -59,9 +59,12 @@ ['] LIT , , ; +: LATEST + CURRENT @ ; + : RECURSE IMMEDIATE LATEST @ \ LATEST points to the word being compiled at the moment - >CFA \ get the codeword + LFA>CFA \ get the codeword , \ compile it ; diff --git a/src/lib_8_decompiler.4th b/src/lib_8_decompiler.4th index d9c9f3a..5daa501 100644 --- a/src/lib_8_decompiler.4th +++ b/src/lib_8_decompiler.4th @@ -37,7 +37,7 @@ DROP ( at this point, the stack is: start-of-word end-of-word ) SWAP ( end-of-word start-of-word ) - DUP >CFA @ CASE + DUP LFA>CFA @ CASE DOCOL OF \ Colon definition [CHAR] : EMIT SPACE DUP 1+ .NAME SPACE @@ -61,7 +61,7 @@ 4 SPACES - >CFA >BODY ( get the data address, ie. points after DOCOL | end-of-word start-of-data ) + LFA>CFA >BODY ( get the data address, ie. points after DOCOL | end-of-word start-of-data ) ( now we start decompiling until we hit the end of the word ) BEGIN ( end start )