7 #define CURRENT_NAME self
9 #define IS_type(o) (IS_CLASS(o))
10 #define AS_type(o) (AS_CLASS(o))
12 #define CURRENT_CTYPE KrkClass *
14 static void _callSetName(
KrkClass * _class) {
17 extern FUNC_SIG(list,append);
22 if (!IS_KWARGS(entry->key)) {
24 if (type->_set_name) {
25 FUNC_NAME(list,append)(2,(
KrkValue[]){setnames,entry->key},0);
26 FUNC_NAME(list,append)(2,(
KrkValue[]){setnames,entry->value},0);
32 for (
size_t i = 0; i < AS_LIST(setnames)->count; i += 2) {
33 KrkValue name = AS_LIST(setnames)->values[i];
34 KrkValue value = AS_LIST(setnames)->values[i+1];
36 if (type->_set_name) {
55 KRK_StaticMethod(type,__new__) {
62 (
const char*[]){
"cls",
"name",
"base",
"namespace"},
63 vm.baseClasses->typeClass, &metaclass,
64 vm.baseClasses->strClass, &name,
65 vm.baseClasses->typeClass, &base,
66 vm.baseClasses->dictClass, &nspace)) {
70 if (base->
obj.
flags & KRK_OBJ_FLAGS_NO_INHERIT) {
77 _class->
_class = metaclass;
85 AS_CLOSURE(tmp)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
89 AS_CLOSURE(tmp)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
93 AS_CLOSURE(tmp)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
117 KRK_Method(type,__base__) {
118 if (argc > 1)
return krk_runtimeError(
vm.exceptions->typeError,
"__base__ can not be reassigned");
119 return self->base ? OBJECT_VAL(self->base) : NONE_VAL();
122 KRK_Method(type,__name__) {
124 if (!IS_STRING(argv[1]))
return TYPE_ERROR(str,argv[1]);
125 self->name = AS_STRING(argv[1]);
127 return self->name ? OBJECT_VAL(self->name) : NONE_VAL();
130 KRK_Method(type,__file__) {
132 if (!IS_STRING(argv[1]))
return TYPE_ERROR(str,argv[1]);
133 self->filename = AS_STRING(argv[1]);
135 return self->filename ? OBJECT_VAL(self->filename) : NONE_VAL();
138 KRK_Method(type,__repr__) {
141 krk_tableGet(&self->methods, OBJECT_VAL(S(
"__module__")), &module);
144 krk_tableGet(&self->methods, OBJECT_VAL(S(
"__qualname__")), &qualname);
145 KrkString * name = IS_STRING(qualname) ? AS_STRING(qualname) : self->name;
147 int includeModule = !(IS_NONE(module) || (IS_STRING(module) && AS_STRING(module) == S(
"builtins")));
149 return krk_stringFromFormat(
"<class '%s%s%S'>",
150 includeModule ? AS_CSTRING(module) :
"",
151 includeModule ?
"." :
"",
155 KRK_Method(type,__subclasses__) {
159 for (
size_t i = 0; i <
self->subclasses.capacity; ++i) {
161 if (IS_KWARGS(entry->key))
continue;
168 KRK_Method(type,__getitem__) {
169 if (self->_classgetitem && argc == 2) {
174 return krk_runtimeError(
vm.exceptions->attributeError,
"'%s' object is not subscriptable",
"type");
177 KRK_Method(type,__call__) {
178 if (
self ==
vm.baseClasses->typeClass) {
185 return krk_runtimeError(
vm.exceptions->typeError,
"%S() can not be built", self->name);
189 if (self->_new->type == KRK_OBJ_NATIVE) {
191 result = ((
KrkNative*)self->_new)->function(argc,argv,hasKw);
195 for (
int i = 0; i < argc; ++i) {
212 if (self->_init != KRK_BASE_CLASS(
object)->_init && self->_init != NULL &&
krk_isInstanceOf(result,
self)) {
218 for (
int i = 0; i < argc - 1; ++i) {
230 if (!IS_NONE(result)) {
231 fprintf(stderr,
"Warning: Non-None result returned from %s.__init__\n",
241 void _createAndBind_type(
void) {
242 KrkClass * type = ADD_BASE_CLASS(
vm.baseClasses->typeClass,
"type",
vm.baseClasses->objectClass);
245 BIND_PROP(type,__base__);
246 BIND_PROP(type,__file__);
247 BIND_PROP(type,__name__);
249 BIND_METHOD(type,__repr__);
250 BIND_METHOD(type,__subclasses__);
251 BIND_METHOD(type,__getitem__);
252 BIND_METHOD(type,__call__);
253 BIND_STATICMETHOD(type,__new__);
256 KRK_DOC(type,
"Obtain the object representation of the class of an object.");
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Functions for dealing with garbage collection and memory allocation.
struct KrkClass KrkClass
Type object.
KrkClass * krk_newClass(KrkString *name, KrkClass *base)
Create a new class object.
KrkString * name
Name of the class.
size_t allocSize
Size to allocate when creating instances of this class.
KrkTable methods
General attributes table.
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
struct KrkClass * _class
Metaclass.
int krk_bindMethodSuper(KrkClass *baseClass, KrkString *name, KrkClass *realClass)
Bind a method with super() semantics.
KrkTable entries
The actual table of values in the dict.
KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw)
Create a list object.
Managed binding to a C function.
uint16_t flags
General object flags, mostly related to garbage collection.
Immutable sequence of Unicode codepoints.
One (key,value) pair in a table.
int krk_tableGet(KrkTable *table, KrkValue key, KrkValue *value)
Obtain the value associated with a key in a table.
void krk_tableAddAll(KrkTable *from, KrkTable *to)
Add all key-value pairs from 'from' into 'to'.
int krk_tableGet_fast(KrkTable *table, struct KrkString *str, KrkValue *value)
Obtain the value associated with a string key in a table.
void krk_writeValueArray(KrkValueArray *array, KrkValue value)
Add a value to a value array.
Stack reference or primative value.
int krk_isInstanceOf(KrkValue obj, const KrkClass *type)
Determine if a class is an instance or subclass of a given type.
KrkClass * krk_getType(KrkValue value)
Get the class representing a value.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
#define KRK_DOC(thing, text)
Attach documentation to a thing of various types.
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
krk_threadLocal KrkThreadState krk_currentThread
Thread-local VM state.
KrkValue krk_callStack(int argCount)
Call a callable on the stack with argCount arguments.
#define vm
Convenience macro for namespacing.
KrkValue krk_pop(void)
Pop the top of the stack.
void krk_push(KrkValue value)
Push a stack value.
KrkValue krk_callDirect(KrkObj *callable, int argCount)
Call a closure or native function with argCount arguments.