1.1 --- a/templates/ops.c Sun Feb 12 23:24:42 2017 +0100
1.2 +++ b/templates/ops.c Mon Feb 13 15:35:36 2017 +0100
1.3 @@ -25,10 +25,19 @@
1.4
1.5 /* Direct access and manipulation of static objects. */
1.6
1.7 -__attr __load_static(__ref parent, __ref obj)
1.8 +__attr __load_static_ignore(__ref obj)
1.9 +{
1.10 + return (__attr) {.value=obj};
1.11 +}
1.12 +
1.13 +__attr __load_static_replace(__ref context, __ref obj)
1.14 {
1.15 - __attr out = {.context=parent, .value=obj};
1.16 - return out;
1.17 + return __update_context(context, (__attr) {.value=obj});
1.18 +}
1.19 +
1.20 +__attr __load_static_test(__ref context, __ref obj)
1.21 +{
1.22 + return __test_context(context, (__attr) {.value=obj});
1.23 }
1.24
1.25 /* Direct retrieval operations, returning and setting attributes. */
1.26 @@ -192,9 +201,11 @@
1.27
1.28 __attr __test_context(__ref context, __attr attr)
1.29 {
1.30 + __ref attrcontext = __CONTEXT_AS_VALUE(attr).value;
1.31 +
1.32 /* Preserve any existing null or instance context. */
1.33
1.34 - if ((attr.context == 0) || __is_instance(attr.context))
1.35 + if ((attrcontext == 0) || __is_instance(attrcontext))
1.36 return attr;
1.37
1.38 /* Test any instance context against the context employed by the
1.39 @@ -202,7 +213,7 @@
1.40
1.41 if (__is_instance(context))
1.42 {
1.43 - if (__test_common_instance(context, __TYPEPOS(attr.context), __TYPECODE(attr.context)))
1.44 + if (__test_common_instance(context, __TYPEPOS(attrcontext), __TYPECODE(attrcontext)))
1.45 return __update_context(context, attr);
1.46 else
1.47 __raise_type_error();
1.48 @@ -210,7 +221,7 @@
1.49
1.50 /* Test for access to a type class attribute using a type instance. */
1.51
1.52 - if (__test_specific_type(attr.context, &__TYPE_CLASS_TYPE) && __is_type_instance(context))
1.53 + if (__test_specific_type(attrcontext, &__TYPE_CLASS_TYPE) && __is_type_instance(context))
1.54 return __update_context(context, attr);
1.55
1.56 /* Otherwise, preserve the attribute as retrieved. */
1.57 @@ -220,47 +231,55 @@
1.58
1.59 __attr __update_context(__ref context, __attr attr)
1.60 {
1.61 - __attr out = {.context=context, .value=attr.value};
1.62 - return out;
1.63 + return __new_wrapper(context, attr);
1.64 }
1.65
1.66 /* Context testing for invocations. */
1.67
1.68 -int __type_method_invocation(__attr attr)
1.69 +int __type_method_invocation(__ref context, __attr target)
1.70 {
1.71 - __attr parent;
1.72 + __ref targetcontext = __CONTEXT_AS_VALUE(target).value;
1.73
1.74 /* Require instances, not classes, where methods are function instances. */
1.75
1.76 - if (!__is_instance(attr.value))
1.77 + if (!__is_instance(target.value))
1.78 return 0;
1.79
1.80 - /* Access the parent of the callable and test if it is the type object. */
1.81 + /* Access the context of the callable and test if it is the type object. */
1.82
1.83 - parent = __check_and_load_via_object_null(attr.value, __ATTRPOS(__parent__), __ATTRCODE(__parent__));
1.84 - return ((parent.value != 0) && __test_specific_type(parent.value, &__TYPE_CLASS_TYPE) && __is_type_instance(attr.context));
1.85 + return ((targetcontext != 0) && __test_specific_type(targetcontext, &__TYPE_CLASS_TYPE) && __is_type_instance(context));
1.86 }
1.87
1.88 -__attr (*__get_function(__attr attr))(__attr[])
1.89 +__attr __unwrap_callable(__attr callable)
1.90 {
1.91 + __attr value = __check_and_load_via_object_null(callable.value, __ATTRPOS(__value__), __ATTRCODE(__value__));
1.92 + return value.value ? value : callable;
1.93 +}
1.94 +
1.95 +__attr (*__get_function(__ref context, __attr target))(__attr[])
1.96 +{
1.97 + target = __unwrap_callable(target);
1.98 +
1.99 /* Require null or instance contexts for functions and methods respectively,
1.100 or type instance contexts for type methods. */
1.101
1.102 - if ((attr.context == 0) || __is_instance(attr.context) || __type_method_invocation(attr))
1.103 - return __load_via_object(attr.value, __ATTRPOS(__fn__)).fn;
1.104 + if ((context == 0) || __is_instance(context) || __type_method_invocation(context, target))
1.105 + return __load_via_object(target.value, __ATTRPOS(__fn__)).fn;
1.106 else
1.107 - return __load_via_object(attr.value, __ATTRPOS(__fn__)).inv;
1.108 + return __unbound_method;
1.109 }
1.110
1.111 -__attr (*__check_and_get_function(__attr attr))(__attr[])
1.112 +__attr (*__check_and_get_function(__ref context, __attr target))(__attr[])
1.113 {
1.114 + target = __unwrap_callable(target);
1.115 +
1.116 /* Require null or instance contexts for functions and methods respectively,
1.117 or type instance contexts for type methods. */
1.118
1.119 - if ((attr.context == 0) || __is_instance(attr.context) || __type_method_invocation(attr))
1.120 - return __check_and_load_via_object(attr.value, __ATTRPOS(__fn__), __ATTRCODE(__fn__)).fn;
1.121 + if ((context == 0) || __is_instance(context) || __type_method_invocation(context, target))
1.122 + return __check_and_load_via_object(target.value, __ATTRPOS(__fn__), __ATTRCODE(__fn__)).fn;
1.123 else
1.124 - return __check_and_load_via_object(attr.value, __ATTRPOS(__fn__), __ATTRCODE(__fn__)).inv;
1.125 + return __unbound_method;
1.126 }
1.127
1.128 /* Basic structure tests. */
1.129 @@ -295,10 +314,7 @@
1.130
1.131 __attr __CONTEXT_AS_VALUE(__attr attr)
1.132 {
1.133 - __attr out;
1.134 - out.context = attr.context;
1.135 - out.value = attr.context;
1.136 - return out;
1.137 + return __check_and_load_via_object_null(attr.value, __ATTRPOS(__context__), __ATTRCODE(__context__));
1.138 }
1.139
1.140 /* Type testing. */
1.141 @@ -310,7 +326,6 @@
1.142
1.143 int __ISNULL(__attr value)
1.144 {
1.145 - /* (value.context == __NULL.context) is superfluous */
1.146 return (value.value == 0); /* __NULL.value */
1.147 }
1.148