FUTURE86(ID:7402/)





Related languages
Fifth => FUTURE86   Evolution of

References:
  • Mike Bunnell and Mitch Bunnell. VARIABLE-LEVEL PROGRAMMING. Dr. Dobbs Journal, June, 1989. view details Extract: FUTURE86
    The FUTURE86 Language

    The history of FUTURE86 dates back to 1979. At this time Akira Katagiri, a Japanese scientist, implemented a Forth compiler for a Z-80-based microcomputer system. During this work, he found some deficiencies in this language, most notably the lack of readability. He then devised a successor, appropriately called FIFTH, and implemented it on different environments. FIFTH is widely used in Japan.

    FUTURE86 is an evolution of FIFTH created during the 1980s. The first compiler was commercially available in 1987. Like FIFTH, it augmented the power of Forth without being just another Forth dialect. Despite its short history, FUTURE86 has already been used to implement numerous projects. For example, software for sophisticated, automatic postal scales and a natural language compiler has used FUTURE86. Like Forth, every FUTURE86 program implicitly operates on two stacks, called the data stack (that is, "stack") and the return stack. These names are a little bit misleading, because the return stack may also contain temporary data in addition to return addresses. Most predefined functions, however, operate on the data stack.

    An expression is written in reverse polish notation (RPN). The sentence 15 27 101 + for instance pushes the numbers 15, 27, and 101 sequentially onto the data stack. The operation "+" then consumes the two topmost elements, 27 and 101, and replaces them by their sum. The data stack now contains the numbers 15 and 128. For readers unfamiliar with Forth or the Hewlett-Packard pocket calculators, this may look strange. In practice, you soon get acquainted with this type of operation.

    Not everything in FUTURE86 is RPN, however, because this paradigm only applies to the evaluation of programs. Compile time expressions, on the other hand, are written in the more traditional infix notation. The following statements, for instance, set MAXLENGTH to 1024.

    BUFSIZE EQU 256 NO-OF-BUFFERS EQU 4 MAXLENGTH EQU BUFSIZE * NO-OF-BUFFERS

    In fact, every sentence may contain compile time expressions in infix notation by enclosing them in parentheses, like this:
    17 (34 * 45 + 8) VAR @ OVER -

    Other differences from Forth concern the dependency between words: Because FUTURE86 was designed as a compiled language, two-pass compilation allows extensive forward referencing. This even applies to different compilation units: It is common practice for words in different modules to mutually call each other.

    FUTURE86 also contains an assembler. Unlike Forth, assembler statements -- which may be freely intermixed with FUTURE86 words -- follow the syntax generally available on the target machine. On a 80186 system, you could for example, write: BOUND BX,[TESTLOC] inside any high-level definition. It is therefore the responsibility of the programmer to select the desired abstraction level at every single line of code!

    Other minor differences from Forth concern the usage of some reserved words. The FUTURE86 version of LOOP functions, for example, is slightly different than its Forth counterpart.

    Now let's look at how the sample programs are written in FUTURE86. Listing Three demonstrates one possible solution of the AUXOUT problem. The definition of AUXOUT, as every definition of a new word, starts with a colon, followed by the name of the function.

    We assume that the character to be output is located on the stack. That is, to send the escape character to the serial interface you write: 27 AUXOUT. The predefined word !DL pops the top value from the stack and stores it in the pseudo CPU DL register. Of course, words like !DL are hardware dependent. The next word, AUXOUT-FUN, pushes this constant onto the stack, which now contains the number 4 only; the 27 is still in pseudoregister DL. Then, the word INT_21H is called. This function removes the top value of the stack (4), uses it as DOS function code (that is, pushes it into AH) and performs an interrupt (21 hex). The semicolon closes the definition.

    At first, words like !DL seem strange for programmers getting used to traditional languages such as Fortran or Pascal. In reality, however, even this enhances readability. Because FUTURE86 --such as Forth or Lisp --is not committed to the traditional "Letter+Digit" identifiers, one can devise more meaningful names, like: IS-THERE-STILL-ROOM-IN-THE-BUFFER? which, by the way, is a perfectly legal FUTURE86 word. In the case of !DL, one needs to understand that the exclamation mark is generally used in the context "store from stack into ...," while the character "@" does the inverse.

    The SFILT program in Listing Four is more complicated. The function XTRANS was --for testing purposes --defined as nonoperation, which is the shortest possible function definition. To comprehend SFILT, you have to understand FUTURE86's unique string concept.

    A string always consists of two parts: A string buffer somewhere in memory, holding left justified the string characters, and a control block called SINFO (String INFOrmation), consisting of a pointer to the buffer and a length field. For string operations the SINFO is stored in the data stack. The simplest way to create a string is to place it within a quote, like this:

    : HELLO "Hello world!" SPRINT;

    The execution of HELLO would allocate a place in memory, large enough to hold all the characters, place the appropriate SINFO on the data stack and call the word SPRINT (String PRINT), which causes the string to be printed.

    Our definition of SFILT assumes that the SINFO's of the destination string T and the source string S (in that order) are placed on the stack. On return, these SINFOs should be replaced by the updated SINFO of the destination string. This behavior of SFILT is depicted in the comment line labeled "stack flow."

    Following the C example SFILT starts by determining the source strings length, which is the second part of its SINFO and therefore on top of the stack. Because IF consumes its argument, this data item has to be duplicated by the word SLEN. Many FUTURE86 functions remove their arguments from the stack, so this is quite a common operation.

    The next steps (CGET and XTRANS) remove the first character from the source string and transform it. The following three lines temporarily save the character to the return stack, interchange the stack position of the two SINFOs, then restore the character to the stack.

    The word C+ appends the character to the destination string. Then, the SINFOs stack position is interchanged again SFILT is recursively called.

    The ELSE part simply discards the now empty SINFO of the source string from the stack to fulfill the functional description of SFILT. The word THEN matches the IF and is similar to Fortran's ENDIF statement.

    The lines below demonstrate the usage of SFILT. The destination buffer is called DEST and may hold up to 80 bytes. This buffer is initialized with the function SETUP.MAIN calls SETUP, then SFILT, and finally prints the resulting string using SPRINT. This also shows how words work together: As mentioned, SFILT leaves the destination string's SINFO on the stack which, in turn, is consumed by SPRINT.