Wednesday, February 4, 2015

Table – Operand Text Virtual Function

The operand text function is called to obtain the text for the operand of a code (for example, the name of a variable or the value of numeric constant).  It is used when a program code for line is decoded into a list of tokens (an then back to the original text of the line).  It is also used for test output.  In both cases it had to check if the code has an operand (using the is code with operand access function) before calling the virtual function.

Similar to the encode functions that control the back insert iterator as needed when the code has an operand, the operand text function should control the advancing of the iterator being used to iterate over the program line if the code has an operand.   The default operand text function does nothing and does not need to advance this iterator.  For now the operand text function was modified to check if the operand text function pointer member is set and then calls the function, otherwise a blank string is returned.

Program Line Reader Class

A regular iterator could have been used with the operand text functions, but the code would look messy (dereference and increment operators would be required).  To make the code more readable and the iterator easier to use, it was encapsulated within a new small Program Line Reader function operator class.

The Program Line Reader class contains two members, the iterator itself and an end iterator used to check for the end the line.  The constructor contains three arguments, the begin iterator of the program code vector, the offset for the start of the program line, and the size of the line.  These values are used to calculate the initial value of the iterator (begin plus offset) and end iterator (iterator plus size).

This class contains three access functions.  The function operator function itself returns the program word pointed to be the iterator and advances the iterator.  The has more words function returns if there are more words in the program line (iterator is not equal to the end iterator).  And there is a previous function for returning the previous word obtained (word before the iterator), which is used by the program model debug text function to get the raw value of the operand to output when there is an operand (the operand text function advances the iterator past this word).

The operand text functions were modified to take a reference to the program line reader instance instead of the operand itself so the codes with operands can advance the iterator as needed (and the other codes without operands do nothing). 

Operand Text Sub-Code Argument

The operand text functions for the variable codes previously added the data type change to the string.  This was only required for test output and was inhibited for normal operation when a program line was decoded into tokens (this character is added later when the tokens are converted into text using the data type of the code table entry).  The sub-code was passed as an argument and when decoding a line, the sub-code was set to a special No Data Type Character sub-code.  The reverse logic made the code less readable.

Eventually the debug/test code will be removed (as much as possible) from the regular application into separate unit test programs.  Adding the data type character was moved from the operand text functions of the variable codes to the program model debug text function.  This was the only use of the sub-code argument, so it was removed from the operand text functions.  The special sub-code enumerator was also removed.

Decoding Into Tokens

The program model decode function, a user of the operand text function, was modified to use the new Program Line Reader class.  It previously created a token from the table entry of the code in the program word.  It then added the sub-code to the token and if the code had an operand, called the operand text function with the No Data Type Character sub-code to prevent adding the data type character and put the resulting string into the string of the token.

Since this section made heavy use of the token, a new token constructor was added to do this work.  The arguments for this new constructor are a pointer to the program unit (for code with operands that need to access the dictionaries) and a reference to the program line reader instance used for iterating over the program line.

The new constructor obtains a program word from the program line reader instance.  The entry member is set to the table entry for the code of the word.  The sub-code member is set to the sub-code of the word.  The operand text function for the entry is called passing the program unit pointer and program line reader.  The string returned is put into the string member.  The string is blank for codes that do not have an operand.

Encoder Tests

The encoder tests did not contain a test where the double data type # character was tested on a variable.  One line in encoder test #1 was modified to contain a variable with the # character on both on the left side (reference) and right side (value) of an assignment.  The expected results for this test were updated accordingly.

[branch table commit ddc2efabbd]