initial support for __new__

This commit is contained in:
K. Lange 2023-01-24 18:15:13 +09:00
parent eef955935d
commit f9df8b22ef
18 changed files with 179 additions and 105 deletions

View File

@ -177,6 +177,29 @@ KRK_Method(object,__setattr__) {
return krk_instanceSetAttribute_wrapper(argv[0], AS_STRING(argv[1]), argv[2]);
}
KRK_StaticMethod(object,__new__) {
KrkClass * _class = NULL;
/* We don't actually care, but we want to accept them anyway */
int _argc = 0;
const KrkValue * _args = NULL;
if (!krk_parseArgs("O!*~", (const char*[]){"cls"}, vm.baseClasses->typeClass, &_class, &_argc, &_args)) {
return NONE_VAL();
}
if (_argc && _class->_init == vm.baseClasses->objectClass->_init) {
return krk_runtimeError(vm.exceptions->typeError, "%S() takes no arguments", _class->name);
}
return OBJECT_VAL(krk_newInstance(_class));
}
KRK_Method(object,__init__) {
return argv[0];
}
/**
* object.__str__() / object.__repr__()
*
@ -1229,7 +1252,9 @@ void _createAndBind_builtins(void) {
BIND_METHOD(object,__hash__);
BIND_METHOD(object,__eq__);
BIND_METHOD(object,__format__);
BIND_METHOD(object,__setattr__)->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
BIND_STATICMETHOD(object,__setattr__);
BIND_STATICMETHOD(object,__new__);
BIND_METHOD(object,__init__);
krk_defineNative(&object->methods, "__repr__", FUNC_NAME(object,__str__));
krk_finalizeClass(object);
KRK_DOC(object,

View File

@ -1606,20 +1606,22 @@ static void classBody(struct GlobalState * state, size_t blockWidth) {
consume(TOKEN_IDENTIFIER, "Expected method name after 'def'");
size_t ind = identifierConstant(state, &state->parser.previous);
if (state->parser.previous.length == 8 && memcmp(state->parser.previous.start, "__init__", 8) == 0) {
if (type == TYPE_COROUTINE_METHOD) {
error("'%s' can not be a coroutine","__init__");
return;
static struct CompilerSpecialMethod { const char * name; int type; } compilerSpecialMethods[] = {
{"__init__", TYPE_INIT},
{"__class_getitem__", TYPE_CLASSMETHOD},
{"__new__", TYPE_STATIC},
{"__prepare__", TYPE_CLASSMETHOD},
{NULL,0}
};
for (struct CompilerSpecialMethod * method = compilerSpecialMethods; method->name; method++) {
if (state->parser.previous.length == strlen(method->name) && memcmp(state->parser.previous.start, method->name, strlen(method->name)) == 0) {
if (type == TYPE_COROUTINE_METHOD) {
error("'%s' can not be a coroutine",method->name);
return;
}
type = method->type;
}
type = TYPE_INIT;
} else if (state->parser.previous.length == 17 && memcmp(state->parser.previous.start, "__class_getitem__", 17) == 0) {
if (type == TYPE_COROUTINE_METHOD) {
error("'%s' can not be a coroutine","__class_getitem__");
return;
}
/* This magic method is implicitly always a class method,
* so mark it as such so we don't do implicit self for it. */
type = TYPE_CLASSMETHOD;
}
function(state, type, blockWidth);

View File

@ -238,6 +238,7 @@ typedef struct KrkClass {
KrkObj * _pos;
KrkObj * _setattr;
KrkObj * _format;
KrkObj * _new;
size_t cacheIndex;
} KrkClass;

View File

