10 const char *
string = ((
KrkNative*)AS_OBJECT(func))->name;
11 if (!
string)
return OBJECT_VAL(S(
"<unnamed>"));
12 size_t len = strlen(
string);
24 if (_self->
obj.
flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
32 if (_self->
obj.
flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
40 #define IS_method(o) IS_BOUND_METHOD(o)
41 #define IS_function(o) (IS_CLOSURE(o)|IS_NATIVE(o))
43 #define AS_method(o) AS_BOUND_METHOD(o)
44 #define AS_function(o) (o)
46 #define CURRENT_NAME self
47 #define CURRENT_CTYPE KrkValue
49 KRK_StaticMethod(
function,__new__) {
50 METHOD_TAKES_EXACTLY(3);
53 if (!IS_INSTANCE(argv[3]))
54 return TYPE_ERROR(dict or instance
object,argv[3]);
56 if (IS_CLOSURE(argv[2]) && AS_CLOSURE(argv[2])->upvalueCount == code->upvalueCount) {
65 memcpy(AS_CLOSURE(
krk_peek(0))->upvalues, AS_CLOSURE(argv[2])->upvalues,
68 }
else if (IS_TUPLE(argv[2]) && AS_TUPLE(argv[2])->values.count == code->upvalueCount) {
75 for (
size_t i = 0; i < code->upvalueCount; ++i) {
77 AS_CLOSURE(
krk_peek(0))->upvalues[i]->closed = AS_TUPLE(argv[2])->values.values[i];
82 return TYPE_ERROR(managed
function with equal upvalue count or tuple,argv[2]);
85 KRK_Method(
function,__doc__) {
86 ATTRIBUTE_NOT_ASSIGNABLE();
88 if (IS_NATIVE(
self) && AS_NATIVE(
self)->doc) {
89 return OBJECT_VAL(
krk_copyString(AS_NATIVE(
self)->doc, strlen(AS_NATIVE(
self)->doc)));
90 }
else if (IS_CLOSURE(
self) && AS_CLOSURE(
self)->function->docstring) {
91 return OBJECT_VAL(AS_CLOSURE(
self)->function->docstring);
97 KRK_Method(
function,__name__) {
98 ATTRIBUTE_NOT_ASSIGNABLE();
100 if (IS_NATIVE(
self)) {
101 return nativeFunctionName(
self);
102 }
else if (IS_CLOSURE(
self) && AS_CLOSURE(
self)->function->name) {
103 return OBJECT_VAL(AS_CLOSURE(
self)->function->name);
106 return OBJECT_VAL(S(
""));
109 KRK_Method(
function,__qualname__) {
110 ATTRIBUTE_NOT_ASSIGNABLE();
112 if (IS_CLOSURE(
self) && AS_CLOSURE(
self)->function->qualname) {
113 return OBJECT_VAL(AS_CLOSURE(
self)->function->qualname);
119 KRK_Method(
function,__globals__) {
120 ATTRIBUTE_NOT_ASSIGNABLE();
122 if (IS_CLOSURE(
self)) {
123 return AS_CLOSURE(
self)->globalsOwner;
129 KRK_Method(
function,_ip_to_line) {
130 METHOD_TAKES_EXACTLY(1);
131 CHECK_ARG(1,
int,krk_integer_type,ip);
133 if (!IS_CLOSURE(
self))
return NONE_VAL();
135 size_t line =
krk_lineNumber(&AS_CLOSURE(
self)->function->chunk, ip);
137 return INTEGER_VAL(line);
140 KRK_Method(
function,__str__) {
144 KrkValue name = FUNC_NAME(
function,__qualname__)(1,&
self,0);
146 name = FUNC_NAME(
function,__name__)(1,&
self,0);
149 if (!IS_STRING(name)) name = OBJECT_VAL(S(
"<unnamed>"));
154 krk_pushStringBuilderFormat(&sb,
"<function %S at %p>", AS_STRING(name), (
void*)AS_OBJECT(
self));
161 KRK_Method(
function,__file__) {
162 ATTRIBUTE_NOT_ASSIGNABLE();
164 if (IS_NATIVE(
self))
return OBJECT_VAL(S(
"<builtin>"));
166 return AS_CLOSURE(
self)->function->chunk.filename ?
167 OBJECT_VAL(AS_CLOSURE(
self)->function->chunk.filename) :
171 KRK_Method(
function,__args__) {
172 ATTRIBUTE_NOT_ASSIGNABLE();
173 if (!IS_CLOSURE(
self))
return OBJECT_VAL(
krk_newTuple(0));
174 KrkTuple * tuple = functionArgs(AS_CLOSURE(
self)->
function);
175 return OBJECT_VAL(tuple);
178 KRK_Method(
function,__annotations__) {
179 ATTRIBUTE_NOT_ASSIGNABLE();
180 if (!IS_CLOSURE(
self))
return NONE_VAL();
181 return AS_CLOSURE(
self)->annotations;
184 KRK_Method(
function,__code__) {
185 ATTRIBUTE_NOT_ASSIGNABLE();
186 if (!IS_CLOSURE(
self))
return NONE_VAL();
187 return OBJECT_VAL(AS_CLOSURE(
self)->
function);
190 KRK_Method(
function,__closure__) {
191 ATTRIBUTE_NOT_ASSIGNABLE();
192 if (!IS_CLOSURE(
self)) {
196 size_t cnt = AS_CLOSURE(
self)->upvalueCount;
199 for (
size_t i = 0; i < cnt; ++i) {
207 #define CURRENT_CTYPE KrkCodeObject*
209 KRK_StaticMethod(codeobject,__new__) {
210 return krk_runtimeError(
vm.exceptions->typeError,
"codeobject object is not instantiable");
213 KRK_Method(codeobject,__name__) {
214 ATTRIBUTE_NOT_ASSIGNABLE();
215 return self->name ? OBJECT_VAL(self->name) : OBJECT_VAL(S(
""));
218 KRK_Method(codeobject,__str__) {
220 KrkValue s = FUNC_NAME(codeobject,__name__)(1,argv,0);
221 if (!IS_STRING(s))
return NONE_VAL();
225 krk_pushStringBuilderFormat(&sb,
"<codeobject %S at %p>", AS_STRING(s), (
void*)
self);
232 KRK_Method(codeobject,_ip_to_line) {
233 METHOD_TAKES_EXACTLY(1);
234 CHECK_ARG(1,
int,krk_integer_type,ip);
236 return INTEGER_VAL(line);
239 KRK_Method(codeobject,__constants__) {
240 ATTRIBUTE_NOT_ASSIGNABLE();
242 memcpy(AS_TUPLE(
krk_peek(0))->values.values,
243 self->chunk.constants.values,
244 sizeof(
KrkValue) * self->chunk.constants.count);
245 AS_TUPLE(
krk_peek(0))->values.count =
self->chunk.constants.count;
249 KRK_Method(codeobject,co_code) {
250 return OBJECT_VAL(
krk_newBytes(self->chunk.count, self->chunk.code));
253 KRK_Method(codeobject,co_argcount) {
254 return INTEGER_VAL(self->potentialPositionals);
257 KRK_Method(codeobject,co_kwonlyargcount) {
258 return INTEGER_VAL(self->keywordArgs);
261 KRK_Method(codeobject,co_posonlyargcount) {
263 for (
size_t i = 0; i <
self->potentialPositionals; ++i) {
264 if (!IS_NONE(self->positionalArgNames.values[i]))
return INTEGER_VAL(i);
266 return INTEGER_VAL(0);
269 KRK_Method(codeobject,__locals__) {
271 for (
size_t i = 0; i <
self->localNameCount; ++i) {
273 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = INTEGER_VAL(self->localNames[i].id);
274 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = INTEGER_VAL(self->localNames[i].birthday);
275 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = INTEGER_VAL(self->localNames[i].deathday);
276 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = OBJECT_VAL(self->localNames[i].name);
284 KRK_Method(codeobject,co_flags) {
285 ATTRIBUTE_NOT_ASSIGNABLE();
292 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) out |= 0x04;
293 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) out |= 0x08;
294 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR) out |= 0x20;
295 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) out |= 0x80;
297 return INTEGER_VAL(out);
300 KRK_Method(codeobject,__args__) {
301 ATTRIBUTE_NOT_ASSIGNABLE();
302 KrkTuple * tuple = functionArgs(
self);
303 return OBJECT_VAL(tuple);
308 #define CURRENT_CTYPE KrkBoundMethod*
312 KRK_StaticMethod(method,__new__) {
313 FUNCTION_TAKES_EXACTLY(3);
314 if (!IS_OBJECT(argv[1]))
return krk_runtimeError(
vm.exceptions->typeError,
"first argument must be a heap object");
318 KRK_Method(method,__name__) {
319 ATTRIBUTE_NOT_ASSIGNABLE();
320 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__name__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
323 KRK_Method(method,__qualname__) {
324 ATTRIBUTE_NOT_ASSIGNABLE();
325 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__qualname__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
328 KRK_Method(method,_ip_to_line) {
329 METHOD_TAKES_EXACTLY(1);
330 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,_ip_to_line)(2,(
KrkValue[]){OBJECT_VAL(self->method),argv[1]},0) : OBJECT_VAL(S(
"?"));
333 KRK_Method(method,__str__) {
335 KrkValue s = FUNC_NAME(method,__qualname__)(1,argv,0);
336 if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(1,argv,0);
337 if (!IS_STRING(s))
return NONE_VAL();
341 krk_pushStringBuilderFormat(&sb,
"<bound method '%S' of %T object", AS_STRING(s), self->receiver);
342 if (IS_OBJECT(self->receiver)) krk_pushStringBuilderFormat(&sb,
" at %p", (
void*)AS_OBJECT(self->receiver));
350 KRK_Method(method,__file__) {
351 ATTRIBUTE_NOT_ASSIGNABLE();
352 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__file__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
355 KRK_Method(method,__args__) {
356 ATTRIBUTE_NOT_ASSIGNABLE();
357 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__args__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
360 KRK_Method(method,__doc__) {
361 ATTRIBUTE_NOT_ASSIGNABLE();
362 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__doc__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
365 KRK_Method(method,__annotations__) {
366 ATTRIBUTE_NOT_ASSIGNABLE();
367 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__annotations__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
370 KRK_Method(method,__code__) {
371 ATTRIBUTE_NOT_ASSIGNABLE();
372 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__code__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
375 KRK_Method(method,__func__) {
376 ATTRIBUTE_NOT_ASSIGNABLE();
377 return OBJECT_VAL(self->method);
380 KRK_Method(method,__self__) {
381 ATTRIBUTE_NOT_ASSIGNABLE();
382 return OBJECT_VAL(self->receiver);
385 KRK_Function(staticmethod) {
387 if (!
krk_parseArgs(
"O!", (
const char*[]){
"method"}, KRK_BASE_CLASS(
function), &method))
return NONE_VAL();
388 method->
flags &= ~(KRK_OBJ_FLAGS_FUNCTION_MASK);
389 method->
flags |= KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
390 return OBJECT_VAL(method);
393 KRK_Function(classmethod) {
395 if (!
krk_parseArgs(
"O!", (
const char*[]){
"method"}, KRK_BASE_CLASS(
function), &method))
return NONE_VAL();
396 method->
flags &= ~(KRK_OBJ_FLAGS_FUNCTION_MASK);
397 method->
flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
398 return OBJECT_VAL(method);
402 void _createAndBind_functionClass(
void) {
403 KrkClass * codeobject = ADD_BASE_CLASS(
vm.baseClasses->codeobjectClass,
"codeobject",
vm.baseClasses->objectClass);
404 codeobject->
obj.
flags |= KRK_OBJ_FLAGS_NO_INHERIT;
406 BIND_STATICMETHOD(codeobject,__new__);
407 BIND_METHOD(codeobject,__str__);
408 BIND_METHOD(codeobject,_ip_to_line);
409 BIND_PROP(codeobject,__constants__);
410 BIND_PROP(codeobject,__name__);
411 BIND_PROP(codeobject,co_flags);
412 BIND_PROP(codeobject,co_code);
413 BIND_PROP(codeobject,co_argcount);
414 BIND_PROP(codeobject,co_kwonlyargcount);
415 BIND_PROP(codeobject,co_posonlyargcount);
416 BIND_PROP(codeobject,__locals__);
417 BIND_PROP(codeobject,__args__);
421 KrkClass *
function = ADD_BASE_CLASS(
vm.baseClasses->functionClass,
"function",
vm.baseClasses->objectClass);
422 function->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
423 function->allocSize = 0;
424 BIND_STATICMETHOD(
function,__new__);
425 BIND_METHOD(
function,__str__);
426 BIND_METHOD(
function,_ip_to_line);
427 BIND_PROP(
function,__doc__);
428 BIND_PROP(
function,__name__);
429 BIND_PROP(
function,__qualname__);
430 BIND_PROP(
function,__file__);
431 BIND_PROP(
function,__args__);
432 BIND_PROP(
function,__annotations__);
433 BIND_PROP(
function,__code__);
434 BIND_PROP(
function,__globals__);
435 BIND_PROP(
function,__closure__);
436 krk_defineNative(&function->methods,
"__repr__", FUNC_NAME(
function,__str__));
440 KrkClass * method = ADD_BASE_CLASS(
vm.baseClasses->methodClass,
"method",
vm.baseClasses->objectClass);
441 method->
obj.
flags |= KRK_OBJ_FLAGS_NO_INHERIT;
443 BIND_STATICMETHOD(method,__new__);
444 BIND_METHOD(method,__str__);
445 BIND_METHOD(method,_ip_to_line);
446 BIND_PROP(method,__doc__);
447 BIND_PROP(method,__name__);
448 BIND_PROP(method,__qualname__);
449 BIND_PROP(method,__file__);
450 BIND_PROP(method,__args__);
451 BIND_PROP(method,__annotations__);
452 BIND_PROP(method,__self__);
453 BIND_PROP(method,__func__);
454 BIND_PROP(method,__code__);
458 BUILTIN_FUNCTION(
"staticmethod", FUNC_NAME(krk,staticmethod),
"A static method does not take an implicit self or cls argument.");
459 BUILTIN_FUNCTION(
"classmethod", FUNC_NAME(krk,classmethod),
"A class method takes an implicit cls argument, instead of self.");
Functions for debugging bytecode execution.
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.
NativeFn krk_GenericAlias
Special value for type hint expressions.
KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj *method)
Create a new bound method.
KrkBytes * krk_newBytes(size_t length, uint8_t *source)
Create a new byte array.
size_t krk_lineNumber(KrkChunk *chunk, size_t offset)
Obtain the line number for a byte offset into a bytecode chunk.
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.
KrkClosure * krk_newClosure(KrkCodeObject *function, KrkValue globals)
Create a new function object.
unsigned short potentialPositionals
Precalculated positional arguments for complex argument processing.
KrkValueArray positionalArgNames
Array of names for positional arguments (and *args)
unsigned short keywordArgs
Arity of keyword (default) arguments.
KrkValueArray keywordArgNames
Array of names for keyword-only arguments (and **kwargs)
unsigned short totalArguments
Total argument cells we can fill in complex argument processing.
Managed binding to a C function.
The most basic object type.
uint16_t flags
General object flags, mostly related to garbage collection.
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
KrkNative * krk_defineNative(KrkTable *table, const char *name, NativeFn function)
Attach a native C function to an attribute table.
Immutable sequence of arbitrary values.
KrkValueArray values
Stores the length, capacity, and actual values of the tuple.
KrkTuple * krk_newTuple(size_t length)
Create a new tuple.
Storage for values referenced from nested functions.
KrkUpvalue * krk_newUpvalue(int slot)
Create an upvalue slot.
Stack reference or primative value.
Inline flexible string array.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
KrkValue krk_finishStringBuilder(struct StringBuilder *sb)
Finalize a string builder into a string object.
void krk_pushStringBuilder(struct StringBuilder *sb, char c)
Add a character to the end of a string builder.
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
#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_peek(int distance)
Peek down from the top of the stack.