Monday, May 31, 2010

Translator – PRINT Command (Translating)

Currently, command tokens are pushed onto the command stack, so will a PRINT command token when it is received. The PRINT's next token mode value will be set to Expression. The Semicolon, Comma and End-of-statement will trigger the insertion of the value specific print code.

The existing find code function can be used to determine which specific print value code to append to the output. The PrintDbl code will serve as the main code, which will have PrintInt, PrintStr and PrintTmpStr as associated codes, each with one operand of the appropriate data type. A new token will be created with the PrintDbl code and passed to the find code function, which will return the correct code for the expression. The token is then be appended to the output.

At the end of the statement, the PRINT command token will be on top of the command stack. The end of statement processing needs to pop this token off from the stack and perform whatever handling is necessary. There needs to be a command handler that performs a command's specific needs. For reasons that will be clear later, the token handler function cannot be used for this purpose, so a new command handler function pointer is required in the table entries.

The PRINT command handler needs to determine when the PRINT token should be appended to the output (to go to a new line), or not (stay on the same line). If the done stack is not empty, then there is an unprocessed expression that needs a specific print value code. This means there was no semicolon or comma at the end of the statement, so the PRINT token can be appended. However, an empty done stack does not indicate no PRINT token is needed, consider the PRINT command by itself.

Therefore, a flag is needed, to be set when an print-only internal function, semicolon or comma is processed. If the done stack was empty, the command handler will check if this flag is set, to determine not to append the PRINT command token (in which case the PRINT token is deleted). This flag will be added to the command stack's item structure item, which is cleared when the command is initially pushed onto the stack.

Translator – PRINT Command (Translation)

The translated statement PRINT will consist of a number of different printing codes, which include PrintDbl, PrintInt, PrintStr, PrintTmpStr, Comma, Semicolon, and Print. The print only Spc and Tab internal function codes will also print. Before explaining further, here are some examples with their translations:
PRINT  Print
PRINT A;B%  A PrintDbl B PrintInt Print
PRINT A$+B$,C$;  A$ B$ + PrintTmpStr Comma C$ PrintStr
PRINT TAB(A+1);"Hello"  A 1 + Tab "Hello" PrintStr Print
PRINT "Start";SPC(10)  "Start" PrintStr 10 Spc
PRINT ,,A  Comma Comma A PrintDbl Print
PRINT ;  Semicolon
Note that when the cursor is to go to a new line, there is a Print code at the end of the translation, otherwise it is absent. The Print code at run-time preforms the new line action, so in it's absence, the cursor remains on the same line. The PrintDbl, PrintInt, PrintStr and PrintTmpStr will output the value that is on top of the evaluation stack, with PrintTmpStr deleting the temporary string when done.

At run-time, the Comma code will advance the cursor to the next column by outputting spaces. The Tab and Spc codes perform there action by outputting spaces. The Semicolon code does not perform any action during run-time, it is there only so that it can't reproduced during recreation of the source. Next, how the PRINT statement will be translated...

Translator – PRINT Command

It is necessary to look at how PRINT statements will be executed to determine how they need to be encoded and thus translated. But first, here is the general syntax of the PRINT statement:
PRINT [<expression>][;|, [<expression>]...]
Zero or more expressions may be included. The expressions can result with a double, integer or string value. Numbers are output with a trailing space. The expression may be one of print only functions SPC and TAB, both taking an integer expression. After the expressions are output, the PRINT will move to a new line unless the line ends with a semicolon, comma, SPC or TAB. (More options will be added later like PRINT USING and PRINT to a file.)

The SPC function outputs the number of spaces of the integer expression (less than 1 outputs no spaces). The TAB function advances the cursor to the column of the integer expression, where the first column is defined as column 1 (less than 1 is taken as column 1). If the cursor is already beyond the column specified, then PRINT goes to the next line, and then to the specified column. Using TAB(1) in the middle of a PRINT statement has the effect of doing a new line (an '\n' in C).

A semicolon is used to separate expressions, but does not affect what is output. The syntax above implies multiple semicolons may be entered. This is allowed, but will cause dummy semicolon tokens to be inserted into the code. A comma advances to the next column. A column will initially be defined as one-fifth of the screen width (at 80 columns, this is 5 columns of 16 characters). Eventually there will be a way for this width to be defined to any value.