Support upvalue cells as exposed objects
This commit is contained in:
parent
ffa5d7e611
commit
46b63fc871
@ -1336,6 +1336,53 @@ KRK_Function(__build_class__) {
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
#undef CURRENT_CTYPE
|
||||
#define CURRENT_CTYPE KrkUpvalue *
|
||||
#define IS_Cell(o) (krk_isObjType((o), KRK_OBJ_UPVALUE))
|
||||
#define AS_Cell(o) ((KrkUpvalue*)AS_OBJECT(o))
|
||||
|
||||
KRK_StaticMethod(Cell,__new__) {
|
||||
KrkClass * _class = NULL;
|
||||
KrkValue contents = NONE_VAL();
|
||||
if (!krk_parseArgs("O!|V", (const char*[]){"cls","contents"}, KRK_BASE_CLASS(type), &_class, &contents)) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
if (_class != KRK_BASE_CLASS(Cell)) {
|
||||
return krk_runtimeError(vm.exceptions->typeError, "can not assemble new Cell from %R", OBJECT_VAL(_class));
|
||||
}
|
||||
|
||||
KrkUpvalue * out = krk_newUpvalue(-1);
|
||||
out->closed = contents;
|
||||
return OBJECT_VAL(out);
|
||||
}
|
||||
|
||||
#define UPVALUE_LOCATION(upvalue) (upvalue->location == -1 ? &upvalue->closed : &upvalue->owner->stack[upvalue->location])
|
||||
KRK_Method(Cell,__repr__) {
|
||||
struct StringBuilder sb = {0};
|
||||
|
||||
KrkValue contents = *UPVALUE_LOCATION(self);
|
||||
|
||||
if (!krk_pushStringBuilderFormat(&sb,"<cell at %p: %T object", (void*)self, contents)) goto _error;
|
||||
if (IS_OBJECT(contents)) {
|
||||
if (!krk_pushStringBuilderFormat(&sb, " at %p>", (void*)AS_OBJECT(contents))) goto _error;
|
||||
} else {
|
||||
krk_pushStringBuilder(&sb,'>');
|
||||
}
|
||||
|
||||
return krk_finishStringBuilder(&sb);
|
||||
|
||||
_error:
|
||||
krk_discardStringBuilder(&sb);
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
KRK_Method(Cell,cell_contents) {
|
||||
if (argc > 1) {
|
||||
*UPVALUE_LOCATION(self) = argv[1];
|
||||
}
|
||||
return *UPVALUE_LOCATION(self);
|
||||
}
|
||||
|
||||
_noexport
|
||||
void _createAndBind_builtins(void) {
|
||||
vm.baseClasses->objectClass = krk_newClass(S("object"), NULL);
|
||||
@ -1483,6 +1530,14 @@ void _createAndBind_builtins(void) {
|
||||
BIND_METHOD(enumerate,__call__);
|
||||
krk_finalizeClass(enumerate);
|
||||
|
||||
KrkClass * Cell = ADD_BASE_CLASS(KRK_BASE_CLASS(Cell), "Cell", object);
|
||||
Cell->allocSize = 0;
|
||||
Cell->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
|
||||
BIND_STATICMETHOD(Cell,__new__);
|
||||
BIND_METHOD(Cell,__repr__);
|
||||
BIND_PROP(Cell,cell_contents);
|
||||
krk_finalizeClass(Cell);
|
||||
|
||||
BUILTIN_FUNCTION("isinstance", FUNC_NAME(krk,isinstance),
|
||||
"@brief Check if an object is an instance of a type.\n"
|
||||
"@arguments inst, cls\n\n"
|
||||
|
@ -202,6 +202,8 @@ static void _closure_more(OPARGS, size_t constant) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (isLocal & 4) {
|
||||
fprintf(f, "classcell");
|
||||
} else { fprintf(f, "upvalue<%d>", index); }
|
||||
if (j + 1 != function->upvalueCount) fprintf(f, ", ");
|
||||
}
|
||||
|
@ -146,6 +146,7 @@ struct BaseClasses {
|
||||
KrkClass * ThreadClass; /**< Threading.Thread */
|
||||
KrkClass * LockClass; /**< Threading.Lock */
|
||||
KrkClass * CompilerStateClass; /**< Compiler global state */
|
||||
KrkClass * CellClass; /**< Upvalue cell */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -187,6 +187,22 @@ KRK_Method(function,__code__) {
|
||||
return OBJECT_VAL(AS_CLOSURE(self)->function);
|
||||
}
|
||||
|
||||
KRK_Method(function,__closure__) {
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
if (!IS_CLOSURE(self)) {
|
||||
return OBJECT_VAL(krk_newTuple(0));
|
||||
}
|
||||
|
||||
size_t cnt = AS_CLOSURE(self)->upvalueCount;
|
||||
KrkTuple * out = krk_newTuple(cnt);
|
||||
krk_push(OBJECT_VAL(out));
|
||||
for (size_t i = 0; i < cnt; ++i) {
|
||||
out->values.values[out->values.count++] = OBJECT_VAL(AS_CLOSURE(self)->upvalues[i]);
|
||||
}
|
||||
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
#undef CURRENT_CTYPE
|
||||
#define CURRENT_CTYPE KrkCodeObject*
|
||||
|
||||
@ -414,6 +430,7 @@ void _createAndBind_functionClass(void) {
|
||||
BIND_PROP(function,__annotations__);
|
||||
BIND_PROP(function,__code__);
|
||||
BIND_PROP(function,__globals__);
|
||||
BIND_PROP(function,__closure__);
|
||||
krk_defineNative(&function->methods, "__repr__", FUNC_NAME(function,__str__));
|
||||
krk_defineNative(&function->methods, "__class_getitem__", krk_GenericAlias)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
|
||||
krk_finalizeClass(function);
|
||||
|
2
src/vm.c
2
src/vm.c
@ -280,7 +280,7 @@ inline KrkClass * krk_getType(KrkValue of) {
|
||||
[KRK_OBJ_CLOSURE] = offsetof(struct BaseClasses, functionClass),
|
||||
[KRK_OBJ_BOUND_METHOD] = offsetof(struct BaseClasses, methodClass),
|
||||
[KRK_OBJ_STRING] = offsetof(struct BaseClasses, strClass),
|
||||
[KRK_OBJ_UPVALUE] = offsetof(struct BaseClasses, objectClass),
|
||||
[KRK_OBJ_UPVALUE] = offsetof(struct BaseClasses, CellClass),
|
||||
[KRK_OBJ_CLASS] = offsetof(struct BaseClasses, typeClass),
|
||||
[KRK_OBJ_TUPLE] = offsetof(struct BaseClasses, tupleClass),
|
||||
[KRK_OBJ_BYTES] = offsetof(struct BaseClasses, bytesClass),
|
||||
|
Loading…
Reference in New Issue
Block a user