private Ref Call(Function function)
        {
            try
            {
                foreach(var statement in function.Body)
                {
                    var returnValue = Execute(statement);
                    if(returnValue != null)
                        // TODO check that the reference ownership and mutablilty match the return type
                        // TODO constrain value to return type
                        // TODO constrain integer values to bits of return type
                        return returnValue;
                }

                // Reached end without return
                if(function.ReturnType.Type is VoidType)
                    return voidReference.Borrow();

                throw new InterpreterPanicException("Reached end of function without returning value");
            }
            catch(InterpreterPanicException ex)
            {
                ex.AddCallStack(function.QualifiedName());
                throw;
            }
        }