int
slang_variable_copy(slang_variable * x, const slang_variable * y)
{
   slang_variable z;

   if (!slang_variable_construct(&z))
      return 0;
   if (!slang_fully_specified_type_copy(&z.type, &y->type)) {
      slang_variable_destruct(&z);
      return 0;
   }
   z.a_name = y->a_name;
   z.array_len = y->array_len;
   if (y->initializer != NULL) {
      z.initializer
         = (slang_operation *) _slang_alloc(sizeof(slang_operation));
      if (z.initializer == NULL) {
         slang_variable_destruct(&z);
         return 0;
      }
      if (!slang_operation_construct(z.initializer)) {
         _slang_free(z.initializer);
         slang_variable_destruct(&z);
         return 0;
      }
      if (!slang_operation_copy(z.initializer, y->initializer)) {
         slang_variable_destruct(&z);
         return 0;
      }
   }
   z.size = y->size;
   slang_variable_destruct(x);
   *x = z;
   return 1;
}
void slang_variable_scope_destruct (slang_variable_scope *scope)
{
	unsigned int i;

	for (i = 0; i < scope->num_variables; i++)
		slang_variable_destruct (scope->variables + i);
	slang_alloc_free (scope->variables);
	/* do not free scope->outer_scope */
}
void slang_function_destruct (slang_function *func)
{
	slang_variable_destruct (&func->header);
	slang_variable_scope_destruct (func->parameters);
	slang_alloc_free (func->parameters);
	if (func->body != NULL)
	{
		slang_operation_destruct (func->body);
		slang_alloc_free (func->body);
	}
	slang_fixup_table_free (&func->fixups);
}
int slang_function_construct (slang_function *func)
{
	func->kind = slang_func_ordinary;
	if (!slang_variable_construct (&func->header))
		return 0;
	func->parameters = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
	if (func->parameters == NULL)
	{
		slang_variable_destruct (&func->header);
		return 0;
	}
	if (!slang_variable_scope_construct (func->parameters))
	{
		slang_alloc_free (func->parameters);
		slang_variable_destruct (&func->header);
		return 0;
	}
	func->param_count = 0;
	func->body = NULL;
	func->address = ~0;
	slang_fixup_table_init (&func->fixups);
	return 1;
}
static void
slang_variable_delete(slang_variable * var)
{
   slang_variable_destruct(var);
   _slang_free(var);
}