Implemented variable deallocation

This commit is contained in:
Justin J. Meza 2010-09-02 01:37:20 -07:00
parent a2db1d932f
commit 1736db5f0f
7 changed files with 235 additions and 20 deletions

View File

@ -281,7 +281,8 @@ void deleteScopeObject(ScopeObject *scope) /**< [in,out] The ScopeObject structu
*
* \see getLocalScopeValue(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. */
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 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. */
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 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. */
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 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. */
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. */
@ -412,6 +416,61 @@ ValueObject *updateScopeValue(ScopeObject *scope, /**< [in,out] A pointer to
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.
*
* \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 interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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 interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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. */
@ -2607,7 +2668,8 @@ ReturnObject *interpretPrintStmtNode(StmtNode *node, /**< [in] A pointer to
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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. */
@ -2672,6 +2734,7 @@ ReturnObject *interpretInputStmtNode(StmtNode *node, /**< [in] A pointer to
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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 interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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 interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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. */
@ -2867,6 +2932,7 @@ ReturnObject *interpretIfThenElseStmtNode(StmtNode *node, /**< [in] A pointe
* \see interpretBreakStmtNode(StmtNode *, ScopeObject *)
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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 interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretlFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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 interpretBreakStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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 interpretBreakStmtNode(StmtNode *, ScopeObject *)
* \see interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
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);
}
/** 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.
*
* \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 interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretExprStmtNode(StmtNode *, ScopeObject *) */
ReturnObject *interpretFuncDefStmtNode(StmtNode *node, /**< 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 interpretReturnStmtNode(StmtNode *, ScopeObject *)
* \see interpretLoopStmtNode(StmtNode *, ScopeObject *)
* \see interpretDeallocationStmtNode(StmtNode *, ScopeObject *)
* \see interpretFuncDefStmtNode(StmtNode *, ScopeObject *) */
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. */
@ -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
* by its its index in the enumerated StmtType type. */
static ReturnObject *(*StmtJumpTable[12])(StmtNode *, ScopeObject *) = {
static ReturnObject *(*StmtJumpTable[13])(StmtNode *, ScopeObject *) = {
interpretCastStmtNode,
interpretPrintStmtNode,
interpretInputStmtNode,
@ -3201,6 +3306,7 @@ static ReturnObject *(*StmtJumpTable[12])(StmtNode *, ScopeObject *) = {
interpretBreakStmtNode,
interpretReturnStmtNode,
interpretLoopStmtNode,
interpretDeallocationStmtNode,
interpretFuncDefStmtNode,
interpretExprStmtNode };

View File

@ -488,6 +488,11 @@ void deleteStmtNode(StmtNode *node) /**< [in, out] A pointer to the StmtNode str
deleteLoopStmtNode(stmt);
break;
}
case ST_DEALLOCATION: {
DeallocationStmtNode *stmt = (DeallocationStmtNode *)node->stmt;
deleteDeallocationStmtNode(stmt);
break;
}
case ST_EXPR: {
ExprNode *expr = (ExprNode *)node->stmt;
deleteExprNode(expr);
@ -949,6 +954,42 @@ void deleteLoopStmtNode(LoopStmtNode *node) /**< [in,out] A pointer to the LoopS
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.
*
* \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;
}
}
/* 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 */
else if (acceptToken(&tokens, TT_HOWDUZ)) {
IdentifierNode *scope = NULL;

View File

@ -200,18 +200,19 @@ typedef struct {
/** Denotes the type of statement a StmtNode stores. */
typedef enum {
ST_CAST, /**< A CastStmtNode structure. */
ST_PRINT, /**< A PrintStmtNode structure. */
ST_INPUT, /**< An InputStmtNode structure. */
ST_ASSIGNMENT, /**< An AssignmentStmtNode structure. */
ST_DECLARATION, /**< A DeclarationStmtNode structure. */
ST_IFTHENELSE, /**< An IfThenElseStmtNode structure. */
ST_SWITCH, /**< A SwitchStmtNode structure. */
ST_BREAK, /**< A break statement (no structure is needed for this type of statement). */
ST_RETURN, /**< A ReturnStmtNode structure. */
ST_LOOP, /**< A LoopStmtNode structure. */
ST_FUNCDEF, /**< A FuncDefStmtNode structure. */
ST_EXPR /**< An ExprNode structure. */
ST_CAST, /**< A CastStmtNode structure. */
ST_PRINT, /**< A PrintStmtNode structure. */
ST_INPUT, /**< An InputStmtNode structure. */
ST_ASSIGNMENT, /**< An AssignmentStmtNode structure. */
ST_DECLARATION, /**< A DeclarationStmtNode structure. */
ST_IFTHENELSE, /**< An IfThenElseStmtNode structure. */
ST_SWITCH, /**< A SwitchStmtNode structure. */
ST_BREAK, /**< A break statement (no structure is needed for this type of statement). */
ST_RETURN, /**< A ReturnStmtNode structure. */
ST_LOOP, /**< A LoopStmtNode structure. */
ST_DEALLOCATION, /**< A DeallocationStmtNode structure. */
ST_FUNCDEF, /**< A FuncDefStmtNode structure. */
ST_EXPR /**< An ExprNode structure. */
} StmtType;
/** 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. */
} 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
* casts it to a particular type.
*
@ -571,6 +581,9 @@ void deleteReturnStmtNode(ReturnStmtNode *);
LoopStmtNode *createLoopStmtNode(IdentifierNode *, IdentifierNode *, ExprNode *, ExprNode *, BlockNode *);
void deleteLoopStmtNode(LoopStmtNode *);
DeallocationStmtNode *createDeallocationStmtNode(IdentifierNode *);
void deleteDeallocationStmtNode(DeallocationStmtNode *);
FuncDefStmtNode *createFuncDefStmtNode(IdentifierNode *, IdentifierNode *, IdentifierNodeList *, BlockNode *);
void deleteFuncDefStmtNode(FuncDefStmtNode *);

View File

@ -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

View File

@ -0,0 +1,5 @@
1
1
1
1
1

View File

@ -0,0 +1 @@
This test checks that variables can be deallocated correctly.

View File

@ -44,6 +44,7 @@ typedef enum {
TT_HASA,
TT_ITZA,
TT_ITZ,
TT_RNOOB,
TT_R,
TT_ANYR,
TT_AN,
@ -111,6 +112,7 @@ static const char *keywords[] = {
"HAS A", /* TT_HASA */
"ITZ A", /* TT_ITZA */
"ITZ", /* TT_ITZ */
"R NOOB", /* TT_RNOOB */
"R", /* TT_R */
"AN YR", /* TT_ANYR */
"AN", /* TT_AN */