Sunday, May 30, 2010

Translator – LET Command (Release)

The LET command is implemented and working. A new set of translator test inputs were added for commands, with LET statements for each possible assignment (each data type, non-list and list) with the LET keyword were included. Three error test inputs were added also, one with a two LET keywords, one with a LET keyword in the middle, and a PRINT (to test the “not yet implemented” error).

The plan was to release a whole series of development releases (0.1.12-dev-X) starting with the LET command, but some many changes were made to the code (including the parser correction, parser test updates, token handlers, etc.) from the 0.1.11 release, that this release will be an official Translator development release (0.1.12). This will probably continue for each command added to the Translator.  Sub-developmental releases may still be used for the more complex commands.

This release also contains regression test scripts that were used during the latest round of changes. The scripts saved a lot of command line typing due to all the reorganization of the code (token handlers, token status and token mode changes). A Windows batch file equivalent is also included, but does not work near as nice because of the limitations of the Window compare utility. Both scripts delete any current output files, runs the tests and then compares to the files in the test directory.

The Translator now has initial support for commands with just the LET/Assignment statement supported and ibcp_0.1.12-src.zip has been uploaded at Sourceforge IBCP Project along with the binary for the program. Next, implementing the PRINT command...

Translator – LET Command (Implementation)

The SimpleStack class is used for the new command stack, which will hold a CmdItem structure consisting of a token pointer and a code. The code will initially be set from the token's index, but may be changed to other associated codes as commands are processed by the Translator. Since the hold and done stacks are also simple stacks, these were changed from the List class to the SimpleStack class. This only required minor changes to push and pop calls for these stacks.

As previously hinted, the Translator status enumeration needed to be moved outside the Translator class before the TableEntry structure. The enumeration was renamed TokenStatus as that seemed appropriate for the return value of the Translator's add token function. Each of the enumeration values were also renamed except for the BUG statuses, which were left alone.

A previously mentioned, the mode must be changed from Command to Assignment upon receiving the LET command token. Some commands will need to change the mode from Command to Expression (PRINT, IF, WHILE, etc.). Some commands will need to change the mode from Command to a new End-of-Statement mode, since nothing is expected after command keyword (END IF, DO, LOOP, etc.).

Having an every growing switch statement of the command code is not efficient. Therefore, a next token mode value was added to the TableEntry structure. When a command token is received, if the mode is currently Command, then the mode will be changed to the command's table entry next token mode value. The command will be pushed onto the command stack along with it's current code. No further action needs to be taken until the rest of the statement is processed.

Since there will be mode values in the TableEntry structure, the Translator mode enumeration was also moved before TableEntry and renamed TokenMode (again an appropriate name). The enumeration values were also renamed to reflect this. For now, if the next token mode is not set for a command (a new Null token mode value), then a “not yet implemented” bug error occurs. If the current mode is not Command, then a new “unexpected command” message occurs.

For the LET command, the next token mode value is Assignment. When an assignment operator is added to the output list, if there is a LET command on the command stack, it is popped and the assignment operator's token's LET sub-code flag is set. For now, since the command stack should be empty, the end-of-line processing only needs to check if the command stack is empty. Later it will need to process commands on the stack.