Wednesday, August 7, 2013

New PRINT At Run-Time (Retracted)

After considering this design, it was decided to be more complicated than it needed to be, so this post has been retracted, see revised post.

Consider the previous example statement and its new translation:
PRINT A,B$;TAB(20);C%
A B$ 20 C% PrintDbl , PrintStr TAB( PrintInt PRINT
At run-time, in additional to the evaluation stack used to hold values of operands and results, there will also be a command stack (not to be confused with the current command stack used by the old translator routines, but not needed by the new translator routines).  The special print codes (specific print type codes, comma, and print functions), will only push themselves to the command stack.

When the PRINT (or semicolon) code is executed, it will process the command stack, except it will start at the bottom of the stack instead of popping items from the top.  This is possible because the QStack class is derived from the QVector class, which allows its elements to be access by index.  The values of the evaluation stack will also be accessed the same way.

When the PRINT (or semicolon) begins, it will start with indexes (one for each stack) set to zero and will process each item on the command stack.  For the specific print type code, it will access the value at the evaluation stack index, output it, and increment the index.  For a comma code, it will output the appropriate number of spaces (leaving the evaluation stack index as is).  For a print function (TAB or SPC), it will access the value at the evaluation stack index, output the appropriate number of spaces, and increment the index.

At the end (top) of the command stack, it will clear both stacks, return the indexes to zero (for the next command), and for the PRINT code only, will advance to the next line.  This scheme works because both the evaluation and command stacks will be empty at the beginning of each command.

New PRINT Implementation (Retracted)

After considering this design, it was decided to be more complicated than it needed to be, so this post has been retracted, see revised post.

The run-time design of the PRINT statement was reconsidered.  The old scheme inserted specific type print codes into the translation with an optional PRINT code at the end depending if the line ended with a semicolon, comma or print function (TAB or SPC).  Consider this example statement and its old translation:
PRINT A,B$;TAB(20);C%
A PrintDbl , B$ PrintStr 20 TAB(';' C% PrintInt PRINT
The specific type print codes pop a value from the evaluation stack and outputs it.  The comma token outputs spaces to advance the cursor to the next column (traditionally groups of 8 characters).  The TAB print function outputs spaces to advance to specified column.  And the final PRINT advances to the next line.  If the line ended with a semicolon, comma or print function, the final PRINT code is not present.  The new translation will look like this (details to follow):
A B$ 20 C% PrintDbl , PrintStr TAB( PrintInt PRINT
The final PRINT code is always present, and at run time will know when to advance to the next line (depends on the code immediately preceding it).  Semicolon tokens (or a sub-code) is not necessary and is implied between the items to print.  Multiple semicolons, though allowed in the old translator (the semicolon sub-code and any semicolon tokens would do nothing at run-time), will not be permitted as there is no reason to allow them (unlike multiple commas).

A semicolon at the end of the line needs special consideration.  If there is a semicolon at the end of the line, it will take the place of the PRINT code.  At run-time, both perform the same actions except only PRINT advances to the next line.  A semicolon can be used this way since no other statement needs a semicolon token.  A 'Keep' sub-code or a new PrintKeep code could have been used, but why have a sub-code check at run-time or create a new code when a semicolon token can be used.

The next post will contain the details of how this new PRINT translation will work at run-time...