void FNSyntax_DeleteExpression(ExprNode *node)
{
	ExprNode *temp = NULL;

	for(ExprNode *i = node; i != NULL; i = i->next)
	{
		if(temp != NULL)
		{
			POV_FREE(temp);
		}

		FNSyntax_DeleteExpression(i->child);

		if((i->op == OP_VARIABLE) || (i->op == OP_MEMBER))
		{
			POV_FREE(i->variable);
		}
		else if(i->op == OP_CALL)
		{
			if((i->call.token == FUNCT_ID_TOKEN) || (i->call.token == VECTFUNCT_ID_TOKEN))
				POVFPU_RemoveFunction(i->call.fn);
			POV_FREE(i->call.name);
		}

		temp = i;
	}

	if(temp != NULL)
	{
		POV_FREE(temp);
	}
}
Example #2
0
void POVFPU_RemoveFunction(FUNCTION fn)
{
	if((POVFPU_Functions == NULL) || (fn >= POVFPU_FunctionCnt))
		return;

	if(POVFPU_Functions[fn].reference_count > 0) // necessary to prevent any recursion
	{
		POVFPU_Functions[fn].reference_count--;

		if(POVFPU_Functions[fn].reference_count == 0)
		{
			// The copying is necessary because recursive POVFPU_RemoveFunction
			// calls may shrink the POVFPU_Functions array and remove the data
			// before we are done with it here! [trf]
			FunctionEntry f = POVFPU_Functions[fn];
			unsigned int i = 0;

			SYS_DELETE_FUNCTION(&f);
			for(i = 0; i < f.fn.program_size; i++)
			{
				if(GET_OP(f.fn.program[i]) == OPCODE_CALL)
					POVFPU_RemoveFunction(GET_K(f.fn.program[i]));
			}
			FNCode_Delete(&(f.fn));

			for(i = POVFPU_FunctionCnt - 1; i > 0; i--)
			{
				if(POVFPU_Functions[i].reference_count == 0)
					POVFPU_FunctionCnt--;
				else
					break;
			}

			if(POVFPU_FunctionCnt == 0)
			{
				POV_FREE(POVFPU_Functions);
				POVFPU_Functions = NULL;
			}
			else
				POVFPU_Functions = (FunctionEntry *)POV_REALLOC(POVFPU_Functions, sizeof(FunctionEntry) * POVFPU_FunctionCnt, "fn: FunctionEntry");
		}
	}
}