@ -93,6 +93,20 @@
#define BIND_PROP(klass,method) krk_defineNativeProperty(&klass->methods, #method, _ ## klass ## _ ## method)
#define BIND_FUNC(module,func) krk_defineNative(&module->fields, #func, _krk_ ## func)
static inline KrkNative * krk_defineNativeStaticMethod(KrkTable * table, const char * name, NativeFn function) {
KrkNative * out = krk_defineNative(table,name,function);
out->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
return out;
}
#define BIND_STATICMETHOD(klass,method) krk_defineNativeStaticMethod(&klass->methods, #method, _ ## klass ## _ ## method)
static inline KrkNative * krk_deifneNativeClassMethod(KrkTable * table, const char * name, NativeFn function) {
KrkNative * out = krk_defineNative(table,name,function);
out->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
return out;
}
#define BIND_CLASSMETHOD(klass,method) krk_defineNativeClassMethod(&klass->methods, #method, _ ## klass ## _ ## method)
#define KRK_Method_internal_name(klass, name) \
_krk_method_ ## klass ## _ ## name
#define KRK_Method_internal_sig(klass, name) \
@ -120,6 +134,16 @@
} \
KRK_Function_internal_sig(name)
#define KRK_StaticMethod_internal_sig(klass, name) \
static inline KrkValue KRK_Method_internal_name(klass, name) (const char * _method_name, int argc, const KrkValue argv[], int hasKw)
#define KRK_StaticMethod(klass, name) \
KRK_StaticMethod_internal_sig(klass, name); \
FUNC_SIG(klass, name) { \
static const char * _method_name = # name; \
return KRK_Method_internal_name(klass,name)(_method_name,argc,argv,hasKw); \
} \
KRK_StaticMethod_internal_sig(klass,name)
/**
* @brief Inline flexible string array.
*/

View File

@ -47,6 +47,7 @@ CACHED_METHOD(SETNAME, "__set_name__", _set_name)
CACHED_METHOD(POS, "__pos__", _pos)
CACHED_METHOD(SETATTR, "__setattr__", _setattr)
CACHED_METHOD(FORMAT, "__format__", _format)
CACHED_METHOD(NEW, "__new__", _new)
/* These are not methods */
SPECIAL_ATTRS(CLASS, "__class__")

View File

