Saturday, April 24, 2010

Translator – Data Type (Table Updates)

Before working on the design of the routines that will handle the matching of the data types and finding the correct code, I decided to make the changes to the table entries for the new operand data type (operand_datatype) array and associated code (assoc_code) array and make sure these compile. The number of arguments member (nargs) was also renamed to the number of operands (noperands). New access functions for these members were added to the Table class.

All the table entries for the operators and internal functions were updated with the new values. The number of operands (previously nargs) for all of the operators were previously set to zero, so these were changed to 1 for the unary or 2 for the binary operators. The data type for many operators were also incorrectly set to None, so these was changed to the appropriate data type.

New entries for all the associated codes were added to the table and their codes were added to the Code enumeration. An entry for the CDBL functions was missing and was added. An entry for a new function FRAC was also added (this function will return the fractional part of a floating point values).

The integer division operator (“\” or IntDiv) is intended to be used with double operands, which will be rounded and converted to integers internally before the division. The operand data types could have been set to the integer data type, but then the CvtInt would always be inserted for both operands.  This operator only has one code and should not be used with integer operands as the regular division should be used, but this will be allowed (CvtDbl will be inserted, but only to be converted back to integers internally).

The Power operator will have three forms, the standard double/double (Power) and integer/integer (PowerInt), but there will also be a double/integer code (PowerMul). The PowerInt will use integer multiplication internally. The idea for the PowerMul code is for it to also use multiplication internally instead of calling the standard C pow() function for speed. However, the pow() function may already have these optimizations, so this may be unnecessary. Some experiments will be needed to determine which is more efficient. The goal is to allow the programmer to use an expression like A^2 instead of A*A and not be penalized by slow execution.

Translator – Associated Codes

Operators and some internal functions allow different operand data types, each will have it's own code (e.g. Add, AddInt, and CatStr), but only one name in the source (e.g. “+”). The Parser will only find the first one in the table since the Parser is only responsible for breaking the source into tokens, not looking at data types and determining appropriate codes. It is the Translator's responsibility to examine and validate the operands of operators and internal functions and to set the token to the appropriate code.

To accomplish this, the first entry in the table (that the Parser finds, the default entry), which for many will be the code that handles the double data type, will contain the other codes associated to the main code. These codes will be put into an associated code array in the table entry.

After obtaining the data types of the operands from the done stack, the Translator will check to see if there is a match to the code by checking the required operand data types in the code's table entry. If there is no match, then each of the associated code table entries will be checked for a match.

In addition to an exact match, there will also be a convertible match. With this type of match, hidden conversion codes can be inserted to obtain the desired data types. The exact match will be preferred so that the correct code is used. For example, if the first exact match or convertible match is used, then for Integer + Integer, the Translator would use the default Add code (for doubles) and add two CvtInt instead of using the preferred AddInt code. Next, how a convertible match will be detected...