( Fixes to make jonesforth somewhat livable. ) HEX ( Step 1: Proper, working ------------------------------------- Technically, this should be CREATE DOES>, but that's a bit more work, and my own Forth implementation doesn't go to all that trouble, so I shan't bother here. This is heavily based on what my implementation does. ). 3. Push the address of the second cell of the data area (the start of actual usable space) to the data stack. 4. Resume interpretation by performing the NEXT operation. Interestingly, this code winds up being a multiple of four bytes long, and thus requires no alignment afterwards (four instructions at three bytes each is twelve bytes, thus aligned; one instruction at one byte plus the NEXT operation at three bytes is four bytes, thus aligned). ) VARIABLE dodoes HERE @ dodoes ! ( This is "PUSHRSP $esi" from jonesforth.S ) 8D C, 6D C, FC C, ( LEA EBP, [EBP-4] ) 89 C, 75 C, 0 C, ( MOV [EBP], ESI ) ( Load the threaded code pointer ) 8B C, 70 C, 4 C, ( MOV ESI, [EAX+4] ) ( Push the address of the start of the user data area ) 83 C, C0 C, 8 C, ( ADD EAX, 8 ) 50 C, ( PUSH EAX ) NEXT ( And resume interpretation ) : is an unusual word. It causes execution of the current definition to stop when it is reached. Further code in the definition beyond DOES> is set up to be executed when the word created by R> ( next xt in current defintion ) LATEST @ ( latest definition ) >DFA ! ( store in first slot of data area ) ; ( Step 2: Variables that allow further allocation into their data area -------------------------------------------------------------------- VARIABLEs can be more convenient if they allow for allocating more than a single cell of contiguous storage, even though this is explicitly not required by the standard (dpANS94, section 3.3.3.3). jonesforth variables don't allow that, by design. If, instead of monkeying about with ALLOT before defining what amounts to a constant (seriously, compare the definitions of CONSTANT and VARIABLE in jonesforth.f), it compiled ' LIT , HERE @ 8 + , ' EXIT , 0 , it would allow for contiguous allocation of the sort that we want. The reason this would work is that the literal value for the constant is one cell wide, and the address of EXIT is one cell wide, thus 8 bytes total, and adding the value of the current dictionary pointer points to the 0 that is comma'd in as storage for the variable. However, rather than doing all that, we'll just provide an example of using , as follows: ) : VARIABLE ; ( Step 3: ALLOT that doesn't suck ------------------------------- ALLOT isn't supposed to return an address, it's just supposed to move the dictionary pointer (dpANS94, section 6.1.0710). ) : ALLOT ( n -- ) HERE @ + HERE ! ; ( Step 4: Standard-conforming HERE -------------------------------- HERE isn't supposed to be a VARIABLE, it's supposed to return the address of the end of the dictionary space (dpANS94, section 3.3.3.2). Now that we have working ALLOT, we can fix HERE. ) : HERE HERE @ ; ( EOF )