@ -90,10 +90,58 @@ KRK_Method(type,__getitem__) {
return krk_runtimeError(vm.exceptions->attributeError, "'%s' object is not subscriptable", "type");
}
KRK_Method(type,__call__) {
if (self == vm.baseClasses->typeClass) {
if (argc == 2) {
return OBJECT_VAL(krk_getType(argv[1]));
}
return krk_runtimeError(vm.exceptions->attributeError, "TODO type(...)");
}
if (!self->_new) {
return krk_runtimeError(vm.exceptions->typeError, "%S() can not be built", self->name);
}
/* Push args */
int argCount = argc;
for (int i = 0; i < argc; ++i) {
krk_push(argv[i]);
}
if (hasKw) {
argCount += 3;
krk_push(KWARGS_VAL(KWARGS_DICT));
krk_push(argv[argc]);
krk_push(KWARGS_VAL(1));
}
krk_push(krk_callDirect(self->_new, argCount));
/* Exception here */
if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return NONE_VAL();
if (krk_isInstanceOf(krk_peek(0), self) && likely(self->_init != NULL)) {
for (int i = 0; i < argc - 1; ++i) {
krk_push(argv[i+1]);
}
if (hasKw) {
krk_push(KWARGS_VAL(KWARGS_DICT));
krk_push(argv[argc]);
krk_push(KWARGS_VAL(1));
}
return krk_callDirect(self->_init, argCount);
}
return krk_pop();
}
_noexport
void _createAndBind_type(void) {
KrkClass * type = ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass);
type->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
type->allocSize = sizeof(KrkClass);
BIND_PROP(type,__base__);
BIND_PROP(type,__file__);
@ -104,6 +152,7 @@ void _createAndBind_type(void) {
BIND_METHOD(type,__str__);
BIND_METHOD(type,__subclasses__);
BIND_METHOD(type,__getitem__);
BIND_METHOD(type,__call__);
krk_defineNative(&type->methods,"__repr__",FUNC_NAME(type,__str__));
krk_finalizeClass(type);

View File

@ -34,7 +34,7 @@ static int _bytes_callback(void * context, const KrkValue * values, size_t count
return 0;
}
KRK_Method(bytes,__init__) {
KRK_StaticMethod(bytes,__new__) {
if (argc < 2) return OBJECT_VAL(krk_newBytes(0,NULL));
METHOD_TAKES_AT_MOST(1);
@ -420,7 +420,7 @@ _noexport
void _createAndBind_bytesClass(void) {
KrkClass * bytes = ADD_BASE_CLASS(vm.baseClasses->bytesClass, "bytes", vm.baseClasses->objectClass);
bytes->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
KRK_DOC(BIND_METHOD(bytes,__init__),
KRK_DOC(BIND_STATICMETHOD(bytes,__new__),
"@brief An array of bytes.\n"
"@arguments iter=None\n\n"
"Creates a new @ref bytes object. If @p iter is provided, it should be a @ref tuple or @ref list "

View File

@ -46,8 +46,7 @@ static KrkTuple * functionArgs(KrkCodeObject * _self) {
#define CURRENT_NAME self
#define CURRENT_CTYPE KrkValue
FUNC_SIG(function,__init__) {
static __attribute__ ((unused)) const char* _method_name = "__init__";
KRK_StaticMethod(function,__new__) {
METHOD_TAKES_EXACTLY(3);
CHECK_ARG(1,codeobject,KrkCodeObject*,code);
@ -191,7 +190,7 @@ KRK_Method(function,__code__) {
#undef CURRENT_CTYPE
#define CURRENT_CTYPE KrkCodeObject*
FUNC_SIG(codeobject,__init__) {
KRK_StaticMethod(codeobject,__new__) {
return krk_runtimeError(vm.exceptions->typeError, "codeobject object is not instantiable");
}
@ -294,9 +293,8 @@ KRK_Method(codeobject,__args__) {
/* __init__ here will be called with a dummy instance as argv[0]; avoid
* complications with method argument checking by not using KRK_METHOD. */
FUNC_SIG(method,__init__) {
static __attribute__ ((unused)) const char* _method_name = "__init__";
METHOD_TAKES_EXACTLY(2);
KRK_StaticMethod(method,__new__) {
FUNCTION_TAKES_EXACTLY(3);
if (!IS_OBJECT(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "first argument must be a heap object");
return OBJECT_VAL(krk_newBoundMethod(argv[2],AS_OBJECT(argv[1])));
}
@ -388,7 +386,7 @@ _noexport
void _createAndBind_functionClass(void) {
KrkClass * codeobject = ADD_BASE_CLASS(vm.baseClasses->codeobjectClass, "codeobject", vm.baseClasses->objectClass);
codeobject->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(codeobject,__init__);
BIND_STATICMETHOD(codeobject,__new__);
BIND_METHOD(codeobject,__str__);
BIND_METHOD(codeobject,_ip_to_line);
BIND_PROP(codeobject,__constants__);
@ -405,7 +403,7 @@ void _createAndBind_functionClass(void) {
KrkClass * function = ADD_BASE_CLASS(vm.baseClasses->functionClass, "function", vm.baseClasses->objectClass);
function->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(function,__init__);
BIND_STATICMETHOD(function,__new__);
BIND_METHOD(function,__str__);
BIND_METHOD(function,_ip_to_line);
BIND_PROP(function,__doc__);
@ -422,9 +420,9 @@ void _createAndBind_functionClass(void) {
KrkClass * method = ADD_BASE_CLASS(vm.baseClasses->methodClass, "method", vm.baseClasses->objectClass);
method->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_STATICMETHOD(method,__new__);
BIND_METHOD(method,__str__);
BIND_METHOD(method,_ip_to_line);
BIND_METHOD(method,__init__);
BIND_PROP(method,__doc__);
BIND_PROP(method,__name__);
BIND_PROP(method,__qualname__);

View File

@ -16,8 +16,7 @@
extern KrkValue krk_int_from_float(double val);
FUNC_SIG(int,__init__) {
static __attribute__ ((unused)) const char* _method_name = "__init__";
KRK_StaticMethod(int,__new__) {
METHOD_TAKES_AT_MOST(2);
if (argc < 2) return INTEGER_VAL(0);
if (IS_BOOLEAN(argv[1])) return INTEGER_VAL(AS_INTEGER(argv[1]));
@ -567,9 +566,8 @@ KRK_Method(int,__pos__) {
} \
} while (0)
FUNC_SIG(float,__init__) {
static __attribute__ ((unused)) const char* _method_name = "__init__";
METHOD_TAKES_AT_MOST(1);
KRK_StaticMethod(float,__new__) {
FUNCTION_TAKES_AT_MOST(2);
if (argc < 2) return FLOATING_VAL(0.0);
if (IS_FLOATING(argv[1])) return argv[1];
if (IS_INTEGER(argv[1])) return FLOATING_VAL(AS_INTEGER(argv[1]));
@ -703,9 +701,8 @@ KRK_Method(float,__pos__) {
#undef CURRENT_CTYPE
#define CURRENT_CTYPE krk_integer_type
FUNC_SIG(bool,__init__) {
static __attribute__ ((unused)) const char* _method_name = "__init__";
METHOD_TAKES_AT_MOST(1);
KRK_StaticMethod(bool,__new__) {
FUNCTION_TAKES_AT_MOST(2);
if (argc < 2) return BOOLEAN_VAL(0);
return BOOLEAN_VAL(!krk_isFalsey(argv[1]));
}
@ -714,7 +711,7 @@ KRK_Method(bool,__str__) {
return OBJECT_VAL((self ? S("True") : S("False")));
}
FUNC_SIG(NoneType,__init__) {
KRK_StaticMethod(NoneType,__new__) {
if (argc > 1) return krk_runtimeError(vm.exceptions->argumentError, "%s takes no arguments", "NoneType");
return NONE_VAL();
}
@ -736,7 +733,7 @@ KRK_Method(NoneType,__eq__) {
#define IS_NotImplementedType(o) IS_NOTIMPL(o)
#define AS_NotImplementedType(o) (1)
FUNC_SIG(NotImplementedType,__init__) {
KRK_StaticMethod(NotImplementedType,__new__) {
if (argc > 1) return krk_runtimeError(vm.exceptions->argumentError, "%s takes no arguments", "NotImplementedType");
return NOTIMPL_VAL();
}
@ -756,8 +753,10 @@ KRK_Method(NotImplementedType,__eq__) {
}
#undef BIND_METHOD
#undef BIND_STATICMETHOD
/* These class names conflict with C types, so we need to cheat a bit */
#define BIND_METHOD(klass,method) do { krk_defineNative(& _ ## klass->methods, #method, _ ## klass ## _ ## method); } while (0)
#define BIND_STATICMETHOD(klass,method) do { krk_defineNativeStaticMethod(& _ ## klass->methods, #method, _ ## klass ## _ ## method); } while (0)
#define BIND_TRIPLET(klass,name) \
BIND_METHOD(klass,__ ## name ## __); \
BIND_METHOD(klass,__r ## name ## __); \
@ -766,7 +765,7 @@ _noexport
void _createAndBind_numericClasses(void) {
KrkClass * _int = ADD_BASE_CLASS(vm.baseClasses->intClass, "int", vm.baseClasses->objectClass);
_int->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(int,__init__);
BIND_STATICMETHOD(int,__new__);
BIND_METHOD(int,__str__);
BIND_METHOD(int,__int__);
BIND_METHOD(int,__chr__);
@ -807,7 +806,7 @@ void _createAndBind_numericClasses(void) {
KrkClass * _float = ADD_BASE_CLASS(vm.baseClasses->floatClass, "float", vm.baseClasses->objectClass);
_float->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(float,__init__);
BIND_STATICMETHOD(float,__new__);
BIND_METHOD(float,__int__);
BIND_METHOD(float,__float__);
BIND_METHOD(float,__str__);
@ -831,7 +830,7 @@ void _createAndBind_numericClasses(void) {
KrkClass * _bool = ADD_BASE_CLASS(vm.baseClasses->boolClass, "bool", vm.baseClasses->intClass);
_bool->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(bool,__init__);
BIND_STATICMETHOD(bool,__new__);
BIND_METHOD(bool,__str__);
krk_defineNative(&_bool->methods, "__repr__", FUNC_NAME(bool,__str__));
krk_finalizeClass(_bool);
@ -839,7 +838,7 @@ void _createAndBind_numericClasses(void) {
KrkClass * _NoneType = ADD_BASE_CLASS(vm.baseClasses->noneTypeClass, "NoneType", vm.baseClasses->objectClass);
_NoneType->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(NoneType, __init__);
BIND_STATICMETHOD(NoneType, __new__);
BIND_METHOD(NoneType, __str__);
BIND_METHOD(NoneType, __hash__);
BIND_METHOD(NoneType, __eq__);
@ -848,7 +847,7 @@ void _createAndBind_numericClasses(void) {
KrkClass * _NotImplementedType = ADD_BASE_CLASS(vm.baseClasses->notImplClass, "NotImplementedType", vm.baseClasses->objectClass);
_NotImplementedType->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(NotImplementedType, __init__);
BIND_STATICMETHOD(NotImplementedType, __new__);
BIND_METHOD(NotImplementedType, __str__);
BIND_METHOD(NotImplementedType, __hash__);
BIND_METHOD(NotImplementedType, __eq__);

View File

@ -27,12 +27,12 @@ KRK_Method(str,__ord__) {
return INTEGER_VAL(krk_unicodeCodepoint(self,0));
}
KRK_Method(str,__init__) {
KRK_StaticMethod(str,__new__) {
/* Ignore argument which would have been an instance */
if (argc < 2) {
return OBJECT_VAL(S(""));
}
METHOD_TAKES_AT_MOST(1);
FUNCTION_TAKES_AT_MOST(2);
if (IS_STRING(argv[1])) return argv[1]; /* strings are immutable, so we can just return the arg */
/* Find the type of arg */
krk_push(argv[1]);
@ -1237,7 +1237,7 @@ _noexport
void _createAndBind_strClass(void) {
KrkClass * str = ADD_BASE_CLASS(vm.baseClasses->strClass, "str", vm.baseClasses->objectClass);
str->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_METHOD(str,__init__);
BIND_STATICMETHOD(str,__new__);
BIND_METHOD(str,__iter__);
BIND_METHOD(str,__ord__);
BIND_METHOD(str,__int__);

View File

@ -24,21 +24,16 @@ static int _tuple_init_callback(void * context, const KrkValue * values, size_t
return 0;
}
static KrkValue _tuple_init(int argc, const KrkValue argv[], int hasKw) {
KRK_StaticMethod(tuple,__new__) {
METHOD_TAKES_AT_MOST(1);
if (argc == 1) {
return OBJECT_VAL(krk_newTuple(0));
} else if (argc == 2) {
/* Expand argument as an iterable. */
krk_push(OBJECT_VAL(krk_newTuple(0)));
KrkValueArray * positionals = &AS_TUPLE(krk_peek(0))->values;
KrkValue other = argv[1];
krk_unpackIterable(other, positionals, _tuple_init_callback);
return krk_pop();
} else {
return krk_runtimeError(vm.exceptions->argumentError,
"%s() takes %s %d argument%s (%d given)",
"tuple","at most",1,"",argc-1);
}
krk_push(OBJECT_VAL(krk_newTuple(0)));
KrkValueArray * positionals = &AS_TUPLE(krk_peek(0))->values;
KrkValue other = argv[1];
krk_unpackIterable(other, positionals, _tuple_init_callback);
return krk_pop();
}
/* tuple creator */
@ -273,6 +268,7 @@ _noexport
void _createAndBind_tupleClass(void) {
KrkClass * tuple = ADD_BASE_CLASS(vm.baseClasses->tupleClass, "tuple", vm.baseClasses->objectClass);
tuple->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_STATICMETHOD(tuple,__new__);
BIND_METHOD(tuple,__repr__);
BIND_METHOD(tuple,__getitem__);
BIND_METHOD(tuple,__len__);
@ -286,7 +282,6 @@ void _createAndBind_tupleClass(void) {
BIND_METHOD(tuple,__hash__);
BIND_METHOD(tuple,__add__);
BIND_METHOD(tuple,__mul__);
krk_defineNative(&tuple->methods, "__init__", _tuple_init);
krk_defineNative(&tuple->methods, "__str__", FUNC_NAME(tuple,__repr__));
krk_finalizeClass(tuple);

View File

@ -4,12 +4,12 @@
#include <kuroko/util.h>
#define KRK_VERSION_MAJOR 1
#define KRK_VERSION_MINOR 3
#define KRK_VERSION_PATCH 1
#define KRK_VERSION_LEVEL 0xF
#define KRK_VERSION_SERIAL 0x0
#define KRK_VERSION_MINOR 4
#define KRK_VERSION_PATCH 0
#define KRK_VERSION_LEVEL 0xa
#define KRK_VERSION_SERIAL 0x1
#define KRK_VERSION_EXTRA_BASE ""
#define KRK_VERSION_EXTRA_BASE "a1"
#ifndef STATIC_ONLY
#define KRK_VERSION_EXTRA KRK_VERSION_EXTRA_BASE

View File

@ -250,7 +250,7 @@ void krk_finalizeClass(KrkClass * _class) {
if (krk_tableGet(&_base->methods, vm.specialMethodNames[entry->index], &tmp)) break;
_base = _base->base;
}
if (_base && (IS_CLOSURE(tmp) || IS_NATIVE(tmp)) && !(AS_OBJECT(tmp)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD)) {
if (_base && (IS_CLOSURE(tmp) || IS_NATIVE(tmp)) && (!(AS_OBJECT(tmp)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD) || entry->index == METHOD_NEW)) {
*entry->method = AS_OBJECT(tmp);
}
}
@ -768,38 +768,6 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) {
switch (OBJECT_TYPE(callee)) {
case KRK_OBJ_CLOSURE: return _callManaged(AS_CLOSURE(callee), argCount, returnDepth);
case KRK_OBJ_NATIVE: return _callNative(AS_NATIVE(callee), argCount, returnDepth);
case KRK_OBJ_INSTANCE: {
KrkClass * _class = AS_INSTANCE(callee)->_class;
if (likely(_class->_call != NULL)) {
if (unlikely(returnDepth == 0)) _rotate(argCount);
krk_currentThread.stackTop[-argCount - 1] = callee;
argCount++;
returnDepth = returnDepth ? (returnDepth - 1) : 0;
return (_class->_call->type == KRK_OBJ_CLOSURE) ? _callManaged((KrkClosure*)_class->_call, argCount, returnDepth) : _callNative((KrkNative*)_class->_call, argCount, returnDepth);
} else {
krk_runtimeError(vm.exceptions->typeError, "'%T' object is not callable", callee);
return 0;
}
}
case KRK_OBJ_CLASS: {
KrkClass * _class = AS_CLASS(callee);
KrkInstance * newInstance = krk_newInstance(_class);
if (likely(_class->_init != NULL)) {
if (unlikely(returnDepth == 0)) _rotate(argCount);
krk_currentThread.stackTop[-argCount - 1] = OBJECT_VAL(newInstance);
callee = OBJECT_VAL(_class->_init);
argCount++;
returnDepth = returnDepth ? (returnDepth - 1) : 0;
goto _innerObject;
} else if (unlikely(argCount != 0)) {
krk_runtimeError(vm.exceptions->typeError, "%S() takes no arguments (%d given)",
_class->name, argCount);
return 0;
}
krk_currentThread.stackTop -= argCount + returnDepth;
krk_push(OBJECT_VAL(newInstance));
return 2;
}
case KRK_OBJ_BOUND_METHOD: {
KrkBoundMethod * bound = AS_BOUND_METHOD(callee);
if (unlikely(!bound->method)) {
@ -813,8 +781,19 @@ int krk_callValue(KrkValue callee, int argCount, int returnDepth) {
returnDepth = returnDepth ? (returnDepth - 1) : 0;
goto _innerObject;
}
default:
break;
default: {
KrkClass * _class = krk_getType(callee);
if (likely(_class->_call != NULL)) {
if (unlikely(returnDepth == 0)) _rotate(argCount);
krk_currentThread.stackTop[-argCount - 1] = callee;
argCount++;
returnDepth = returnDepth ? (returnDepth - 1) : 0;
return (_class->_call->type == KRK_OBJ_CLOSURE) ? _callManaged((KrkClosure*)_class->_call, argCount, returnDepth) : _callNative((KrkNative*)_class->_call, argCount, returnDepth);
} else {
krk_runtimeError(vm.exceptions->typeError, "'%T' object is not callable", callee);
return 0;
}
}
}
}
krk_runtimeError(vm.exceptions->typeError, "'%T' object is not callable", callee);
@ -2778,6 +2757,9 @@ _finishReturn: (void)0;
if (AS_STRING(name) == S("__class_getitem__") && IS_CLOSURE(method)) {
AS_CLOSURE(method)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
}
if (AS_STRING(name) == S("__new__") && IS_CLOSURE(method)) {
AS_CLOSURE(method)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
}
krk_pop();
break;
}

View File

@ -1,4 +1,4 @@
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__', 'longList', 'ofAttributes', 'onThatObject', 'thatWeWantToSet']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__init__', '__new__', '__repr__', '__setattr__', '__str__', 'longList', 'ofAttributes', 'onThatObject', 'thatWeWantToSet']
1
2
3

View File

@ -7,10 +7,10 @@ False
[1, 3, 4, 5]
[1, 3, 4]
list index out of range: 3
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__', 'baz', 'qux']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__init__', '__new__', '__repr__', '__setattr__', '__str__', 'baz', 'qux']
42
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__', 'qux']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__init__', '__new__', '__repr__', '__setattr__', '__str__', 'qux']
hi
'object' object has no attribute 'baz'
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__repr__', '__setattr__', '__str__']
['__class__', '__dir__', '__eq__', '__format__', '__hash__', '__init__', '__new__', '__repr__', '__setattr__', '__str__']
'object' object has no attribute 'bar'

View File

@ -1,3 +1,3 @@
['__class__', '__dir__', '__eq__', '__format__', '__func__', '__getattr__', '__hash__', '__init__', '__module__', '__qualname__', '__repr__', '__setattr__', '__str__', '_dict']
['__class__', '__dir__', '__eq__', '__format__', '__func__', '__getattr__', '__hash__', '__init__', '__module__', '__new__', '__qualname__', '__repr__', '__setattr__', '__str__', '_dict']
1
['__class__', '__dir__', '__eq__', '__format__', '__func__', '__hash__', '__module__', '__qualname__', '__repr__', '__setattr__', '__str__', 'butts']
['__class__', '__dir__', '__eq__', '__format__', '__func__', '__hash__', '__init__', '__module__', '__new__', '__qualname__', '__repr__', '__setattr__', '__str__', 'butts']

View File

@ -1,2 +0,0 @@
'object' object has no attribute '__init__'
'object' object has no attribute '__init__'

View File

@ -1,6 +1,6 @@
True
True
['__class__', '__dir__', '__doc__', '__eq__', '__format__', '__get__', '__hash__', '__init__', '__module__', '__name__', '__repr__', '__set__', '__setattr__', '__str__', 'fget', 'setter']
['__class__', '__dir__', '__doc__', '__eq__', '__format__', '__get__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__repr__', '__set__', '__setattr__', '__str__', 'fget', 'setter']
p retrieved from A
{'a': 45}
calling property from subclass