Thursday, October 3, 2013

Remark Dictionary

The remark dictionary is the first dictionary implemented.  This is the simplest dictionary as it only needs to store the string of a comment, so the base dictionary is sufficient for this dictionary.  The ProgramUnit class was added to contain the remark dictionary, which is defined as a pointer and allocated in the ProgramUnit constructor.  A pointer was used since all the other program units will use the same remark dictionary.

Previously, the encoder encode routine just set the operand to zero and was modified to call the encode function for the code with an operand.  For now, if the code does not have an encode function, the operand is still set to zero.  The encode functions contain arguments for the pointer to the current program unit and the pointer to the token being encoded.  Additional arguments will probably be needed, but these are sufficient for now.

The rem encode function was implemented, which simply passes the token to the add function of the remark dictionary and returns the index of the entry to be set as the operand word.  The pointer to an encode function was added to the table entry structure and a table access function was added to return this pointer.  A pointer to the rem encode function was added to the REM command and REM operator code table entries.

For testing, a temporary program unit was added to the main tester run routine and a pointer to it is passed to the encode input routine, which passed to the encode routine.  Additional remarks were added to encoder test #1 including one set of duplicate comments to test that a single entry is stored in the dictionary.  Currently only the index value is output as the string (of the remark) is not yet retrieved, which will be the subject of the next change.  For now, the current output of this test (though incomplete) was copied for the expected results.  Though this makes the test pass, the purpose for changing this file was detect changes as more of the encode routines are implemented.

[commit d2222df1d8]

Base Dictionary Class

A dictionary will hold a list of strings (keys) for the program for a particular type of item (remark, constants, variables, arrays, etc.).  The index of the name will be stored in the program.  When the program is running, the index will be used to access an item (constant, variable value, etc.).  When the program is converted back to text (recreated) for display in the GUI, the index will be used to recover the originally entered string.

There are several member variables and functions that every dictionary will have.  The variables include a stack of index values of entries that have been removed sp they can be reused, a list of entry keys, a map of entry keys to index values, and a entry use count.  The functions include adding and removing entries to and from the dictionary.

The key list variable (QStringList) holds the list of keys.  The index of the key within this list is the index stored in the program.   The index is converted back to a string by using the key list.  The purpose of the key map variable is for an efficient way of looking up a string in the dictionary for its index.  The string could be looked up in the key list but would require a slow sequential search since it is unsorted.  The key map variable (QMap<QString,&nbspint>) where the map stores the string as the key and the index as the value and allows for fast look up of keys.  Since the  QString class supports the implicit sharing feature of Qt, there is only one actual copy of each string.

The use count variable (QList<quint16>) hold the number of times the string is used in the program.  On first use, the use count entry for the key is set to one.  For each additional use, the use count for the key is incremented, and for each time it is removed from the program, the use count is decremented.  When the use count for a key drops to zero, the key is removed from the dictionary.  The use count list mirrors the key list.

The add function starts by looking up the string of a token in the key map to get its index.  If not in the key map, the string is added to the dictionary.  If the free stack is empty, then the index for the string is set to the size of the key list and the string is appended to it.  A value of one is appended the use count list.  Otherwise, an index of popped from the free stack and the token string is set at that location in the key list and a one is set in the use count list.  The token string is added to the key map.  If already in the dictionary, the use count entry for the string is incremented.  The status of whether a new entry was added to the dictionary is returned, which will be used by derived dictionaries to know when to add additional information to the dictionary.

The remove function decrements the use count for index of an entry.  If the use count is zero, the key is obtained from the key list and removed from the key map.  The string in the key list is cleared (freeing the string).  The now unused index is pushed to the free stack for reuse when a new string is added.