Lichen

templates/native/introspection.c

627:05ad7964265c
2017-02-27 Paul Boddie Merged convenience macro changes.
     1 /* Native functions for introspection operations.     2      3 Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>     4      5 This program is free software; you can redistribute it and/or modify it under     6 the terms of the GNU General Public License as published by the Free Software     7 Foundation; either version 3 of the License, or (at your option) any later     8 version.     9     10 This program is distributed in the hope that it will be useful, but WITHOUT    11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    12 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    13 details.    14     15 You should have received a copy of the GNU General Public License along with    16 this program.  If not, see <http://www.gnu.org/licenses/>.    17 */    18     19 #include "types.h"    20 #include "exceptions.h"    21 #include "ops.h"    22 #include "progconsts.h"    23 #include "progops.h"    24 #include "progtypes.h"    25 #include "main.h"    26     27 /* Introspection. */    28     29 __attr __fn_native_introspection_object_getattr(__attr __args[])    30 {    31     __attr * const obj = &__args[1];    32     __attr * const name = &__args[2];    33     __attr * const _default = &__args[3];    34     /* name.__data__ interpreted as string */    35     __attr key = __load_via_object(name->value, __key__);    36     __attr out;    37     38     if ((key.code == 0) && (key.pos == 0))    39         return *_default;    40     41     /* Attempt to get the attribute from the object. */    42     43     out = __check_and_load_via_object_null(obj->value, key.pos, key.code);    44     if (out.value == 0)    45     {    46         /* Inspect the object's class if this failed. */    47     48         out = __check_and_load_via_class__(obj->value, key.pos, key.code);    49         if (out.value == 0)    50             return *_default;    51     52         /* Update the context to the object if it is a method. */    53     54         return __update_context(obj->value, out);    55     }    56     57     return out;    58 }    59     60 static int __issubclass(__ref obj, __attr cls)    61 {    62     return (__HASATTR(obj, __TYPEPOS(cls.value), __TYPECODE(cls.value)));    63 }    64     65 __attr __fn_native_introspection_isinstance(__attr __args[])    66 {    67     __attr * const obj = &__args[1];    68     __attr * const cls = &__args[2];    69     70     /* cls must be a class. */    71     if (__is_instance(obj->value) && __issubclass(__get_class(obj->value), *cls))    72         return __builtins___boolean_True;    73     else    74         return __builtins___boolean_False;    75 }    76     77 __attr __fn_native_introspection_issubclass(__attr __args[])    78 {    79     __attr * const obj = &__args[1];    80     __attr * const cls = &__args[2];    81     82     /* obj and cls must be classes. */    83     if (__issubclass(obj->value, *cls))    84         return __builtins___boolean_True;    85     else    86         return __builtins___boolean_False;    87 }    88     89 /* Module initialisation. */    90     91 void __main_native_introspection()    92 {    93 }