1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/templates/ops.c Mon Oct 24 21:18:10 2016 +0200
1.3 @@ -0,0 +1,212 @@
1.4 +/* Common operations. */
1.5 +
1.6 +#include "ops.h"
1.7 +#include "progconsts.h"
1.8 +#include "progtypes.h"
1.9 +
1.10 +__attr null = {0, 0};
1.11 +
1.12 +/* Direct access to functions. */
1.13 +
1.14 +__attr __load_function(__func fn)
1.15 +{
1.16 + __attr out = {0, .fn=fn};
1.17 + return out;
1.18 +}
1.19 +
1.20 +/* Direct access and manipulation of static objects. */
1.21 +
1.22 +__attr __load_static(__ref obj)
1.23 +{
1.24 + __attr out = {0, .value=obj};
1.25 + return out;
1.26 +}
1.27 +
1.28 +/* Direct retrieval operations, returning and setting attributes. */
1.29 +
1.30 +__attr __load_via_object(__ref obj, int pos)
1.31 +{
1.32 + return obj->attrs[pos];
1.33 +}
1.34 +
1.35 +__attr __load_via_class(__ref obj, int pos)
1.36 +{
1.37 + return __load_via_object(__get_class(obj), pos);
1.38 +}
1.39 +
1.40 +__attr __get_class_and_load(__ref obj, int pos)
1.41 +{
1.42 + if (!__is_instance(obj))
1.43 + return __load_via_object(obj, pos);
1.44 + else
1.45 + return __load_via_class(obj, pos);
1.46 +}
1.47 +
1.48 +/* Direct storage operations. */
1.49 +
1.50 +int __store_via_object(__ref obj, int pos, __attr value)
1.51 +{
1.52 + obj->attrs[pos] = value;
1.53 + return 1;
1.54 +}
1.55 +
1.56 +/* Introspection. */
1.57 +
1.58 +int __is_instance(__ref obj)
1.59 +{
1.60 + return obj->pos == __INSTANCEPOS;
1.61 +}
1.62 +
1.63 +__ref __get_class(__ref obj)
1.64 +{
1.65 + return __load_via_object(obj, __pos___class__).value;
1.66 +}
1.67 +
1.68 +/* Attribute testing operations. */
1.69 +
1.70 +int __test_specific_instance(__ref obj, __ref type)
1.71 +{
1.72 + return __get_class(obj) == type;
1.73 +}
1.74 +
1.75 +int __test_common_instance(__ref obj, int pos, int code)
1.76 +{
1.77 + return __HASATTR(__get_class(obj), pos, code);
1.78 +}
1.79 +
1.80 +/* Attribute testing and retrieval operations. */
1.81 +
1.82 +__attr __check_and_load_via_class(__ref obj, int pos, int code)
1.83 +{
1.84 + return __check_and_load_via_object(__get_class(obj), pos, code);
1.85 +}
1.86 +
1.87 +__attr __check_and_load_via_object(__ref obj, int pos, int code)
1.88 +{
1.89 + return __HASATTR(obj, pos, code) ? __load_via_object(obj, pos) : null;
1.90 +}
1.91 +
1.92 +__attr __check_and_load_via_any(__ref obj, int pos, int code)
1.93 +{
1.94 + __attr out = __check_and_load_via_object(obj, pos, code);
1.95 + if (out.value == 0)
1.96 + out = __check_and_load_via_class(obj, pos, code);
1.97 + return out;
1.98 +}
1.99 +
1.100 +/* Attribute testing and storage operations. */
1.101 +
1.102 +int __check_and_store_via_object(__ref obj, int pos, int code, __attr value)
1.103 +{
1.104 + if (__HASATTR(obj, pos, code))
1.105 + {
1.106 + __store_via_object(obj, pos, value);
1.107 + return 1;
1.108 + }
1.109 + return 0;
1.110 +}
1.111 +
1.112 +int __check_and_store_via_any(__ref obj, int pos, int code, __attr value)
1.113 +{
1.114 + if (__check_and_store_via_object(obj, pos, code, value))
1.115 + return 1;
1.116 + return __check_and_store_via_object(__get_class(obj), pos, code, value);
1.117 +}
1.118 +
1.119 +/* Context-related operations. */
1.120 +
1.121 +__attr __test_context(__ref context, __attr attr)
1.122 +{
1.123 + if (__is_instance(attr.context))
1.124 + return attr;
1.125 + if (__test_common_instance(context, __TYPEPOS(attr.context), __TYPECODE(attr.context)))
1.126 + return __replace_context(context, attr);
1.127 +
1.128 + /* NOTE: An error may be more appropriate. */
1.129 +
1.130 + return null;
1.131 +}
1.132 +
1.133 +__attr __replace_context(__ref context, __attr attr)
1.134 +{
1.135 + __attr out;
1.136 +
1.137 + /* Set the context. */
1.138 +
1.139 + out.context = context;
1.140 +
1.141 + /* Reference a callable version of the attribute by obtaining the bound
1.142 + method reference from the __fn__ special attribute. */
1.143 +
1.144 + out.value = __load_via_object(attr.value, __ATTRPOS(__fn__)).b;
1.145 + return out;
1.146 +}
1.147 +
1.148 +__attr __update_context(__ref context, __attr attr)
1.149 +{
1.150 + __attr out = {context, .fn=attr.fn};
1.151 + return out;
1.152 +}
1.153 +
1.154 +/* Basic structure tests. */
1.155 +
1.156 +int __WITHIN(__ref obj, int pos)
1.157 +{
1.158 + return pos < obj->table->size;
1.159 +}
1.160 +
1.161 +int __HASATTR(__ref obj, int pos, int code)
1.162 +{
1.163 + return __WITHIN(obj, pos) && (obj->table->attrs[pos] == code);
1.164 +}
1.165 +
1.166 +/* Parameter position operations. */
1.167 +
1.168 +int __HASPARAM(const __ptable *ptable, int ppos, int pcode)
1.169 +{
1.170 + __param param;
1.171 +
1.172 + if (ppos < ptable->size)
1.173 + {
1.174 + param = ptable->params[ppos];
1.175 + if (param.code == pcode)
1.176 + return param.pos;
1.177 + }
1.178 +
1.179 + return -1;
1.180 +}
1.181 +
1.182 +/* Conversions. */
1.183 +
1.184 +__attr __CONTEXT_AS_VALUE(__attr attr)
1.185 +{
1.186 + __attr out;
1.187 + out.context = attr.context;
1.188 + out.value = attr.context;
1.189 + return out;
1.190 +}
1.191 +
1.192 +/* Type testing. */
1.193 +
1.194 +int __ISFUNC(__ref obj)
1.195 +{
1.196 + return __test_specific_instance(obj, &__FUNCTION_TYPE);
1.197 +}
1.198 +
1.199 +int __ISNULL(__attr value)
1.200 +{
1.201 + /* (value.context == null.context) is superfluous */
1.202 + return (value.value == null.value);
1.203 +}
1.204 +
1.205 +/* Attribute codes and positions for type objects. */
1.206 +
1.207 +unsigned int __TYPECODE(__ref obj)
1.208 +{
1.209 + return obj->table->attrs[obj->pos];
1.210 +}
1.211 +
1.212 +unsigned int __TYPEPOS(__ref obj)
1.213 +{
1.214 + return obj->pos;
1.215 +}