Saturday, July 13, 2013

LET Command – Single/Multiple Assignments

The design of each command will be reconsidered with the new translator design.  Several designs for the LET command were considered, but in the end, the current design seems to the most efficient at run time with the minor exception of multiple sub-string assignments.  Excluding sub-string assignments, LET statements are translated as follows:
A = 5.0              A<ref> 5.0 Assign
A,B,C = 5.0          A<ref> B<ref> C<ref> 5.0 AssignList
For multiple assignments, all variables being assigned must be the same data type.  The data type of the value being assigned must match the variables being assigned, however, for numeric types, an appropriate hidden conversion code will be added as needed.  If the optional LET keyword was specified, the hidden LET sub-code is set in the final assignment token.

Click Continue... For details of the implementation of the LET translation.  See the commit log for other minor changes made.  Translator tests #1 through #3 (various assignment tests) now pass with the new translator routines.

[commit f965e0f649]

The get operand routine was modified with an additional reference argument to indicate that a reference is desired.  When set to obtain a reference, only token types valid for a reference (identifiers with or without parentheses and defined functions with no parentheses) are accepted.  The reference flag of the token is set. 

The LET translate routine starts by checking if there was a LET command token.  If not, the hidden flag is set, otherwise the command token is deleted and the hidden flag is reset.  The expected variable data type is set to Any and a loop is entered.  The get operand routine is called to get a reference.

After the reference, the get token routine is called to get the next token, which is checked for a comma or equal and a flag is set for whether the token is a comma or equal.  The token is set to the base Assign (double) code.  The existing find code routine is called to change this to the appropriate assign code (double, integer or string) depending on the data type of the reference.  The token is pushed to a local stack to hold it until the end of the LET translate routine.

If the reference was the first (the expected data type is any), then the expected data type is set to the data type of the reference.  Otherwise, the data type of the latest reference is checked with the expected data.  If the separating token was a comma, the loop continues with the next reference.

After the equal token, the get expression routine is called to get the expression to be assigned.  Upon success, the last token is pulled from the local stack.  If the stack is not empty after the pull, then the command is a multiple assignment and the token is changed to the associated AssignList code (double, integer or string).

The existing process final operand routine is called to check the data type of the expression and append any needed numeric conversion code along with the assign code to the RPN output list.  Finally, the terminating token from the get expression routine is checked to make sure it is a valid end-of-statement token (currently only an end-of-line token).

A new TokenStack class was created for the local stack (other command translate routines will also need a local stack).  This class is based on the QStack class with Token pointers with a reimplemented destructor to delete the tokens left remaining in the stack when the stack goes out of scope.  This is a convenience for the end of the translate routine (the LET translate routine can leave the unused tokens on the stack) or if an error is returned so the tokens do not have to be specifically deleted.

No comments:

Post a Comment

All comments and feedback welcomed, whether positive or negative.
(Anonymous comments are allowed, but comments with URL links or unrelated comments will be removed.)