21.3 Differences between 4tH and ANS-Forth. 4tH 4tH Forth compiler
広告
広告
CHAPTER 21. PORTING GUIDE
21.3
Differences between 4tH and ANS-Forth
383
Like any software, 4tH is a compromise. We have to address the requirements of both newbies and power users, which means we have to make choices
1 concerning ANS-Forth compliancy. There are several reasons why 4tH is not completely ANS-Forth compliant:
1. 4tH uses a different architecture which makes it impossible to be ANS-Forth compliant, so some constructions are simply not feasible;
2. Some constructions in ANS-Forth are considered to be illogical, unelegant, bloated, not intuitive, error prone, inefficient or otherwise not acceptable;
3. 4tH maintains a close relationship with C, so it is more logical and efficient to use
C-conventions instead of ANS-Forth conventions.
Where possible, we try to minimize the consequences for our users by hiding the differences behind abstractions or other transparent solutions. But sometimes, we simply can’t.
In this section we will show you which differences there are between 4tH and ANS-Forth and how you can either avoid or resolve them.
21.3.1
Strings
In 4tH, strings are stored in an ASCIIZ format. ANS-Forth uses counted strings. In
4tH there is no such thing as a countbyte, since it uses a terminator. If you limit the use of ’COUNT’ only to string variables and constants, and exclusively use ’PLACE’ or
’+PLACE’ you should be fine, since the address/count convention of ANS-Forth is fully supported. Should you resort to low level operations which require a terminator, you might have to define an equivalent word in ANS-Forth to make your program portable.
’S"’ does have interpretation semantics, but the string stored at the address ’S"’ returns might have a very short lifespan, depending on your ANS-Forth compiler. 4tH has a transparent, circular buffer that protects the string from overwriting, but when you port your program you might not be that lucky. Note that ANS-Forth does not require compilers to provide these facilities.
21.3.2
Double numbers
4tH uses only signed 32 bit cells, but some words in ANS-Forth, like ’<#’, ’#>’, ’FILE-
SIZE’, ’FILE-POSITION’ and ’REPOSITION-FILE’ require the use of double numbers.
You can easily fix this by adding ’S>D’, which converts a number to a double number. Its counterpart, ’D>S’, is available too. In 4tH these words have no effect.
21.3.3
Booleans
Another nice topic for a flame war is the value of truth. In ANS-Forth the ’TRUE’ has the value "-1", which means all bits are set. Which is very clever. You can ’XOR’, ’OR’,
’AND’ and ’INVERT’ it with any other value and it will behave as logical value. But "the all bits set" flag has its drawbacks too. Let’s see what the ANS-Forth standard says about flags:
1
You may or may not agree with the choices we made, but you can rest assured we have given them considerable thought.
CHAPTER 21. PORTING GUIDE
"A FALSE flag is a single-cell datum with all bits unset, and a TRUE flag is a single-cell datum with all bits set. While Forth words which test flags accept any non-null bit pattern as true, there exists the concept of the wellformed flag. If an operation whose result is to be used as a flag may produce any bit-mask other than TRUE or FALSE, the recommended discipline is to convert the result to a well-formed flag by means of the Forth word 0<> so that the result of any subsequent logical operations on the flag will be predictable.
In addition to the words which move, fetch and store single-cell items, the following words are valid for operations on one or more flag data residing on the data stack: AND OR XOR INVERT"
384
We highly recommend the discipline of converting a non-zero value to a well-formed flag.
But we don’t understand why ’INVERT’ is a valid way to manipulate a flag. We’ll try to explain you why.
Forth traditionally has no specific logical operators. Instead, binary operators were used.
This put ’INVERT’ (or ’NOT’ as it was called in Forth-79) in a difficult position. ’IN-
VERT’ing any non-zero value will result in a non-zero value, except when all bits are set.
That is why ’0=’ was introduced, a full-fledged logical operator. So why use ’INVERT’ when you want to perform a logical operation? Another quote:
"Since a "char" can store small positive numbers and since the character data type is a sub-range of the unsigned integer data type, C! must store the n least-significant bits of a cell (8 <= n <= bits/cell). Given the enumeration of allowed number representations and their known encodings, "TRUE xx C! xx
C@" must leave a stack item with some number of bits set, which will thus will be accepted as non-zero by IF."
This is another problem of using "all bits set" as a true flag: you store a well formed flag in an address unit that should easily be able to handle it and you’ll never get it back. A flag is a boolean and can have two values: either true or false. The smallest unit that can hold a boolean is a bit. ANS-Forth programmers are denied that privilege.
But why are some Forth programmers so keen on their “all bits set” flag? Well, you can do neat things with it.
: >CHAR DUP 9 > 7 AND + ASCII 0 + ;
This will convert a digit to its ASCII representation. True, it is a clever piece of programming, but in our opinion it is bad style. Why? Because you are using a flag as a bitmask, which is a completely different datatype. Although there is no such thing as “data typing” in Forth, this way of programming makes it difficult to understand and maintain a program, which the ANS-Forth standard acknowledges:
"The discipline of circumscribing meaning which a program may assign to various combinations of bit patterns is sometimes called data typing. Many computer languages impose explicit data typing and have compilers that prevent ill-defined operations. Forth rarely explicitly imposes data-type restrictions. Still, data types implicitly do exist, and discipline is required, particularly if portability of programs is a goal. In Forth, it is incumbent upon the programmer (rather than the compiler) to determine that data are accurately typed."
ダウンロード
広告