Implemented variable deallocation
This commit is contained in:
parent
a2db1d932f
commit
1736db5f0f
122
interpreter.c
122
interpreter.c
|
@ -281,7 +281,8 @@ void deleteScopeObject(ScopeObject *scope) /**< [in,out] The ScopeObject structu
|
||||||
*
|
*
|
||||||
* \see getLocalScopeValue(ScopeObject *, IdentifierNode *)
|
* \see getLocalScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see createScopeValue(ScopeObject *, IdentifierNode *)
|
* \see createScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *) */
|
* \see updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *)
|
||||||
|
* \see deleteScopeValue(ScopeObject *, IdentifierNode *) */
|
||||||
ValueObject *getScopeValue(ScopeObject *scope, /**< [in] The ScopeObject structure to check. */
|
ValueObject *getScopeValue(ScopeObject *scope, /**< [in] The ScopeObject structure to check. */
|
||||||
IdentifierNode *target) /**< [in] The name of the value to find. */
|
IdentifierNode *target) /**< [in] The name of the value to find. */
|
||||||
{
|
{
|
||||||
|
@ -312,7 +313,8 @@ ValueObject *getScopeValue(ScopeObject *scope, /**< [in] The ScopeObject str
|
||||||
*
|
*
|
||||||
* \see getScopeValue(ScopeObject *, IdentifierNode *)
|
* \see getScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see createScopeValue(ScopeObject *, IdentifierNode *)
|
* \see createScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *) */
|
* \see updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *)
|
||||||
|
* \see deleteScopeValue(ScopeObject *, IdentifierNode *) */
|
||||||
ValueObject *getLocalScopeValue(ScopeObject *scope, /**< [in] The ScopeObject structure to check. */
|
ValueObject *getLocalScopeValue(ScopeObject *scope, /**< [in] The ScopeObject structure to check. */
|
||||||
IdentifierNode *target) /**< [in] The name of the value to find. */
|
IdentifierNode *target) /**< [in] The name of the value to find. */
|
||||||
{
|
{
|
||||||
|
@ -339,7 +341,8 @@ ValueObject *getLocalScopeValue(ScopeObject *scope, /**< [in] The ScopeObjec
|
||||||
*
|
*
|
||||||
* \see getScopeValue(ScopeObject *, IdentifierNode *)
|
* \see getScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see getLocalScopeValue(ScopeObject *, IdentifierNode *)
|
* \see getLocalScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *) */
|
* \see updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *)
|
||||||
|
* \see deleteScopeValue(ScopeObject *, IdentifierNode *) */
|
||||||
ValueObject *createScopeValue(ScopeObject *scope, /**< [in,out] The ScopeObject structure to add a value to. */
|
ValueObject *createScopeValue(ScopeObject *scope, /**< [in,out] The ScopeObject structure to add a value to. */
|
||||||
IdentifierNode *target) /**< [in] The name of the value to add. */
|
IdentifierNode *target) /**< [in] The name of the value to add. */
|
||||||
{
|
{
|
||||||
|
@ -385,7 +388,8 @@ ValueObject *createScopeValue(ScopeObject *scope, /**< [in,out] The ScopeObj
|
||||||
*
|
*
|
||||||
* \see getScopeValue(ScopeObject *, IdentifierNode *)
|
* \see getScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see getLocalScopeValue(ScopeObject *, IdentifierNode *)
|
* \see getLocalScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
* \see createScopeValue(ScopeObject *, IdentifierNode *) */
|
* \see createScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
|
* \see deleteScopeValue(ScopeObject *, IdentifierNode *) */
|
||||||
ValueObject *updateScopeValue(ScopeObject *scope, /**< [in,out] A pointer to the ScopeObject structure to update. */
|
ValueObject *updateScopeValue(ScopeObject *scope, /**< [in,out] A pointer to the ScopeObject structure to update. */
|
||||||
IdentifierNode *target, /**< [in] A pointer to the IdentifierNode structure containing the name of the value to update. */
|
IdentifierNode *target, /**< [in] A pointer to the IdentifierNode structure containing the name of the value to update. */
|
||||||
ValueObject *value) /**< [in] A pointer to the ValueObject structure containing the value to copy for the update. */
|
ValueObject *value) /**< [in] A pointer to the ValueObject structure containing the value to copy for the update. */
|
||||||
|
@ -412,6 +416,61 @@ ValueObject *updateScopeValue(ScopeObject *scope, /**< [in,out] A pointer to
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Deletes a ValueObject structure named by an IdentifierNode structure in a
|
||||||
|
* ScopeObject structure.
|
||||||
|
*
|
||||||
|
* \pre \a scope was created by createScopeObject(ScopeObject *) and contains
|
||||||
|
* contents added by createScopeValue(ScopeObject *, IdentifierNode *) and
|
||||||
|
* contents updated by updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *).
|
||||||
|
* \pre \a target was created by createIdentifierNode(char *).
|
||||||
|
*
|
||||||
|
* \see getScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
|
* \see getLocalScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
|
* \see createScopeValue(ScopeObject *, IdentifierNode *)
|
||||||
|
* \see updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *) */
|
||||||
|
void deleteScopeValue(ScopeObject *scope, /**< [in,out] A pointer to the ScopeObject structure to delete from. */
|
||||||
|
IdentifierNode *target) /**< [in] A pointer to the IdentifierNode structure containing the name of the value to delete. */
|
||||||
|
{
|
||||||
|
ScopeObject *current = scope;
|
||||||
|
/* Traverse upwards through scopes */
|
||||||
|
do {
|
||||||
|
unsigned int n;
|
||||||
|
/* Check for existing value in current scope */
|
||||||
|
for (n = 0; n < current->numvals; n++) {
|
||||||
|
if (!strcmp(current->names[n]->image, target->image)) {
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int newnumvals = scope->numvals - 1;
|
||||||
|
void *mem1 = NULL, *mem2 = NULL;
|
||||||
|
/* Don't delete anything in the names table
|
||||||
|
* because it's just pointers to IdentifierNode
|
||||||
|
* structures in the parse tree. */
|
||||||
|
/* Wipe out the value */
|
||||||
|
deleteValueObject(current->values[n]);
|
||||||
|
/* Reorder the tables */
|
||||||
|
for (i = n; i < current->numvals - 1; i++) {
|
||||||
|
current->names[i] = current->names[i + 1];
|
||||||
|
current->values[i] = current->values[i + 1];
|
||||||
|
}
|
||||||
|
/* Resize the tables */
|
||||||
|
mem1 = realloc(scope->names, sizeof(IdentifierNode *) * newnumvals);
|
||||||
|
if (!mem1) {
|
||||||
|
perror("realloc");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mem2 = realloc(scope->values, sizeof(ValueObject *) * newnumvals);
|
||||||
|
if (!mem2) {
|
||||||
|
perror("realloc");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scope->names = mem1;
|
||||||
|
scope->values = mem2;
|
||||||
|
scope->numvals = newnumvals;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ((current = current->parent));
|
||||||
|
}
|
||||||
|
|
||||||
/** Checks if a string of characters follows the format for a number.
|
/** Checks if a string of characters follows the format for a number.
|
||||||
*
|
*
|
||||||
* \retval 0 The string of characters is not a number.
|
* \retval 0 The string of characters is not a number.
|
||||||
|
@ -2504,6 +2563,7 @@ ValueObject *interpretExprNode(ExprNode *node, /**< [in] A pointer to an Exp
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretCastStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the CastStmtNode structure to interpret. */
|
ReturnObject *interpretCastStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the CastStmtNode structure to interpret. */
|
||||||
|
@ -2562,7 +2622,8 @@ ReturnObject *interpretCastStmtNode(StmtNode *node, /**< [in] A pointer to t
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretPrintStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the PrintStmtNode structure to interpret. */
|
ReturnObject *interpretPrintStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the PrintStmtNode structure to interpret. */
|
||||||
ScopeObject *scope) /**< [in] A pointer to the ScopeObject structure to evaluate \a node under. */
|
ScopeObject *scope) /**< [in] A pointer to the ScopeObject structure to evaluate \a node under. */
|
||||||
|
@ -2607,7 +2668,8 @@ ReturnObject *interpretPrintStmtNode(StmtNode *node, /**< [in] A pointer to
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretInputStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing an InputStmtNode structure to interpret. */
|
ReturnObject *interpretInputStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing an InputStmtNode structure to interpret. */
|
||||||
ScopeObject *scope) /**< [in,out] A pointer to the ScopeObject structure to evaluate \a node under. */
|
ScopeObject *scope) /**< [in,out] A pointer to the ScopeObject structure to evaluate \a node under. */
|
||||||
|
@ -2672,6 +2734,7 @@ ReturnObject *interpretInputStmtNode(StmtNode *node, /**< [in] A pointer to
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretAssignmentStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the AssignmentStmtNode structure to interpret. */
|
ReturnObject *interpretAssignmentStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the AssignmentStmtNode structure to interpret. */
|
||||||
|
@ -2708,6 +2771,7 @@ ReturnObject *interpretAssignmentStmtNode(StmtNode *node, /**< [in] A pointe
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretDeclarationStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the DeclarationStmtNode structure to interpret. */
|
ReturnObject *interpretDeclarationStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the DeclarationStmtNode structure to interpret. */
|
||||||
|
@ -2776,7 +2840,8 @@ ReturnObject *interpretDeclarationStmtNode(StmtNode *node, /**< [in] A point
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretIfThenElseStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the IfThenElseStmtNode structure to interpret. */
|
ReturnObject *interpretIfThenElseStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the IfThenElseStmtNode structure to interpret. */
|
||||||
ScopeObject *scope) /**< [in,out] A pointer to the ScopeObject structure to evaluate \a node under. */
|
ScopeObject *scope) /**< [in,out] A pointer to the ScopeObject structure to evaluate \a node under. */
|
||||||
|
@ -2867,6 +2932,7 @@ ReturnObject *interpretIfThenElseStmtNode(StmtNode *node, /**< [in] A pointe
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretSwitchStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the SwitchStmtNode structure to interpret. */
|
ReturnObject *interpretSwitchStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the SwitchStmtNode structure to interpret. */
|
||||||
|
@ -2965,6 +3031,7 @@ ReturnObject *interpretSwitchStmtNode(StmtNode *node, /**< [in] A pointer to
|
||||||
* \see interpretSwitchStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretSwitchStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretBreakStmtNode(StmtNode *node, /**< Not used (see note). */
|
ReturnObject *interpretBreakStmtNode(StmtNode *node, /**< Not used (see note). */
|
||||||
|
@ -2997,6 +3064,7 @@ ReturnObject *interpretBreakStmtNode(StmtNode *node, /**< Not used (see note
|
||||||
* \see interpretSwitchStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretSwitchStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretReturnStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the ReturnStmtNode structure to interpret. */
|
ReturnObject *interpretReturnStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the ReturnStmtNode structure to interpret. */
|
||||||
|
@ -3031,6 +3099,7 @@ ReturnObject *interpretReturnStmtNode(StmtNode *node, /**< [in] A pointer to
|
||||||
* \see interpretSwitchStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretSwitchStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretLoopStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the LoopStmtNode structure to interpret. */
|
ReturnObject *interpretLoopStmtNode(StmtNode *node, /**< [in] A pointer to the StmtNode structure containing the LoopStmtNode structure to interpret. */
|
||||||
|
@ -3118,6 +3187,40 @@ ReturnObject *interpretLoopStmtNode(StmtNode *node, /**< [in] A pointer to t
|
||||||
return createReturnObject(RT_DEFAULT, NULL);
|
return createReturnObject(RT_DEFAULT, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Interprets a deallocation statement.
|
||||||
|
*
|
||||||
|
* \pre \a node was created by createStmtNode(StmtType type, void *stmt) where
|
||||||
|
* \a type is ST_DEALLOCATION and \a stmt was created by createDeallocationStmtNode(IdentifierNode *).
|
||||||
|
* \pre \a scope was created by createScopeObject(ScopeObject *) and contains
|
||||||
|
* contents added by createScopeValue(ScopeObject *, IdentifierNode *) and
|
||||||
|
* contents updated by updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *).
|
||||||
|
*
|
||||||
|
* \return A pointer to a ReturnObject structure with the default return value.
|
||||||
|
*
|
||||||
|
* \retval NULL An error occurred during interpretation.
|
||||||
|
*
|
||||||
|
* \see interpretCastStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretPrintStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretInputStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeclarationStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretIfThenElseStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretSwitchStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
|
ReturnObject *interpretDeallocationStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the DeallocationStmtNode structure to interpret. */
|
||||||
|
ScopeObject *scope) /**< [in,out] A pointer to the ScopeObject structure to evaluate \a node under. */
|
||||||
|
{
|
||||||
|
DeallocationStmtNode *stmt = (DeallocationStmtNode *)node->stmt;
|
||||||
|
if (!updateScopeValue(scope, stmt->target, NULL)) return NULL;
|
||||||
|
/* If we want to completely remove the variable, use:
|
||||||
|
deleteScopeValue(scope, stmt->target);
|
||||||
|
*/
|
||||||
|
return createReturnObject(RT_DEFAULT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/** Interprets a function definition statement.
|
/** Interprets a function definition statement.
|
||||||
*
|
*
|
||||||
* \pre \a node was created by createStmtNode(StmtType type, void *stmt) where
|
* \pre \a node was created by createStmtNode(StmtType type, void *stmt) where
|
||||||
|
@ -3144,6 +3247,7 @@ ReturnObject *interpretLoopStmtNode(StmtNode *node, /**< [in] A pointer to t
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretFuncDefStmtNode(StmtNode *node, /**< Not used (see note). */
|
ReturnObject *interpretFuncDefStmtNode(StmtNode *node, /**< Not used (see note). */
|
||||||
ScopeObject *scope) /**< Not used (see note). */
|
ScopeObject *scope) /**< Not used (see note). */
|
||||||
|
@ -3176,6 +3280,7 @@ ReturnObject *interpretFuncDefStmtNode(StmtNode *node, /**< Not used (see no
|
||||||
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
|
||||||
|
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
|
||||||
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *) */
|
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *) */
|
||||||
ReturnObject *interpretExprStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the ExprNode structure to interpret. */
|
ReturnObject *interpretExprStmtNode(StmtNode *node, /**< [in] A pointer to a StmtNode structure containing the ExprNode structure to interpret. */
|
||||||
ScopeObject *scope) /**< [in,out] A pointer to the ScopeObject structure to evaluate \a node under. */
|
ScopeObject *scope) /**< [in,out] A pointer to the ScopeObject structure to evaluate \a node under. */
|
||||||
|
@ -3190,7 +3295,7 @@ ReturnObject *interpretExprStmtNode(StmtNode *node, /**< [in] A pointer to a
|
||||||
|
|
||||||
/* A jump table for statements. The index of a function in the table is given
|
/* A jump table for statements. The index of a function in the table is given
|
||||||
* by its its index in the enumerated StmtType type. */
|
* by its its index in the enumerated StmtType type. */
|
||||||
static ReturnObject *(*StmtJumpTable[12])(StmtNode *, ScopeObject *) = {
|
static ReturnObject *(*StmtJumpTable[13])(StmtNode *, ScopeObject *) = {
|
||||||
interpretCastStmtNode,
|
interpretCastStmtNode,
|
||||||
interpretPrintStmtNode,
|
interpretPrintStmtNode,
|
||||||
interpretInputStmtNode,
|
interpretInputStmtNode,
|
||||||
|
@ -3201,6 +3306,7 @@ static ReturnObject *(*StmtJumpTable[12])(StmtNode *, ScopeObject *) = {
|
||||||
interpretBreakStmtNode,
|
interpretBreakStmtNode,
|
||||||
interpretReturnStmtNode,
|
interpretReturnStmtNode,
|
||||||
interpretLoopStmtNode,
|
interpretLoopStmtNode,
|
||||||
|
interpretDeallocationStmtNode,
|
||||||
interpretFuncDefStmtNode,
|
interpretFuncDefStmtNode,
|
||||||
interpretExprStmtNode };
|
interpretExprStmtNode };
|
||||||
|
|
||||||
|
|
71
parser.c
71
parser.c
|
@ -488,6 +488,11 @@ void deleteStmtNode(StmtNode *node) /**< [in, out] A pointer to the StmtNode str
|
||||||
deleteLoopStmtNode(stmt);
|
deleteLoopStmtNode(stmt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ST_DEALLOCATION: {
|
||||||
|
DeallocationStmtNode *stmt = (DeallocationStmtNode *)node->stmt;
|
||||||
|
deleteDeallocationStmtNode(stmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ST_EXPR: {
|
case ST_EXPR: {
|
||||||
ExprNode *expr = (ExprNode *)node->stmt;
|
ExprNode *expr = (ExprNode *)node->stmt;
|
||||||
deleteExprNode(expr);
|
deleteExprNode(expr);
|
||||||
|
@ -949,6 +954,42 @@ void deleteLoopStmtNode(LoopStmtNode *node) /**< [in,out] A pointer to the LoopS
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Creates a DeallocationStmtNode structure.
|
||||||
|
*
|
||||||
|
* \pre \a target was created by createIdentifierNode(char *).
|
||||||
|
*
|
||||||
|
* \return A pointer to a DeallocationStmtNode structure with the desired
|
||||||
|
* properties.
|
||||||
|
*
|
||||||
|
* \retval NULL malloc was unable to allocate memory.
|
||||||
|
*
|
||||||
|
* \see deleteDeallocationStmtNode(DeallocationStmtNode *) */
|
||||||
|
DeallocationStmtNode *createDeallocationStmtNode(IdentifierNode *target) /**< [in] A pointer to the name of the variable. */
|
||||||
|
{
|
||||||
|
DeallocationStmtNode *p = malloc(sizeof(DeallocationStmtNode));
|
||||||
|
if (!p) {
|
||||||
|
perror("malloc");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
p->target = target;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Deletes a DeallocationStmtNode structure.
|
||||||
|
*
|
||||||
|
* \pre \a node was created by createDeallocationStmtNode(IdentifierNode *).
|
||||||
|
*
|
||||||
|
* \post The memory at \a node and any of its associated members will be
|
||||||
|
* freed.
|
||||||
|
*
|
||||||
|
* \see createDeallocationStmtNode(IdentifierNode *) */
|
||||||
|
void deleteDeallocationStmtNode(DeallocationStmtNode *node) /**< [in,out] A pointer to the DeallocationStmtNode structure to be deleted. */
|
||||||
|
{
|
||||||
|
if (!node) return;
|
||||||
|
deleteIdentifierNode(node->target);
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates a FuncDefStmtNode structure.
|
/** Creates a FuncDefStmtNode structure.
|
||||||
*
|
*
|
||||||
* \pre \a scope was created by createIdentifierNode(char *).
|
* \pre \a scope was created by createIdentifierNode(char *).
|
||||||
|
@ -2806,6 +2847,36 @@ StmtNode *parseStmtNode(Token ***tokenp, /**< [in,out] A pointer to the p
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Deallocation */
|
||||||
|
else if (nextToken(&tokens, TT_RNOOB)) {
|
||||||
|
IdentifierNode *target = NULL;
|
||||||
|
DeallocationStmtNode *stmt = NULL;
|
||||||
|
#ifdef DEBUG
|
||||||
|
debug("ST_DEALLOCATION");
|
||||||
|
#endif
|
||||||
|
target = parseIdentifierNode(&tokens);
|
||||||
|
if (!target) return NULL;
|
||||||
|
if (!acceptToken(&tokens, TT_RNOOB)) {
|
||||||
|
error("expected R NOOB", tokens);
|
||||||
|
deleteIdentifierNode(target);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!acceptToken(&tokens, TT_NEWLINE)) {
|
||||||
|
error("expected end of statement", tokens);
|
||||||
|
deleteIdentifierNode(target);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
stmt = createDeallocationStmtNode(target);
|
||||||
|
if (!stmt) {
|
||||||
|
deleteIdentifierNode(target);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = createStmtNode(ST_DEALLOCATION, stmt);
|
||||||
|
if (!ret) {
|
||||||
|
deleteDeallocationStmtNode(stmt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Function definition */
|
/* Function definition */
|
||||||
else if (acceptToken(&tokens, TT_HOWDUZ)) {
|
else if (acceptToken(&tokens, TT_HOWDUZ)) {
|
||||||
IdentifierNode *scope = NULL;
|
IdentifierNode *scope = NULL;
|
||||||
|
|
37
parser.h
37
parser.h
|
@ -200,18 +200,19 @@ typedef struct {
|
||||||
|
|
||||||
/** Denotes the type of statement a StmtNode stores. */
|
/** Denotes the type of statement a StmtNode stores. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ST_CAST, /**< A CastStmtNode structure. */
|
ST_CAST, /**< A CastStmtNode structure. */
|
||||||
ST_PRINT, /**< A PrintStmtNode structure. */
|
ST_PRINT, /**< A PrintStmtNode structure. */
|
||||||
ST_INPUT, /**< An InputStmtNode structure. */
|
ST_INPUT, /**< An InputStmtNode structure. */
|
||||||
ST_ASSIGNMENT, /**< An AssignmentStmtNode structure. */
|
ST_ASSIGNMENT, /**< An AssignmentStmtNode structure. */
|
||||||
ST_DECLARATION, /**< A DeclarationStmtNode structure. */
|
ST_DECLARATION, /**< A DeclarationStmtNode structure. */
|
||||||
ST_IFTHENELSE, /**< An IfThenElseStmtNode structure. */
|
ST_IFTHENELSE, /**< An IfThenElseStmtNode structure. */
|
||||||
ST_SWITCH, /**< A SwitchStmtNode structure. */
|
ST_SWITCH, /**< A SwitchStmtNode structure. */
|
||||||
ST_BREAK, /**< A break statement (no structure is needed for this type of statement). */
|
ST_BREAK, /**< A break statement (no structure is needed for this type of statement). */
|
||||||
ST_RETURN, /**< A ReturnStmtNode structure. */
|
ST_RETURN, /**< A ReturnStmtNode structure. */
|
||||||
ST_LOOP, /**< A LoopStmtNode structure. */
|
ST_LOOP, /**< A LoopStmtNode structure. */
|
||||||
ST_FUNCDEF, /**< A FuncDefStmtNode structure. */
|
ST_DEALLOCATION, /**< A DeallocationStmtNode structure. */
|
||||||
ST_EXPR /**< An ExprNode structure. */
|
ST_FUNCDEF, /**< A FuncDefStmtNode structure. */
|
||||||
|
ST_EXPR /**< An ExprNode structure. */
|
||||||
} StmtType;
|
} StmtType;
|
||||||
|
|
||||||
/** Stores a statement. A statement is a unit of code which can be executed by
|
/** Stores a statement. A statement is a unit of code which can be executed by
|
||||||
|
@ -466,6 +467,15 @@ typedef struct {
|
||||||
BlockNode *body; /**< A pointer to the block of code to be executed with each iteration of the loop. */
|
BlockNode *body; /**< A pointer to the block of code to be executed with each iteration of the loop. */
|
||||||
} LoopStmtNode;
|
} LoopStmtNode;
|
||||||
|
|
||||||
|
/** Deallocates a variable. This means freeing the memory and structures used
|
||||||
|
* by the variable.
|
||||||
|
*
|
||||||
|
* \see createDeallocationStmtNode(IdentifierNode *)
|
||||||
|
* \see deleteDeallocationStmtNode(DeallocationStmtNode *) */
|
||||||
|
typedef struct {
|
||||||
|
IdentifierNode *target; /**< A pointer to the name of the variable. */
|
||||||
|
} DeallocationStmtNode;
|
||||||
|
|
||||||
/** Stores a cast expression. A cast expression evaluates an expression and
|
/** Stores a cast expression. A cast expression evaluates an expression and
|
||||||
* casts it to a particular type.
|
* casts it to a particular type.
|
||||||
*
|
*
|
||||||
|
@ -571,6 +581,9 @@ void deleteReturnStmtNode(ReturnStmtNode *);
|
||||||
LoopStmtNode *createLoopStmtNode(IdentifierNode *, IdentifierNode *, ExprNode *, ExprNode *, BlockNode *);
|
LoopStmtNode *createLoopStmtNode(IdentifierNode *, IdentifierNode *, ExprNode *, ExprNode *, BlockNode *);
|
||||||
void deleteLoopStmtNode(LoopStmtNode *);
|
void deleteLoopStmtNode(LoopStmtNode *);
|
||||||
|
|
||||||
|
DeallocationStmtNode *createDeallocationStmtNode(IdentifierNode *);
|
||||||
|
void deleteDeallocationStmtNode(DeallocationStmtNode *);
|
||||||
|
|
||||||
FuncDefStmtNode *createFuncDefStmtNode(IdentifierNode *, IdentifierNode *, IdentifierNodeList *, BlockNode *);
|
FuncDefStmtNode *createFuncDefStmtNode(IdentifierNode *, IdentifierNode *, IdentifierNodeList *, BlockNode *);
|
||||||
void deleteFuncDefStmtNode(FuncDefStmtNode *);
|
void deleteFuncDefStmtNode(FuncDefStmtNode *);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
HAI 1.3
|
||||||
|
I HAS A var1
|
||||||
|
I HAS A var2 ITZ WIN
|
||||||
|
I HAS A var3 ITZ 1
|
||||||
|
I HAS A var4 ITZ 2.345
|
||||||
|
I HAS A var5 ITZ "Lorem ipsum dolor sit."
|
||||||
|
var1 R NOOB
|
||||||
|
var2 R NOOB
|
||||||
|
var3 R NOOB
|
||||||
|
var4 R NOOB
|
||||||
|
var5 R NOOB
|
||||||
|
VISIBLE SUM OF 0 AN NOT var1
|
||||||
|
VISIBLE SUM OF 0 AN NOT var2
|
||||||
|
VISIBLE SUM OF 0 AN NOT var3
|
||||||
|
VISIBLE SUM OF 0 AN NOT var4
|
||||||
|
VISIBLE SUM OF 0 AN NOT var5
|
||||||
|
KTHXBYE
|
|
@ -0,0 +1,5 @@
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
|
@ -0,0 +1 @@
|
||||||
|
This test checks that variables can be deallocated correctly.
|
|
@ -44,6 +44,7 @@ typedef enum {
|
||||||
TT_HASA,
|
TT_HASA,
|
||||||
TT_ITZA,
|
TT_ITZA,
|
||||||
TT_ITZ,
|
TT_ITZ,
|
||||||
|
TT_RNOOB,
|
||||||
TT_R,
|
TT_R,
|
||||||
TT_ANYR,
|
TT_ANYR,
|
||||||
TT_AN,
|
TT_AN,
|
||||||
|
@ -111,6 +112,7 @@ static const char *keywords[] = {
|
||||||
"HAS A", /* TT_HASA */
|
"HAS A", /* TT_HASA */
|
||||||
"ITZ A", /* TT_ITZA */
|
"ITZ A", /* TT_ITZA */
|
||||||
"ITZ", /* TT_ITZ */
|
"ITZ", /* TT_ITZ */
|
||||||
|
"R NOOB", /* TT_RNOOB */
|
||||||
"R", /* TT_R */
|
"R", /* TT_R */
|
||||||
"AN YR", /* TT_ANYR */
|
"AN YR", /* TT_ANYR */
|
||||||
"AN", /* TT_AN */
|
"AN", /* TT_AN */
|
||||||
|
|
Loading…
Reference in New Issue