builtins.c
1 #include <string.h>
2 #include <kuroko/vm.h>
3 #include <kuroko/value.h>
4 #include <kuroko/memory.h>
5 #include <kuroko/util.h>
6 #include <kuroko/debug.h>
7 
8 #include "private.h"
9 
10 FUNC_SIG(list,__init__);
11 FUNC_SIG(list,sort);
12 
13 KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw) {
14  if (argc != 1)
15  return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)",
16  "dir", "exactly", 1, "", argc);
17 
18  /* Create a new list instance */
19  KrkValue myList = krk_list_of(0,NULL,0);
20  krk_push(myList);
21 
22  if (IS_INSTANCE(argv[0])) {
23  /* Obtain self-reference */
24  KrkInstance * self = AS_INSTANCE(argv[0]);
25  for (size_t i = 0; i < self->fields.capacity; ++i) {
26  if (!IS_KWARGS(self->fields.entries[i].key)) {
27  krk_writeValueArray(AS_LIST(myList),
28  self->fields.entries[i].key);
29  }
30  }
31  } else if (IS_CLOSURE(argv[0])) {
32  /* Why not just make closures instances... */
33  KrkClosure * self = AS_CLOSURE(argv[0]);
34  for (size_t i = 0; i < self->fields.capacity; ++i) {
35  if (!IS_KWARGS(self->fields.entries[i].key)) {
36  krk_writeValueArray(AS_LIST(myList),
37  self->fields.entries[i].key);
38  }
39  }
40  } else if (IS_CLASS(argv[0])) {
41  KrkClass * _class = AS_CLASS(argv[0]);
42  while (_class) {
43  for (size_t i = 0; i < _class->methods.capacity; ++i) {
44  if (!IS_KWARGS(_class->methods.entries[i].key)) {
45  krk_writeValueArray(AS_LIST(myList),
46  _class->methods.entries[i].key);
47  }
48  }
49  _class = _class->base;
50  }
51  }
52 
53  KrkClass * type = krk_getType(argv[0]);
54 
55  while (type) {
56  for (size_t i = 0; i < type->methods.capacity; ++i) {
57  if (!IS_KWARGS(type->methods.entries[i].key)) {
58  krk_writeValueArray(AS_LIST(myList),
59  type->methods.entries[i].key);
60  }
61  }
62  type = type->base;
63  }
64 
65  /* Throw it at a set to get unique, unordered results */
66  krk_push(krk_set_of(AS_LIST(myList)->count, AS_LIST(myList)->values, 0));
67  krk_swap(1);
68  krk_pop();
69 
70  /* Now build a fresh list */
71  myList = krk_list_of(0,NULL,0);
72  krk_push(myList);
73  krk_swap(1);
74  FUNC_NAME(list,__init__)(2,(KrkValue[]){krk_peek(1), krk_peek(0)},0);
75  FUNC_NAME(list,sort)(1,(KrkValue[]){krk_peek(1)},0);
76  krk_pop();
77 
78  return krk_pop();
79 }
80 
81 #define IS_object(o) (1)
82 #define AS_object(o) (o)
83 #define CURRENT_CTYPE KrkValue
84 #define CURRENT_NAME self
85 
86 KRK_Method(object,__dir__) {
87  return krk_dirObject(argc,argv,hasKw);
88 }
89 
90 KRK_Method(object,__class__) {
91  KrkClass * current = krk_getType(self);
92  if (argc > 1) {
93  if (!IS_CLASS(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not a class", argv[1]);
94  if (!IS_INSTANCE(argv[0]) || current->allocSize != sizeof(KrkInstance)) return krk_runtimeError(vm.exceptions->typeError, "'%T' object does not have modifiable type", argv[0]); /* TODO class? */
95  if (AS_CLASS(argv[1])->allocSize != sizeof(KrkInstance)) return krk_runtimeError(vm.exceptions->typeError, "'%S' type is not assignable", AS_CLASS(argv[1])->name);
96  AS_INSTANCE(argv[0])->_class = AS_CLASS(argv[1]);
97  current = AS_CLASS(argv[1]);
98  }
99  return OBJECT_VAL(current);
100 }
101 
102 KRK_Method(object,__hash__) {
103  if (!IS_OBJECT(self)) {
104  uint32_t hashed;
105  if (krk_hashValue(self, &hashed)) return NONE_VAL();
106  return INTEGER_VAL(hashed);
107  }
108  KrkObj * obj = AS_OBJECT(self);
109  if (!(obj->flags & KRK_OBJ_FLAGS_VALID_HASH)) {
110  obj->hash = INTEGER_VAL((int)((intptr_t)self >> 3));
111  obj->flags |= KRK_OBJ_FLAGS_VALID_HASH;
112  }
113  return INTEGER_VAL(obj->hash);
114 }
115 
116 KRK_Method(object,__eq__) {
117  METHOD_TAKES_EXACTLY(1);
118  if (argv[0] == argv[1]) return BOOLEAN_VAL(1);
119  return NOTIMPL_VAL();
120 }
121 
122 KRK_Function(getattr) {
123  FUNCTION_TAKES_AT_LEAST(2);
124  CHECK_ARG(1,str,KrkString*,property);
125 
126  krk_push(argv[0]);
127  if (!krk_getAttribute(AS_STRING(argv[1]))) {
128  krk_pop();
129  if (argc == 3) return argv[2];
130  return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", argv[0], AS_STRING(argv[1]));
131  }
132  return krk_pop();
133 }
134 
135 KRK_Function(setattr) {
136  FUNCTION_TAKES_EXACTLY(3);
137  CHECK_ARG(1,str,KrkString*,property);
138 
139  krk_push(argv[0]);
140  krk_push(argv[2]);
141  if (!krk_setAttribute(AS_STRING(argv[1]))) {
142  return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", argv[0], AS_STRING(argv[1]));
143  }
144  return krk_pop();
145 }
146 
147 KRK_Function(hasattr) {
148  FUNCTION_TAKES_AT_LEAST(2);
149  CHECK_ARG(1,str,KrkString*,property);
150 
151  krk_push(argv[0]);
152  if (!krk_getAttribute(AS_STRING(argv[1]))) {
153  krk_pop();
154  return BOOLEAN_VAL(0);
155  }
156  krk_pop();
157  return BOOLEAN_VAL(1);
158 }
159 
160 KRK_Function(delattr) {
161  FUNCTION_TAKES_AT_LEAST(2);
162  CHECK_ARG(1,str,KrkString*,property);
163 
164  krk_push(argv[0]);
165  if (!krk_delAttribute(AS_STRING(argv[1]))) {
166  return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%S'", argv[0], AS_STRING(argv[1]));
167  }
168  return NONE_VAL();
169 }
170 
175 KRK_Method(object,__setattr__) {
176  METHOD_TAKES_EXACTLY(2);
177  if (!IS_STRING(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "expected str");
178 
179  if (!IS_INSTANCE(argv[0])) {
180  return FUNC_NAME(krk,setattr)(argc,argv,hasKw);
181  }
182 
183  /* It's an instance, that presumably does not have a `__setattr__`? */
184  return krk_instanceSetAttribute_wrapper(argv[0], AS_STRING(argv[1]), argv[2]);
185 }
186 
187 KRK_StaticMethod(object,__new__) {
188  KrkClass * _class = NULL;
189 
190  /* We don't actually care, but we want to accept them anyway */
191  int _argc = 0;
192  const KrkValue * _args = NULL;
193 
194  if (!krk_parseArgs("O!*~", (const char*[]){"cls"}, vm.baseClasses->typeClass, &_class, &_argc, &_args)) {
195  return NONE_VAL();
196  }
197 
198  KrkClass * _cls = _class;
199  while (_cls) {
200  if (_cls->_new && IS_NATIVE(OBJECT_VAL(_cls->_new)) && _cls->_new != KRK_BASE_CLASS(object)->_new) {
201  return krk_runtimeError(vm.exceptions->typeError, "object.__new__(%S) is not safe, use %S.__new__()", _class->name, _cls->name);
202  }
203  _cls = _cls->base;
204  }
205 
206  if (_class->_init == vm.baseClasses->objectClass->_init && (_argc || (hasKw && AS_DICT(argv[argc])->count))) {
207  return krk_runtimeError(vm.exceptions->typeError, "%S() takes no arguments", _class->name);
208  }
209 
210  return OBJECT_VAL(krk_newInstance(_class));
211 }
212 
213 KRK_Method(object,__init__) {
214  return NONE_VAL();
215 }
216 
217 KRK_StaticMethod(object,__init_subclass__) {
218  if (!krk_parseArgs(".", (const char*[]){NULL}, NULL)) return NONE_VAL();
219  return NONE_VAL();
220 }
221 
222 
236 KRK_Method(object,__str__) {
237  KrkClass * type = krk_getType(self);
238 
239  KrkValue module = NONE_VAL();
240  krk_tableGet(&type->methods, OBJECT_VAL(S("__module__")), &module);
241  KrkValue qualname = NONE_VAL();
242  krk_tableGet(&type->methods, OBJECT_VAL(S("__qualname__")), &qualname);
243  KrkString * name = IS_STRING(qualname) ? AS_STRING(qualname) : type->name;
244  int includeModule = !(IS_NONE(module) || (IS_STRING(module) && AS_STRING(module) == S("builtins")));
245 
246  struct StringBuilder sb = {0};
247 
248  if (!krk_pushStringBuilderFormat(&sb, "<%s%s%s object",
249  includeModule ? AS_CSTRING(module) : "",
250  includeModule ? "." : "",
251  name->chars)) goto _error;
252 
253  if (IS_OBJECT(self) && !krk_pushStringBuilderFormat(&sb, " at %p", (void*)AS_OBJECT(self))) {
254  goto _error;
255  }
256 
257  krk_pushStringBuilder(&sb, '>');
258  return krk_finishStringBuilder(&sb);
259 
260 _error:
262  return NONE_VAL();
263 }
264 
265 KRK_Method(object,__format__) {
266  METHOD_TAKES_EXACTLY(1);
267  if (!IS_STRING(argv[1])) return TYPE_ERROR(str,argv[1]);
268  if (AS_STRING(argv[1])->length != 0) return krk_runtimeError(vm.exceptions->typeError, "Unsupported format string");
269  KrkClass * type = krk_getType(argv[0]);
270  if (!type->_tostr) return krk_runtimeError(vm.exceptions->typeError, "'%T' can not be converted to str", argv[0]);
271  krk_push(argv[0]);
272  return krk_callDirect(type->_tostr, 1);
273 }
274 
275 #undef CURRENT_CTYPE
276 #undef CURRENT_NAME
277 
278 KRK_Function(len) {
279  FUNCTION_TAKES_EXACTLY(1);
280  /* Shortcuts */
281  if (IS_STRING(argv[0])) return INTEGER_VAL(AS_STRING(argv[0])->codesLength);
282  if (IS_TUPLE(argv[0])) return INTEGER_VAL(AS_TUPLE(argv[0])->values.count);
283 
284  KrkClass * type = krk_getType(argv[0]);
285  if (!type->_len) return krk_runtimeError(vm.exceptions->typeError, "object of type '%T' has no len()", argv[0]);
286  krk_push(argv[0]);
287 
288  return krk_callDirect(type->_len, 1);
289 }
290 
291 KRK_Function(dir) {
292  FUNCTION_TAKES_AT_MOST(1);
293  if (argc) {
294  KrkClass * type = krk_getType(argv[0]);
295  if (!type->_dir) {
296  return krk_dirObject(argc,argv,hasKw); /* Fallback */
297  }
298  krk_push(argv[0]);
299  return krk_callDirect(type->_dir, 1);
300  } else {
301  /* Current globals */
303  return krk_runtimeError(vm.exceptions->nameError, "No active globals context");
304  }
305 
306  /* Set up a new list for our output */
307  KrkValue myList = krk_list_of(0,NULL,0);
308  krk_push(myList);
309 
310  /* Put all the keys from the globals table in it */
312  for (size_t i = 0; i < globals->capacity; ++i) {
313  KrkTableEntry * entry = &globals->entries[i];
314  if (IS_KWARGS(entry->key)) continue;
315  krk_writeValueArray(AS_LIST(myList), entry->key);
316  }
317 
318  /* Now sort it */
319  FUNC_NAME(list,sort)(1,(KrkValue[]){krk_peek(0)},0);
320  return krk_pop(); /* Return the list */
321  }
322 }
323 
324 KRK_Function(repr) {
325  FUNCTION_TAKES_EXACTLY(1);
326  /* Everything should have a __repr__ */
327  KrkClass * type = krk_getType(argv[0]);
328  krk_push(argv[0]);
329  return krk_callDirect(type->_reprer, 1);
330 }
331 
332 #define trySlowMethod(name) do { \
333  KrkClass * type = krk_getType(argv[0]); \
334  KrkValue method; \
335  while (type) { \
336  if (krk_tableGet(&type->methods, name, &method)) { \
337  krk_push(method); \
338  krk_push(argv[0]); \
339  return krk_callStack(1); \
340  } \
341  type = type->base; \
342  } \
343 } while (0)
344 
345 KRK_Function(ord) {
346  FUNCTION_TAKES_EXACTLY(1);
347  trySlowMethod(vm.specialMethodNames[METHOD_ORD]);
348  return TYPE_ERROR(string of length 1,argv[0]);
349 }
350 
351 KRK_Function(chr) {
352  FUNCTION_TAKES_EXACTLY(1);
353  trySlowMethod(vm.specialMethodNames[METHOD_CHR]);
354  return TYPE_ERROR(int,argv[0]);
355 }
356 
357 KRK_Function(hex) {
358  FUNCTION_TAKES_EXACTLY(1);
359  trySlowMethod(OBJECT_VAL(S("__hex__")));
360  return TYPE_ERROR(int,argv[0]);
361 }
362 
363 KRK_Function(oct) {
364  FUNCTION_TAKES_EXACTLY(1);
365  trySlowMethod(OBJECT_VAL(S("__oct__")));
366  return TYPE_ERROR(int,argv[0]);
367 }
368 
369 KRK_Function(bin) {
370  FUNCTION_TAKES_EXACTLY(1);
371  trySlowMethod(OBJECT_VAL(S("__bin__")));
372  return TYPE_ERROR(int,argv[0]);
373 }
374 
375 #define KRK_STRING_FAST(string,offset) (uint32_t)\
376  ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) <= (KRK_OBJ_FLAGS_STRING_UCS1) ? ((uint8_t*)string->codes)[offset] : \
377  ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == (KRK_OBJ_FLAGS_STRING_UCS2) ? ((uint16_t*)string->codes)[offset] : \
378  ((uint32_t*)string->codes)[offset]))
379 
380 int krk_unpackIterable(KrkValue iterable, void * context, int callback(void *, const KrkValue *, size_t)) {
381  if (IS_TUPLE(iterable)) {
382  if (callback(context, AS_TUPLE(iterable)->values.values, AS_TUPLE(iterable)->values.count)) return 1;
383  } else if (IS_list(iterable)) {
384  if (callback(context, AS_LIST(iterable)->values, AS_LIST(iterable)->count)) return 1;
385  } else if (IS_dict(iterable)) {
386  for (size_t i = 0; i < AS_DICT(iterable)->capacity; ++i) {
387  if (!IS_KWARGS(AS_DICT(iterable)->entries[i].key)) {
388  if (callback(context, &AS_DICT(iterable)->entries[i].key, 1)) return 1;
389  }
390  }
391  } else if (IS_STRING(iterable)) {
392  krk_unicodeString(AS_STRING(iterable));
393  for (size_t i = 0; i < AS_STRING(iterable)->codesLength; ++i) {
394  KrkValue s = krk_string_get(2, (KrkValue[]){iterable,INTEGER_VAL(i)}, i);
395  if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
396  krk_push(s);
397  if (callback(context, &s, 1)) {
398  krk_pop();
399  return 1;
400  }
401  krk_pop();
402  }
403  } else {
404  KrkClass * type = krk_getType(iterable);
405  if (unlikely(!type->_iter)) {
406  krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", iterable);
407  return 1;
408  }
409 
410  /* Build the iterable */
411  krk_push(iterable);
412  KrkValue iterator = krk_callDirect(type->_iter, 1);
413 
414  if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
415 
416  krk_push(iterator);
417 
418  do {
419  /* Call the iterator */
420  krk_push(iterator);
421  KrkValue item = krk_callStack(0);
422 
423  if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
424  krk_pop(); /* __iter__() result */
425  return 1;
426  }
427 
428  if (krk_valuesSame(iterator, item)) {
429  break;
430  }
431 
432  krk_push(item);
433  if (callback(context, &item, 1)) {
434  krk_pop(); /* item */
435  krk_pop(); /* __iter__ */
436  return 1;
437  }
438  krk_pop(); /* item */
439  } while (1);
440 
441  krk_pop(); /* __iter__() result */
442  }
443  return 0;
444 }
445 
447  KrkValue base;
448 };
449 
450 static int _any_callback(void * context, const KrkValue * values, size_t count) {
451  struct SimpleContext * _context = context;
452  for (size_t i = 0; i < count; ++i) {
453  if (!krk_isFalsey(values[i])) {
454  _context->base = BOOLEAN_VAL(1);
455  return 1;
456  }
457  }
458  return 0;
459 }
460 
461 KRK_Function(any) {
462  FUNCTION_TAKES_EXACTLY(1);
463  struct SimpleContext context = { BOOLEAN_VAL(0) };
464  krk_unpackIterable(argv[0], &context, _any_callback);
465  return context.base;
466 }
467 
468 static int _all_callback(void * context, const KrkValue * values, size_t count) {
469  struct SimpleContext * _context = context;
470  for (size_t i = 0; i < count; ++i) {
471  if (krk_isFalsey(values[i])) {
472  _context->base = BOOLEAN_VAL(0);
473  return 1;
474  }
475  }
476  return 0;
477 }
478 
479 KRK_Function(all) {
480  FUNCTION_TAKES_EXACTLY(1);
481  struct SimpleContext context = { BOOLEAN_VAL(1) };
482  krk_unpackIterable(argv[0], &context, _all_callback);
483  return context.base;
484 }
485 
486 #define CURRENT_CTYPE KrkInstance *
487 #define CURRENT_NAME self
488 
489 #define IS_map(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(map)))
490 #define AS_map(o) (AS_INSTANCE(o))
491 KRK_Method(map,__init__) {
492  METHOD_TAKES_AT_LEAST(2);
493 
494  /* Attach the function to it */
495  krk_attachNamedValue(&self->fields, "_function", argv[1]);
496 
497  /* Make the iter objects */
498  KrkTuple * iters = krk_newTuple(argc - 2);
499  krk_push(OBJECT_VAL(iters));
500 
501  /* Attach the tuple to the object */
502  krk_attachNamedValue(&self->fields, "_iterables", krk_peek(0));
503  krk_pop();
504 
505  for (int i = 2; i < argc; ++i) {
506  KrkClass * type = krk_getType(argv[i]);
507  if (!type->_iter) {
508  return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[i]);
509  }
510  krk_push(argv[i]);
511  KrkValue asIter = krk_callDirect(type->_iter, 1);
512  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
513  /* Attach it to the tuple */
514  iters->values.values[iters->values.count++] = asIter;
515  }
516 
517  return NONE_VAL();
518 }
519 
520 KRK_Method(map,__iter__) {
521  METHOD_TAKES_NONE();
522  return OBJECT_VAL(self);
523 }
524 
525 KRK_Method(map,__call__) {
526  METHOD_TAKES_NONE();
527 
528  size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack;
529 
530  /* Get members */
531  KrkValue function = NONE_VAL();
532  KrkValue iterators = NONE_VAL();
533 
534  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("_function")), &function)) return krk_runtimeError(vm.exceptions->valueError, "corrupt map object");
535  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("_iterables")), &iterators) || !IS_TUPLE(iterators)) return krk_runtimeError(vm.exceptions->valueError, "corrupt map object");
536 
537  krk_push(function);
538 
539  /* Go through each iterator */
540  for (size_t i = 0; i < AS_TUPLE(iterators)->values.count; ++i) {
541  /* Obtain the next value and push it */
542  krk_push(AS_TUPLE(iterators)->values.values[i]);
544  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
545  /* End iteration whenever one runs out */
546  if (krk_valuesEqual(krk_peek(0), AS_TUPLE(iterators)->values.values[i])) {
547  for (size_t j = 0; j < i + 1; ++j) krk_pop();
548  krk_pop(); /* the function */
549  return OBJECT_VAL(self);
550  }
551  }
552 
553  /* Call the function */
554  KrkValue val = krk_callStack(AS_TUPLE(iterators)->values.count);
556  return val;
557 }
558 
559 #define IS_zip(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(zip)))
560 #define AS_zip(o) (AS_INSTANCE(o))
561 KRK_Method(zip,__init__) {
562  if (hasKw && AS_DICT(argv[argc])->count) return krk_runtimeError(vm.exceptions->typeError, "%s() takes no keyword arguments", "zip");
563 
564  KrkTuple * iters = krk_newTuple(argc - 1);
565  krk_push(OBJECT_VAL(iters));
566  krk_attachNamedValue(&self->fields, "_iterables", krk_peek(0));
567  krk_pop();
568 
569  for (int i = 1; i < argc; ++i) {
570  KrkClass * type = krk_getType(argv[i]);
571  if (!type->_iter) {
572  return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[i]);
573  }
574  krk_push(argv[i]);
575  KrkValue asIter = krk_callDirect(type->_iter, 1);
576  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
577  /* Attach it to the tuple */
578  iters->values.values[iters->values.count++] = asIter;
579  }
580 
581  return NONE_VAL();
582 }
583 
584 KRK_Method(zip,__iter__) {
585  METHOD_TAKES_NONE();
586  return OBJECT_VAL(self);
587 }
588 
589 KRK_Method(zip,__call__) {
590  METHOD_TAKES_NONE();
591 
592  /* Get members */
593  KrkValue iterators = NONE_VAL();
594  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("_iterables")), &iterators) || !IS_TUPLE(iterators)) return krk_runtimeError(vm.exceptions->valueError, "corrupt zip object");
595 
596  /* Set up a tuple */
597  KrkTuple * out = krk_newTuple(AS_TUPLE(iterators)->values.count);
598  krk_push(OBJECT_VAL(out));
599 
600  /* Go through each iterator */
601  for (size_t i = 0; i < AS_TUPLE(iterators)->values.count; ++i) {
602  krk_push(AS_TUPLE(iterators)->values.values[i]);
604  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
605  if (krk_valuesEqual(krk_peek(0), AS_TUPLE(iterators)->values.values[i])) {
606  return OBJECT_VAL(self);
607  }
608  out->values.values[out->values.count++] = krk_pop();
609  }
610 
611  /* Return tuple */
612  return krk_pop();
613 }
614 
615 #define IS_filter(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(filter)))
616 #define AS_filter(o) (AS_INSTANCE(o))
617 KRK_Method(filter,__init__) {
618  METHOD_TAKES_EXACTLY(2);
619  krk_attachNamedValue(&self->fields, "_function", argv[1]);
620  KrkClass * type = krk_getType(argv[2]);
621  if (!type->_iter) {
622  return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[2]);
623  }
624  krk_push(argv[2]);
625  KrkValue asIter = krk_callDirect(type->_iter, 1);
626  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
627  krk_attachNamedValue(&self->fields, "_iterator", asIter);
628 
629  return NONE_VAL();
630 }
631 
632 KRK_Method(filter,__iter__) {
633  METHOD_TAKES_NONE();
634  return OBJECT_VAL(self);
635 }
636 
637 KRK_Method(filter,__call__) {
638  METHOD_TAKES_NONE();
639  size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack;
640  KrkValue function = NONE_VAL();
641  KrkValue iterator = NONE_VAL();
642 
643  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("_function")), &function)) return krk_runtimeError(vm.exceptions->valueError, "corrupt filter object");
644  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("_iterator")), &iterator)) return krk_runtimeError(vm.exceptions->valueError, "corrupt filter object");
645 
646  while (1) {
647  krk_push(iterator);
649 
650  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
651  if (krk_valuesEqual(iterator, krk_peek(0))) {
653  return OBJECT_VAL(self);
654  }
655 
656  if (IS_NONE(function)) {
657  if (krk_isFalsey(krk_peek(0))) {
658  krk_pop(); /* iterator result */
659  continue;
660  }
661  } else {
662  krk_push(function);
663  krk_push(krk_peek(1));
664  KrkValue result = krk_callStack(1);
665  if (krk_isFalsey(result)) {
666  krk_pop(); /* iterator result */
667  continue;
668  }
669  }
670 
671  KrkValue out = krk_pop();
673  return out;
674  }
675 }
676 
677 #define IS_enumerate(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(enumerate)))
678 #define AS_enumerate(o) (AS_INSTANCE(o))
679 KRK_Method(enumerate,__init__) {
680  METHOD_TAKES_EXACTLY(1);
681  KrkValue start = INTEGER_VAL(0);
682  if (hasKw) krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("start")), &start);
683 
684  krk_attachNamedValue(&self->fields, "_counter", start);
685 
686  /* Attach iterator */
687  KrkClass * type = krk_getType(argv[1]);
688  if (!type->_iter) {
689  return krk_runtimeError(vm.exceptions->typeError, "'%T' object is not iterable", argv[1]);
690  }
691  krk_push(argv[1]);
692  KrkValue asIter = krk_callDirect(type->_iter, 1);
693  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
694  krk_attachNamedValue(&self->fields, "_iterator", asIter);
695 
696  return NONE_VAL();
697 }
698 
699 KRK_Method(enumerate,__iter__) {
700  METHOD_TAKES_NONE();
701  return OBJECT_VAL(self);
702 }
703 
704 extern KrkValue krk_operator_add (KrkValue a, KrkValue b);
705 KRK_Method(enumerate,__call__) {
706  METHOD_TAKES_NONE();
707  size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack;
708  KrkValue counter = NONE_VAL();
709  KrkValue iterator = NONE_VAL();
710 
711  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("_counter")), &counter)) return krk_runtimeError(vm.exceptions->valueError, "corrupt enumerate object");
712  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("_iterator")), &iterator)) return krk_runtimeError(vm.exceptions->valueError, "corrupt enumerate object");
713 
714  KrkTuple * tupleOut = krk_newTuple(2);
715  krk_push(OBJECT_VAL(tupleOut));
716 
717  krk_push(iterator);
719 
720  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
722  return NONE_VAL();
723  }
724  if (krk_valuesEqual(iterator, krk_peek(0))) {
725  krk_pop();
726  krk_pop();
728  return OBJECT_VAL(self);
729  }
730 
731  /* Make a tuple */
732  tupleOut->values.values[tupleOut->values.count++] = counter;
733  tupleOut->values.values[tupleOut->values.count++] = krk_pop();
734 
735  krk_push(krk_operator_add(counter, INTEGER_VAL(1)));
736  krk_attachNamedValue(&self->fields, "_counter", krk_pop());
737 
738  KrkValue out = krk_pop();
740  return out;
741 }
742 
743 static int _sum_callback(void * context, const KrkValue * values, size_t count) {
744  struct SimpleContext * _context = context;
745  for (size_t i = 0; i < count; ++i) {
746  _context->base = krk_operator_add(_context->base, values[i]);
747  if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 1;
748  }
749  return 0;
750 }
751 
752 KRK_Function(sum) {
753  FUNCTION_TAKES_AT_LEAST(1);
754  KrkValue base = INTEGER_VAL(0);
755  if (hasKw) {
756  krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("start")), &base);
757  }
758  struct SimpleContext context = { base };
759  if (krk_unpackIterable(argv[0], &context, _sum_callback)) return NONE_VAL();
760  return context.base;
761 }
762 
763 static int _min_callback(void * context, const KrkValue * values, size_t count) {
764  struct SimpleContext * _context = context;
765  for (size_t i = 0; i < count; ++i) {
766  if (IS_KWARGS(_context->base)) _context->base = values[i];
767  else {
768  KrkValue check = krk_operator_lt(values[i], _context->base);
769  if (!IS_BOOLEAN(check)) return 1;
770  else if (AS_BOOLEAN(check) == 1) _context->base = values[i];
771  }
772  }
773  return 0;
774 }
775 
776 KRK_Function(min) {
777  FUNCTION_TAKES_AT_LEAST(1);
778  struct SimpleContext context = { KWARGS_VAL(0) };
779  if (argc > 1) {
780  if (_min_callback(&context, argv, argc)) return NONE_VAL();
781  } else {
782  if (krk_unpackIterable(argv[0], &context, _min_callback)) return NONE_VAL();
783  }
784  if (IS_KWARGS(context.base)) return krk_runtimeError(vm.exceptions->valueError, "empty argument to %s()", "min");
785  return context.base;
786 }
787 
788 static int _max_callback(void * context, const KrkValue * values, size_t count) {
789  struct SimpleContext * _context = context;
790  for (size_t i = 0; i < count; ++i) {
791  if (IS_KWARGS(_context->base)) _context->base = values[i];
792  else {
793  KrkValue check = krk_operator_gt(values[i], _context->base);
794  if (!IS_BOOLEAN(check)) return 1;
795  else if (AS_BOOLEAN(check) == 1) _context->base = values[i];
796  }
797  }
798  return 0;
799 }
800 
801 KRK_Function(max) {
802  FUNCTION_TAKES_AT_LEAST(1);
803  struct SimpleContext context = { KWARGS_VAL(0) };
804  if (argc > 1) {
805  if (_max_callback(&context, argv, argc)) return NONE_VAL();
806  } else {
807  if (krk_unpackIterable(argv[0], &context, _max_callback)) return NONE_VAL();
808  }
809  if (IS_KWARGS(context.base)) return krk_runtimeError(vm.exceptions->valueError, "empty argument to %s()", "max");
810  return context.base;
811 }
812 
813 KRK_Function(print) {
814  KrkValue sepVal;
815  KrkValue endVal;
816  char * sep = " "; size_t sepLen = 1;
817  char * end = "\n"; size_t endLen = 1;
818  if (hasKw) {
819  if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("sep")), &sepVal)) {
820  if (!IS_STRING(sepVal)) return krk_runtimeError(vm.exceptions->typeError, "'%s' should be a string, not '%T'", "sep", sepVal);
821  sep = AS_CSTRING(sepVal);
822  sepLen = AS_STRING(sepVal)->length;
823  }
824  if (krk_tableGet(AS_DICT(argv[argc]), OBJECT_VAL(S("end")), &endVal)) {
825  if (!IS_STRING(endVal)) return krk_runtimeError(vm.exceptions->typeError, "'%s' should be a string, not '%T'", "end", endVal);
826  end = AS_CSTRING(endVal);
827  endLen = AS_STRING(endVal)->length;
828  }
829  }
830  if (!argc) {
831  for (size_t j = 0; j < endLen; ++j) {
832  fputc(end[j], stdout);
833  }
834  }
835  for (int i = 0; i < argc; ++i) {
836  KrkValue printable = argv[i];
837  if (IS_STRING(printable)) { /* krk_printValue runs repr */
838  /* Make sure we handle nil bits correctly. */
839  for (size_t j = 0; j < AS_STRING(printable)->length; ++j) {
840  fputc(AS_CSTRING(printable)[j], stdout);
841  }
842  } else {
843  krk_printValue(stdout, printable);
844  if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return NONE_VAL();
845  }
846  char * thingToPrint = (i == argc - 1) ? end : sep;
847  for (size_t j = 0; j < ((i == argc - 1) ? endLen : sepLen); ++j) {
848  fputc(thingToPrint[j], stdout);
849  }
850  }
851 
852  return NONE_VAL();
853 }
854 
860 KRK_Function(globals) {
861  FUNCTION_TAKES_NONE();
862  /* Make a new empty dict */
863  KrkValue dict = krk_dict_of(0, NULL, 0);
864  krk_push(dict);
865  /* Copy the globals table into it */
867  krk_pop();
868 
869  return dict;
870 }
871 
877 KRK_Function(locals) {
878  FUNCTION_TAKES_AT_MOST(1);
879  KrkValue dict = krk_dict_of(0, NULL, 0);
880  krk_push(dict);
881 
882  int index = 1;
883  if (argc > 0 && IS_INTEGER(argv[0])) {
884  if (AS_INTEGER(argv[0]) < 1) {
885  return krk_runtimeError(vm.exceptions->indexError, "Frame index must be >= 1");
886  }
887  if (krk_currentThread.frameCount < (size_t)AS_INTEGER(argv[0])) {
888  return krk_runtimeError(vm.exceptions->indexError, "Frame index out of range");
889  }
890  index = AS_INTEGER(argv[0]);
891  }
892 
894  KrkCodeObject * func = frame->closure->function;
895  size_t offset = frame->ip - func->chunk.code;
896 
897  /* First, we'll populate with arguments */
898  size_t slot = 0;
899  for (short int i = 0; i < func->potentialPositionals; ++i) {
900  krk_tableSet(AS_DICT(dict),
901  func->positionalArgNames.values[i],
902  krk_currentThread.stack[frame->slots + slot]);
903  slot++;
904  }
905  if (func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
906  krk_tableSet(AS_DICT(dict),
908  krk_currentThread.stack[frame->slots + slot]);
909  slot++;
910  }
911  for (short int i = 0; i < func->keywordArgs; ++i) {
912  krk_tableSet(AS_DICT(dict),
913  func->keywordArgNames.values[i],
914  krk_currentThread.stack[frame->slots + slot]);
915  slot++;
916  }
917  if (func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
918  krk_tableSet(AS_DICT(dict),
919  func->keywordArgNames.values[func->keywordArgs],
920  krk_currentThread.stack[frame->slots + slot]);
921  slot++;
922  }
923  /* Now we need to find out what non-argument locals are valid... */
924  for (size_t i = 0; i < func->localNameCount; ++i) {
925  if (func->localNames[i].birthday <= offset &&
926  func->localNames[i].deathday >= offset) {
927  krk_tableSet(AS_DICT(dict),
928  OBJECT_VAL(func->localNames[i].name),
929  krk_currentThread.stack[frame->slots + func->localNames[i].id]);
930  }
931  }
932 
933  return krk_pop();
934 }
935 
936 KRK_Function(isinstance) {
937  FUNCTION_TAKES_EXACTLY(2);
938  if (IS_CLASS(argv[1])) {
939  return BOOLEAN_VAL(krk_isInstanceOf(argv[0], AS_CLASS(argv[1])));
940  } else if (IS_TUPLE(argv[1])) {
941  for (size_t i = 0; i < AS_TUPLE(argv[1])->values.count; ++i) {
942  if (IS_CLASS(AS_TUPLE(argv[1])->values.values[i]) && krk_isInstanceOf(argv[0], AS_CLASS(AS_TUPLE(argv[1])->values.values[i]))) {
943  return BOOLEAN_VAL(1);
944  }
945  }
946  return BOOLEAN_VAL(0);
947  } else {
948  return TYPE_ERROR(class or tuple,argv[1]);
949  }
950 }
951 
952 KRK_Function(issubclass) {
953  FUNCTION_TAKES_EXACTLY(2);
954  CHECK_ARG(0,class,KrkClass*,cls);
955  if (IS_CLASS(argv[1])) {
956  return BOOLEAN_VAL(krk_isSubClass(cls, AS_CLASS(argv[1])));
957  } else if (IS_TUPLE(argv[1])) {
958  for (size_t i = 0; i < AS_TUPLE(argv[1])->values.count; ++i) {
959  if (IS_CLASS(AS_TUPLE(argv[1])->values.values[i]) && krk_isSubClass(cls, AS_CLASS(AS_TUPLE(argv[1])->values.values[i]))) {
960  return BOOLEAN_VAL(1);
961  }
962  }
963  return BOOLEAN_VAL(0);
964  } else {
965  return TYPE_ERROR(class or tuple,argv[1]);
966  }
967 }
968 
969 #define IS_module(o) (IS_INSTANCE(o))
970 #define AS_module(o) (AS_INSTANCE(o))
971 
972 KRK_Method(module,__repr__) {
973  KrkValue name = NONE_VAL();
974  krk_tableGet(&self->fields, vm.specialMethodNames[METHOD_NAME], &name);
975 
976  if (!IS_STRING(name)) {
977  return OBJECT_VAL(S("<module>"));
978  }
979 
980  KrkValue file = NONE_VAL();
981  krk_tableGet(&self->fields, vm.specialMethodNames[METHOD_FILE], &file);
982 
983  struct StringBuilder sb = {0};
984 
985  if (!krk_pushStringBuilderFormat(&sb,"<module '%S' ", AS_STRING(name))) goto _error;
986 
987  if (IS_STRING(file)) {
988  if (!krk_pushStringBuilderFormat(&sb, "from %R>", file)) goto _error;
989  } else {
990  if (!krk_pushStringBuilderFormat(&sb, "(built-in)>")) goto _error;
991  }
992 
993  return krk_finishStringBuilder(&sb);
994 _error:
996  return NONE_VAL();
997 }
998 
999 #define IS_Helper(o) (krk_isInstanceOf(o, KRK_BASE_CLASS(Helper)))
1000 #define AS_Helper(o) (AS_INSTANCE(o))
1001 #define IS_LicenseReader(o) (krk_isInstanceOf(o, KRK_BASE_CLASS(LicenseReader)))
1002 #define AS_LicenseReader(o) (AS_INSTANCE(o))
1003 
1004 KRK_Method(Helper,__repr__) {
1005  return OBJECT_VAL(S("Type help() for more help, or help(obj) to describe an object."));
1006 }
1007 
1008 KRK_Method(Helper,__call__) {
1009  METHOD_TAKES_AT_MOST(1);
1010  if (!krk_doRecursiveModuleLoad(S("help"))) return NONE_VAL();
1011  KrkValue helpModule = krk_pop();
1012  KrkValue callable = NONE_VAL();
1013 
1014  if (argc == 2) {
1015  krk_tableGet(&AS_INSTANCE(helpModule)->fields, OBJECT_VAL(S("simple")), &callable);
1016  } else {
1017  krk_tableGet(&AS_INSTANCE(helpModule)->fields, OBJECT_VAL(S("interactive")), &callable);
1018  }
1019 
1020  if (!IS_NONE(callable)) {
1021  krk_push(callable);
1022  if (argc == 2) krk_push(argv[1]);
1023  return krk_callStack(argc == 2);
1024  }
1025 
1026  return krk_runtimeError(vm.exceptions->typeError, "unexpected error");
1027 }
1028 
1029 KRK_Method(LicenseReader,__repr__) {
1030  return OBJECT_VAL(S("Copyright 2020-2022 K. Lange <klange@toaruos.org>. Type `license()` for more information."));
1031 }
1032 
1033 KRK_Method(LicenseReader,__call__) {
1034  METHOD_TAKES_NONE();
1035  if (!krk_doRecursiveModuleLoad(S("help"))) return NONE_VAL();
1036  KrkValue helpModule = krk_pop();
1037 
1038  KrkValue text = NONE_VAL();
1039  krk_tableGet(&AS_INSTANCE(helpModule)->fields, OBJECT_VAL(S("__licenseText")), &text);
1040 
1041  if (IS_STRING(text)) {
1042  printf("%s\n", AS_CSTRING(text));
1043  return NONE_VAL();
1044  }
1045 
1046  return krk_runtimeError(vm.exceptions->typeError, "unexpected error");
1047 }
1048 
1049 #define IS_property(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(property)))
1050 #define AS_property(o) (AS_INSTANCE(o))
1051 
1052 struct Property {
1053  KrkInstance inst;
1054  KrkObj* fget;
1055  KrkObj* fset;
1056 };
1057 
1058 static void _property_gcscan(KrkInstance *_self) {
1059  struct Property * self = (struct Property*)_self;
1060  if (self->fget) krk_markObject(self->fget);
1061  if (self->fset) krk_markObject(self->fset);
1062 }
1063 
1064 KRK_Method(property,__init__) {
1065  METHOD_TAKES_AT_LEAST(1);
1066  METHOD_TAKES_AT_MOST(2); /* TODO fdel */
1067  krk_attachNamedValue(&self->fields, "fget", argv[1]);
1068 
1069  ((struct Property*)self)->fget = IS_OBJECT(argv[1]) ? AS_OBJECT(argv[1]) : NULL;
1070 
1071  /* Try to attach doc */
1072  if (IS_NATIVE(argv[1])) {
1073  krk_attachNamedValue(&self->fields, "__doc__",
1074  AS_NATIVE(argv[1])->doc ? OBJECT_VAL(krk_copyString(AS_NATIVE(argv[1])->doc, strlen(AS_NATIVE(argv[1])->doc))) : NONE_VAL());
1075  } else if (IS_CLOSURE(argv[1])) {
1076  krk_attachNamedValue(&self->fields, "__doc__",
1077  AS_CLOSURE(argv[1])->function->docstring ? OBJECT_VAL(AS_CLOSURE(argv[1])->function->docstring) : NONE_VAL());
1078  }
1079 
1080  /* Try to attach name */
1081  if (IS_NATIVE(argv[1])) {
1082  krk_attachNamedValue(&self->fields, "__name__",
1083  AS_NATIVE(argv[1])->name ? OBJECT_VAL(krk_copyString(AS_NATIVE(argv[1])->name, strlen(AS_NATIVE(argv[1])->name))) : NONE_VAL());
1084  } else if (IS_CLOSURE(argv[1])) {
1085  krk_attachNamedValue(&self->fields, "__name__",
1086  AS_CLOSURE(argv[1])->function->name ? OBJECT_VAL(AS_CLOSURE(argv[1])->function->name) : NONE_VAL());
1087  }
1088 
1089  if (argc > 2) {
1090  krk_attachNamedValue(&self->fields, "fset", argv[2]);
1091  ((struct Property*)self)->fset = IS_OBJECT(argv[2]) ? AS_OBJECT(argv[2]) : NULL;
1092  }
1093 
1094  return NONE_VAL();
1095 }
1096 
1097 KRK_Method(property,setter) {
1098  METHOD_TAKES_EXACTLY(1);
1099  krk_attachNamedValue(&self->fields, "fset", argv[1]);
1100  return argv[0]; /* Return the original property */
1101 }
1102 
1103 KRK_Method(property,__get__) {
1104  METHOD_TAKES_AT_LEAST(1); /* the owner */
1105 
1106  if (IS_NONE(argv[1])) return argv[0];
1107 
1108  struct Property * asProp = (struct Property *)self;
1109 
1110  if (asProp->fget) {
1111  krk_push(argv[1]);
1112  return krk_callDirect(asProp->fget, 1);
1113  }
1114 
1115  KrkValue fget;
1116  if (!krk_tableGet(&self->fields, OBJECT_VAL(S("fget")), &fget))
1117  return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", argv[0], "fget");
1118 
1119  krk_push(fget);
1120  krk_push(argv[1]);
1121  return krk_callStack(1);
1122 }
1123 
1124 KRK_Method(property,__set__) {
1125  METHOD_TAKES_EXACTLY(2); /* the owner and the value */
1126 
1127  struct Property * asProp = (struct Property *)self;
1128 
1129  if (asProp->fset) {
1130  krk_push(argv[1]);
1131  krk_push(argv[2]);
1132  return krk_callDirect(asProp->fset, 2);
1133  }
1134 
1135  KrkValue fset;
1136  if (krk_tableGet(&self->fields, OBJECT_VAL(S("fset")), &fset)) {
1137  krk_push(fset);
1138  krk_push(argv[1]);
1139  krk_push(argv[2]);
1140  return krk_callStack(2);
1141  }
1142 
1143  if (asProp->fget) {
1144  krk_push(argv[1]);
1145  krk_push(argv[2]);
1146  return krk_callDirect(asProp->fget, 2);
1147  }
1148 
1149  KrkValue fget;
1150  if (krk_tableGet(&self->fields, OBJECT_VAL(S("fget")), &fget)) {
1151  krk_push(fget);
1152  krk_push(argv[1]);
1153  krk_push(argv[2]);
1154  return krk_callStack(2);
1155  }
1156 
1157  return krk_runtimeError(vm.exceptions->attributeError, "attribute can not be set");
1158 }
1159 
1160 KRK_Method(property,__setattr__) {
1161  METHOD_TAKES_EXACTLY(2);
1162  if (!IS_STRING(argv[1])) return TYPE_ERROR(str,argv[1]);
1163  krk_instanceSetAttribute_wrapper(argv[0], AS_STRING(argv[1]), argv[2]);
1164  struct Property * asProp = (struct Property *)self;
1165 
1166  KrkValue fget = NONE_VAL();
1167  krk_tableGet(&self->fields, OBJECT_VAL(S("fget")), &fget);
1168  asProp->fget = (IS_CLOSURE(fget) || IS_NATIVE(fget)) ? AS_OBJECT(fget) : NULL;
1169 
1170  KrkValue fset = NONE_VAL();
1171  krk_tableGet(&self->fields, OBJECT_VAL(S("fset")), &fset);
1172  asProp->fset = (IS_CLOSURE(fset) || IS_NATIVE(fset)) ? AS_OBJECT(fset) : NULL;
1173 
1174  return argv[2];
1175 }
1176 
1183 KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, NativeFn function) {
1184  KrkNative * func = krk_newNative(function, name, 0);
1185  krk_push(OBJECT_VAL(func));
1186  KrkInstance * property = krk_newInstance(vm.baseClasses->propertyClass);
1187  krk_attachNamedObject(table, name, (KrkObj*)property);
1188  krk_attachNamedObject(&property->fields, "fget", (KrkObj*)func);
1189  krk_attachNamedObject(&property->fields, "fset", (KrkObj*)func);
1190  ((struct Property*)property)->fget = (KrkObj*)func;
1191  ((struct Property*)property)->fset = (KrkObj*)func;
1192  krk_pop();
1193  return func;
1194 }
1195 
1196 KRK_Function(id) {
1197  FUNCTION_TAKES_EXACTLY(1);
1198  if (!IS_OBJECT(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "'%T' has no identity", argv[0]);
1199  return INTEGER_VAL((size_t)AS_OBJECT(argv[0]));
1200 }
1201 
1202 KRK_Function(hash) {
1203  FUNCTION_TAKES_EXACTLY(1);
1204  uint32_t hashed;
1205  if (krk_hashValue(argv[0], &hashed)) return NONE_VAL();
1206  return INTEGER_VAL(hashed);
1207 }
1208 
1209 KRK_Function(next) {
1210  FUNCTION_TAKES_EXACTLY(1);
1211  krk_push(argv[0]);
1212  return krk_callStack(0);
1213 }
1214 
1215 KRK_Function(abs) {
1216  FUNCTION_TAKES_EXACTLY(1);
1217  if (IS_INTEGER(argv[0])) {
1218  krk_integer_type i = AS_INTEGER(argv[0]);
1219  return INTEGER_VAL(i >= 0 ? i : -i);
1220 #ifndef KRK_NO_FLOAT
1221  } else if (IS_FLOATING(argv[0])) {
1222  double i = AS_FLOATING(argv[0]);
1223  return FLOATING_VAL(i >= 0 ? i : -i);
1224 #endif
1225  } else {
1226  trySlowMethod(OBJECT_VAL(S("__abs__")));
1227  return krk_runtimeError(vm.exceptions->typeError, "bad operand type for 'abs()': '%T'", argv[0]);
1228  }
1229 }
1230 
1231 KRK_Function(format) {
1232  FUNCTION_TAKES_AT_LEAST(1);
1233  FUNCTION_TAKES_AT_MOST(2);
1234 
1235  KrkClass * type = krk_getType(argv[0]);
1236 
1237  if (!type->_format) {
1238  return krk_runtimeError(vm.exceptions->typeError, "'%T' has no __format__ method", argv[0]);
1239  }
1240 
1241  krk_push(argv[0]);
1242  if (argc < 2) krk_push(OBJECT_VAL(S("")));
1243  else krk_push(argv[1]);
1244 
1245  KrkValue result = krk_callDirect(type->_format, 2);
1246  if (!IS_STRING(result)) {
1247  return krk_runtimeError(vm.exceptions->typeError, "__format__ result was not a string");
1248  }
1249  return result;
1250 }
1251 
1252 static void module_sweep(KrkInstance * inst) {
1253 #ifndef KRK_STATIC_ONLY
1254  struct KrkModule * module = (struct KrkModule*)inst;
1255  if (module->libHandle) {
1256  dlClose(module->libHandle);
1257  }
1258 #endif
1259 }
1260 
1261 KRK_Function(__build_class__) {
1262  KrkValue func = NONE_VAL();
1263  KrkString * name = NULL;
1264  KrkClass * base = vm.baseClasses->objectClass;
1265  KrkValue metaclass = OBJECT_VAL(vm.baseClasses->typeClass);
1266 
1267  if (!krk_parseArgs("VO!|O!$V~",
1268  (const char*[]){"func","name","base","metaclass"},
1269  &func,
1270  vm.baseClasses->strClass, &name,
1271  vm.baseClasses->typeClass, &base,
1272  &metaclass)) {
1273  return NONE_VAL();
1274  }
1275 
1276  if (IS_CLASS(metaclass)) {
1277  KrkClass * basemeta = base->_class ? base->_class : vm.baseClasses->typeClass;
1278  if (krk_isSubClass(AS_CLASS(metaclass), basemeta)) {
1279  /* good to go */
1280  } else if (krk_isSubClass(basemeta, AS_CLASS(metaclass))) {
1281  /* take the more derived one */
1282  metaclass = OBJECT_VAL(basemeta);
1283  } else {
1284  return krk_runtimeError(vm.exceptions->typeError,
1285  "metaclass conflict: %S is not a subclass of %S", AS_CLASS(metaclass)->name, basemeta->name);
1286  }
1287  }
1288 
1289  /* Push function */
1290  krk_push(func);
1291 
1292  /* Call __prepare__ from metaclass */
1293  krk_push(krk_valueGetAttribute_default(metaclass, "__prepare__", KWARGS_VAL(0)));
1294 
1295  /* Bail early on exception */
1296  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
1297 
1298  if (IS_KWARGS(krk_peek(0))) {
1299  krk_pop();
1300  krk_push(krk_dict_of(0,NULL,0));
1301  } else {
1302  krk_push(OBJECT_VAL(name));
1303  krk_push(OBJECT_VAL(base));
1304  /* Do we have keywords? */
1305  int args = 2;
1306  if (hasKw) {
1307  args += 3;
1308  krk_push(KWARGS_VAL(KWARGS_DICT));
1309  krk_push(argv[argc]);
1310  krk_push(KWARGS_VAL(1));
1311  }
1312  krk_push(krk_callStack(args));
1313  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
1314  }
1315 
1316  /* Run the class function on it */
1317  krk_push(krk_callStack(1));
1318  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
1319 
1320  /* Now call the metaclass with the name, base, namespace, and kwds */
1321  int args = 3;
1322  krk_push(OBJECT_VAL(name));
1323  krk_push(OBJECT_VAL(base));
1324  krk_push(metaclass);
1325  krk_swap(3);
1326 
1327  if (hasKw) {
1328  args += 3;
1329  krk_push(KWARGS_VAL(KWARGS_DICT));
1330  krk_push(argv[argc]);
1331  krk_push(KWARGS_VAL(1));
1332  }
1333 
1334  krk_push(krk_callStack(args));
1335  if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
1336 
1337  /* Now assign the upvalue for the original function if it's a closure. */
1338  if (IS_CLOSURE(func)) {
1339  if (AS_CLOSURE(func)->upvalueCount && AS_CLOSURE(func)->upvalues[0]->location == -1 && IS_NONE(AS_CLOSURE(func)->upvalues[0]->closed)) {
1340  AS_CLOSURE(func)->upvalues[0]->closed = krk_peek(0);
1341  }
1342  }
1343 
1344  /* We're done, return the resulting class object. */
1345  return krk_pop();
1346 }
1347 
1348 #undef CURRENT_CTYPE
1349 #define CURRENT_CTYPE KrkUpvalue *
1350 #define IS_Cell(o) (krk_isObjType((o), KRK_OBJ_UPVALUE))
1351 #define AS_Cell(o) ((KrkUpvalue*)AS_OBJECT(o))
1352 
1353 KRK_StaticMethod(Cell,__new__) {
1354  KrkClass * _class = NULL;
1355  KrkValue contents = NONE_VAL();
1356  if (!krk_parseArgs("O!|V:Cell", (const char*[]){"cls","contents"}, KRK_BASE_CLASS(type), &_class, &contents)) {
1357  return NONE_VAL();
1358  }
1359  if (_class != KRK_BASE_CLASS(Cell)) {
1360  return krk_runtimeError(vm.exceptions->typeError, "can not assemble new Cell from %R", OBJECT_VAL(_class));
1361  }
1362 
1363  KrkUpvalue * out = krk_newUpvalue(-1);
1364  out->closed = contents;
1365  return OBJECT_VAL(out);
1366 }
1367 
1368 #define UPVALUE_LOCATION(upvalue) (upvalue->location == -1 ? &upvalue->closed : &upvalue->owner->stack[upvalue->location])
1369 KRK_Method(Cell,__repr__) {
1370  struct StringBuilder sb = {0};
1371 
1372  KrkValue contents = *UPVALUE_LOCATION(self);
1373 
1374  if (!krk_pushStringBuilderFormat(&sb,"<cell at %p: %T object", (void*)self, contents)) goto _error;
1375  if (IS_OBJECT(contents)) {
1376  if (!krk_pushStringBuilderFormat(&sb, " at %p>", (void*)AS_OBJECT(contents))) goto _error;
1377  } else {
1378  krk_pushStringBuilder(&sb,'>');
1379  }
1380 
1381  return krk_finishStringBuilder(&sb);
1382 
1383 _error:
1385  return NONE_VAL();
1386 }
1387 
1388 KRK_Method(Cell,cell_contents) {
1389  if (argc > 1) {
1390  *UPVALUE_LOCATION(self) = argv[1];
1391  }
1392  return *UPVALUE_LOCATION(self);
1393 }
1394 
1395 _noexport
1396 void _createAndBind_builtins(void) {
1397  vm.baseClasses->objectClass = krk_newClass(S("object"), NULL);
1398  krk_push(OBJECT_VAL(vm.baseClasses->objectClass));
1399 
1400  KrkClass * object = vm.baseClasses->objectClass;
1401  BIND_METHOD(object,__dir__);
1402  BIND_METHOD(object,__str__);
1403  BIND_METHOD(object,__hash__);
1404  BIND_METHOD(object,__eq__);
1405  BIND_METHOD(object,__format__);
1406  BIND_STATICMETHOD(object,__setattr__);
1407  BIND_STATICMETHOD(object,__new__);
1408  BIND_METHOD(object,__init__);
1409  BIND_CLASSMETHOD(object,__init_subclass__);
1410  krk_defineNative(&object->methods, "__repr__", FUNC_NAME(object,__str__));
1411  krk_finalizeClass(object);
1412  KRK_DOC(object,
1413  "@brief Base class for all types.\n\n"
1414  "The @c object base class provides the fallback implementations of methods like "
1415  "@ref object___dir__ \"__dir__\". All object and primitive types eventually inherit from @c object."
1416  );
1417 
1418  vm.baseClasses->moduleClass = krk_newClass(S("module"), vm.baseClasses->objectClass);
1419 
1420  KrkClass * module = vm.baseClasses->moduleClass;
1421  module->allocSize = sizeof(struct KrkModule);
1422  module->_ongcsweep = module_sweep;
1423 
1424  krk_push(OBJECT_VAL(module));
1425 
1426  BIND_METHOD(module,__repr__);
1427  krk_defineNative(&module->methods, "__str__", FUNC_NAME(module,__repr__));
1428  krk_finalizeClass(module);
1429  KRK_DOC(module, "Type of imported modules and packages.");
1430 
1431  vm.builtins = krk_newInstance(module);
1432  krk_attachNamedObject(&vm.modules, "builtins", (KrkObj*)vm.builtins);
1433  krk_attachNamedObject(&vm.builtins->fields, "object", (KrkObj*)vm.baseClasses->objectClass);
1434  krk_pop();
1435  krk_pop();
1436 
1437  krk_attachNamedObject(&vm.builtins->fields, "__name__", (KrkObj*)S("builtins"));
1438  krk_attachNamedValue(&vm.builtins->fields, "__file__", NONE_VAL());
1439  KRK_DOC(vm.builtins,
1440  "@brief Internal module containing built-in functions and classes.\n\n"
1441  "Classes and functions from the @c \\__builtins__ module are generally available from "
1442  "all global namespaces. Built-in names can still be shadowed by module-level globals "
1443  "and function-level locals, so none the names in this module are reserved. When "
1444  "a built-in name has been shadowed, the original can be referenced directly as "
1445  " @c \\__builtins__.name instead.\n\n"
1446  "Built-in names may be bound from several sources. Most come from the core interpreter "
1447  "directly, but some may come from loaded C extension modules or the interpreter binary. "
1448  "Kuroko source modules are also free to append new names to the built-in name space by "
1449  "attaching new properties to the @c \\__builtins__ instance."
1450  );
1451 
1452  KrkClass * property = ADD_BASE_CLASS(KRK_BASE_CLASS(property), "property", object);
1453  property->allocSize = sizeof(struct Property);
1454  property->_ongcscan = _property_gcscan;
1455  KRK_DOC(BIND_METHOD(property,__init__),
1456  "@brief Create a property object.\n"
1457  "@arguments fget,[fset]\n\n"
1458  "When a property object is obtained from an instance of the class in which it is defined, "
1459  "the function or method assigned to @p fget is called with the instance as an argument. "
1460  "If @p fset is provided, it will be called with the instance and a value when the property "
1461  "object is assigned to through an instance. For legacy compatibility reasons, a property "
1462  "object's @p fget method may also accept an additional argument to act as a setter if "
1463  "@p fset is not provided, but this functionality may be removed in the future.\n\n"
1464  "The typical use for @c property is as a decorator on methods in a class. See also "
1465  "@ref property_setter \"property.setter\" for the newer Python-style approach to decorating a companion "
1466  "setter method.");
1467  BIND_METHOD(property,__get__);
1468  BIND_METHOD(property,__set__);
1469  KRK_DOC(BIND_METHOD(property,setter),
1470  "@brief Assign the setter method of a property object.\n"
1471  "@arguments fset\n\n"
1472  "This should be used as a decorator from an existing property object as follows:\n\n"
1473  "```\n"
1474  "class Foo():\n"
1475  " @property\n"
1476  " def bar(self):\n"
1477  " return 42\n"
1478  " @bar.setter\n"
1479  " def bar(self, val):\n"
1480  " print('setting bar to',val)\n"
1481  "```\n"
1482  "Be sure to apply the decorator to a function or method with the same name, as this "
1483  "name will be used to assign the property to the class's attribute table; using a "
1484  "different name will create a duplicate alias.");
1485  krk_finalizeClass(property);
1486 
1487  /* Need to do this after creating 'property' */
1488  BIND_PROP(object,__class__);
1489 
1490  KrkClass * Helper = ADD_BASE_CLASS(KRK_BASE_CLASS(Helper), "Helper", object);
1491  KRK_DOC(Helper,
1492  "@brief Special object that prints a helpeful message.\n\n"
1493  "Object that prints help summary when passed to @ref repr.");
1494  KRK_DOC(BIND_METHOD(Helper,__call__),
1495  "@brief Prints help text.\n"
1496  "@arguments obj=None\n\n"
1497  "Prints the help documentation attached to @p obj or starts the interactive help system by "
1498  "importing the @ref mod_help module.");
1499  BIND_METHOD(Helper,__repr__);
1500  krk_finalizeClass(Helper);
1501  krk_attachNamedObject(&vm.builtins->fields, "help", (KrkObj*)krk_newInstance(Helper));
1502 
1503  KrkClass * LicenseReader = ADD_BASE_CLASS(KRK_BASE_CLASS(LicenseReader), "LicenseReader", object);
1504  KRK_DOC(LicenseReader, "Special object that prints Kuroko's copyright information when passed to @ref repr");
1505  KRK_DOC(BIND_METHOD(LicenseReader,__call__), "Print the full license statement.");
1506  BIND_METHOD(LicenseReader,__repr__);
1507  krk_finalizeClass(LicenseReader);
1508  krk_attachNamedObject(&vm.builtins->fields, "license", (KrkObj*)krk_newInstance(LicenseReader));
1509 
1510  KrkClass * map = ADD_BASE_CLASS(KRK_BASE_CLASS(map), "map", object);
1511  KRK_DOC(map, "Return an iterator that applies a function to a series of iterables");
1512  BIND_METHOD(map,__init__);
1513  BIND_METHOD(map,__iter__);
1514  BIND_METHOD(map,__call__);
1515  krk_finalizeClass(map);
1516 
1517  KrkClass * zip = ADD_BASE_CLASS(KRK_BASE_CLASS(zip), "zip", object);
1518  KRK_DOC(zip,
1519  "@brief Returns an iterator that produces tuples of the nth element of each passed iterable.\n"
1520  "@arguments *iterables\n\n"
1521  "Creates an iterator that returns a tuple of elements from each of @p iterables, until one "
1522  "of @p iterables is exhuasted.");
1523  BIND_METHOD(zip,__init__);
1524  BIND_METHOD(zip,__iter__);
1525  BIND_METHOD(zip,__call__);
1526  krk_finalizeClass(zip);
1527 
1528  KrkClass * filter = ADD_BASE_CLASS(KRK_BASE_CLASS(filter), "filter", object);
1529  KRK_DOC(filter, "Return an iterator that returns only the items from an iterable for which the given function returns true.");
1530  BIND_METHOD(filter,__init__);
1531  BIND_METHOD(filter,__iter__);
1532  BIND_METHOD(filter,__call__);
1533  krk_finalizeClass(filter);
1534 
1535  KrkClass * enumerate = ADD_BASE_CLASS(KRK_BASE_CLASS(enumerate), "enumerate", object);
1536  KRK_DOC(enumerate, "Return an iterator that produces a tuple with a count the iterated values of the passed iteratable.");
1537  BIND_METHOD(enumerate,__init__);
1538  BIND_METHOD(enumerate,__iter__);
1539  BIND_METHOD(enumerate,__call__);
1540  krk_finalizeClass(enumerate);
1541 
1542  KrkClass * Cell = ADD_BASE_CLASS(KRK_BASE_CLASS(Cell), "Cell", object);
1543  Cell->allocSize = 0;
1544  Cell->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
1545  BIND_STATICMETHOD(Cell,__new__);
1546  BIND_METHOD(Cell,__repr__);
1547  BIND_PROP(Cell,cell_contents);
1548  krk_finalizeClass(Cell);
1549 
1550  BUILTIN_FUNCTION("isinstance", FUNC_NAME(krk,isinstance),
1551  "@brief Check if an object is an instance of a type.\n"
1552  "@arguments inst, cls\n\n"
1553  "Determine if an object @p inst is an instance of the given class @p cls or one if its subclasses. "
1554  "@p cls may be a single class or a tuple of classes.");
1555  BUILTIN_FUNCTION("issubclass", FUNC_NAME(krk,issubclass),
1556  "@brief Check if a class is a subclass of a type.\n"
1557  "@arguments cls, clsinfo\n\n"
1558  "Determine if the class @p cls is a subclass of the class @p clsinfo. @p clsinfo may be a single "
1559  "class or a tuple of classes.");
1560  BUILTIN_FUNCTION("globals", FUNC_NAME(krk,globals),
1561  "@brief Update and a return a mapping of names in the global namespace.\n\n"
1562  "Produces a dict mapping all of the names of the current globals namespace to their values. "
1563  "Updating this dict has no meaning, but modifying mutable values within it can affect the global namespace.");
1564  BUILTIN_FUNCTION("locals", FUNC_NAME(krk,locals),
1565  "@brief Update and return a mapping of names in the current local scope.\n"
1566  "@arguments callDepth=1\n\n"
1567  "Produces a dict mapping the names of the requested locals scope to their current stack values. "
1568  "If @p callDepth is provided, the locals of an outer call frame will be returned. If the requested "
1569  "call depth is out of range, an exception will be raised.");
1570  BUILTIN_FUNCTION("dir", FUNC_NAME(krk,dir),
1571  "@brief Return a list of known property names for a given object.\n"
1572  "@arguments [obj]\n\n"
1573  "Uses various internal methods to collect a list of property names of @p obj, returning "
1574  "that list sorted lexicographically. If no argument is given, the returned list will "
1575  "be the valid global names in the calling scope.");
1576  BUILTIN_FUNCTION("len", FUNC_NAME(krk,len),
1577  "@brief Return the length of a given sequence object.\n"
1578  "@arguments seq\n\n"
1579  "Returns the length of the sequence object @p seq, which must implement @c __len__.");
1580  BUILTIN_FUNCTION("repr", FUNC_NAME(krk,repr),
1581  "@brief Produce a string representation of the given object.\n"
1582  "@arguments val\n\n"
1583  "Return a string representation of the given object through its @c __repr__ method. "
1584  "@c repr strings should convey all information needed to recreate the object, if this is possible.");
1585  BUILTIN_FUNCTION("print", FUNC_NAME(krk,print),
1586  "@brief Print text to the standard output.\n"
1587  "@arguments *args,sep=' ',end='\\n'\n\n"
1588  "Prints the string representation of each argument to the standard output. "
1589  "The keyword argument @p sep specifies the string to print between values. "
1590  "The keyword argument @p end specifies the string to print after all of the values have been printed.");
1591  BUILTIN_FUNCTION("ord", FUNC_NAME(krk,ord),
1592  "@brief Obtain the ordinal integer value of a codepoint or byte.\n"
1593  "@arguments char\n\n"
1594  "Returns the integer codepoint value of a single-character string @p char.");
1595  BUILTIN_FUNCTION("chr", FUNC_NAME(krk,chr),
1596  "@brief Convert an integer codepoint to its string representation.\n"
1597  "@arguments codepoint\n\n"
1598  "Creates a single-codepoint string with the character represented by the integer codepoint @p codepoint.");
1599  BUILTIN_FUNCTION("hex", FUNC_NAME(krk,hex),
1600  "@brief Convert an integer value to a hexadecimal string.\n"
1601  "@arguments i\n\n"
1602  "Returns a string representation of @p i in hexadecimal, with a leading @c 0x.");
1603  BUILTIN_FUNCTION("oct", FUNC_NAME(krk,oct),
1604  "@brief Convert an integer value to an octal string.\n"
1605  "@arguments i\n\n"
1606  "Returns a string representation of @p i in octal, with a leading @c 0o.");
1607  BUILTIN_FUNCTION("any", FUNC_NAME(krk,any),
1608  "@brief Returns True if at least one element in the given iterable is truthy, False otherwise.\n"
1609  "@arguments iterable");
1610  BUILTIN_FUNCTION("all", FUNC_NAME(krk,all),
1611  "@brief Returns True if every element in the given iterable is truthy, False otherwise.\n"
1612  "@arguments iterable");
1613  BUILTIN_FUNCTION("getattr", FUNC_NAME(krk,getattr),
1614  "@brief Perform attribute lookup on an object using a string.\n"
1615  "@arguments obj,attribute,[default]\n\n"
1616  "Obtains the attributed named @p attribute from the object @p obj, if such an "
1617  "attribute exists. Attribute lookup ordering is complex and includes direct "
1618  "attribute tables of instances, dynamic attributes from classes, and so on. "
1619  "The use of @c getattr is equivalent to a dotted access. If @p attribute refers "
1620  "to a method of @p obj's class, a bound method will be obtained. If @p default "
1621  "is provided then the value supplied will be returned in the case where @p obj "
1622  "does not have an attribute named @p attribute, otherwise an @ref AttributeError "
1623  "will be raised.");
1624  BUILTIN_FUNCTION("setattr", FUNC_NAME(krk,setattr),
1625  "@brief Set an attribute of an object using a string name.\n"
1626  "@arguments obj,attribute,value\n\n"
1627  "Sets the attribute named by @p attribute of the object @p obj to @p value. "
1628  "If @p attribute refers to a @ref property object or other descriptor, the "
1629  "descriptor's @c \\__set__ method will be called. If @p obj is a class, instance, "
1630  "or other type with its own attribute table, then the field will be updated. If "
1631  "@p obj is a type without an attribute table and no class property provides an "
1632  "overriding setter for @p attribute, an @ref AttributeError will be raised.");
1633  BUILTIN_FUNCTION("hasattr", FUNC_NAME(krk,hasattr),
1634  "@brief Determines if an object has an attribute.\n"
1635  "@arguments obj,attribute\n\n"
1636  "Uses @ref getattr to determine if @p obj has an attribute named @p attribute.");
1637  BUILTIN_FUNCTION("delattr", FUNC_NAME(krk,delattr),
1638  "@brief Delete an attribute by name.\n"
1639  "@arguments obj,attribute\n\n"
1640  "Deletes the attribute @p attribute from @p obj.");
1641  BUILTIN_FUNCTION("sum", FUNC_NAME(krk,sum),
1642  "@brief add the elements of an iterable.\n"
1643  "@arguments iterable,start=0\n\n"
1644  "Continuously adds all of the elements from @p iterable to @p start and returns the result "
1645  "when @p iterable has been exhausted.");
1646  BUILTIN_FUNCTION("min", FUNC_NAME(krk,min),
1647  "@brief Return the lowest value in an iterable or the passed arguments.\n"
1648  "@arguments iterable");
1649  BUILTIN_FUNCTION("max", FUNC_NAME(krk,max),
1650  "@brief Return the highest value in an iterable or the passed arguments.\n"
1651  "@arguments iterable");
1652  BUILTIN_FUNCTION("id", FUNC_NAME(krk,id),
1653  "@brief Returns the identity of an object.\n"
1654  "@arguments val\n\n"
1655  "Returns the internal identity for @p val. Note that not all objects have "
1656  "identities; primitive values such as @c int or @c float do not have identities. "
1657  "Internally, this is the pointer value for a heap object, but this is an implementation detail.");
1658  BUILTIN_FUNCTION("hash", FUNC_NAME(krk,hash),
1659  "@brief Returns the hash of a value, used for table indexing.\n"
1660  "@arguments val\n\n"
1661  "If @p val is hashable, its hash value will be calculated if necessary and returned. "
1662  "If @p val is not hashable, @ref TypeError will be raised.");
1663  BUILTIN_FUNCTION("bin", FUNC_NAME(krk,bin),
1664  "@brief Convert an integer value to a binary string.\n"
1665  "@arguments i\n\n"
1666  "Produces a string representation of @p i in binary, with a leading @p 0b.");
1667  BUILTIN_FUNCTION("next", FUNC_NAME(krk,next),
1668  "@brief Compatibility function. Calls an iterable.\n"
1669  "@arguments iterable");
1670  BUILTIN_FUNCTION("abs", FUNC_NAME(krk,abs),
1671  "@brief Obtain the absolute value of a numeric.\n"
1672  "@arguments iterable");
1673  BUILTIN_FUNCTION("format", FUNC_NAME(krk,format),
1674  "@brief Format a value for string printing.\n"
1675  "@arguments value[,format_spec]");
1676  BUILTIN_FUNCTION("__build_class__", FUNC_NAME(krk,__build_class__),
1677  "@brief Internal function to build a type object.\n"
1678  "@arguments func, name, base=object, metaclass=type");
1679 }
1680 
Functions for debugging bytecode execution.
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Definition: exceptions.c:445
Functions for dealing with garbage collection and memory allocation.
void krk_markObject(KrkObj *object)
During a GC scan cycle, mark an object as used.
Definition: memory.c:316
Internal header.
Represents a managed call state in a VM thread.
Definition: vm.h:46
size_t slots
Definition: vm.h:49
KrkTable * globals
Definition: vm.h:51
KrkClosure * closure
Definition: vm.h:47
uint8_t * ip
Definition: vm.h:48
Type object.
Definition: object.h:189
KrkObj * _tostr
__str__ Called to produce a string from an instance
Definition: object.h:204
KrkCleanupCallback _ongcsweep
C function to call when the garbage collector is discarding an instance of this class.
Definition: object.h:198
KrkClass * krk_newClass(KrkString *name, KrkClass *base)
Create a new class object.
Definition: object.c:320
KrkObj * _reprer
__repr__ Called to create a reproducible string representation of an instance
Definition: object.h:203
KrkString * name
Name of the class.
Definition: object.h:193
struct KrkClass * base
Pointer to base class implementation.
Definition: object.h:195
KrkObj * _init
__init__ Implicitly called when an instance is created
Definition: object.h:206
KrkObj * _len
__len__ Generally called by len() but may be used to determine truthiness
Definition: object.h:208
size_t allocSize
Size to allocate when creating instances of this class.
Definition: object.h:196
KrkObj obj
Base.
Definition: object.h:190
KrkObj * _iter
__iter__ Called by for ... in ..., etc.
Definition: object.h:212
KrkTable methods
General attributes table.
Definition: object.h:192
KrkObj * _dir
__dir__ Overrides normal behavior for dir()
Definition: object.h:214
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
struct KrkClass * _class
Metaclass.
Definition: object.h:191
Function object.
Definition: object.h:169
KrkCodeObject * function
The codeobject containing the bytecode run when this function is called.
Definition: object.h:171
Code object.
Definition: object.h:144
unsigned short potentialPositionals
Precalculated positional arguments for complex argument processing.
Definition: object.h:148
KrkChunk chunk
Bytecode data.
Definition: object.h:151
KrkValueArray positionalArgNames
Array of names for positional arguments (and *args)
Definition: object.h:154
KrkLocalEntry * localNames
Stores the names of local variables used in the function, for debugging.
Definition: object.h:158
unsigned short keywordArgs
Arity of keyword (default) arguments.
Definition: object.h:147
KrkObj obj
Base.
Definition: object.h:145
KrkValueArray keywordArgNames
Array of names for keyword-only arguments (and **kwargs)
Definition: object.h:155
size_t localNameCount
Number of entries in localNames.
Definition: object.h:157
KrkValue krk_dict_of(int argc, const KrkValue argv[], int hasKw)
Create a dict object.
Definition: obj_dict.c:11
An object of a class.
Definition: object.h:255
KrkInstance * krk_newInstance(KrkClass *_class)
Create a new instance of the given class.
Definition: object.c:339
KrkClass * _class
Type.
Definition: object.h:257
KrkValue krk_list_of(int argc, const KrkValue argv[], int hasKw)
Create a list object.
Definition: obj_list.c:30
size_t birthday
Instruction offset that this local name became valid on.
Definition: object.h:131
KrkString * name
Name of the local.
Definition: object.h:133
size_t id
Local ID as used by opcodes; offset from the frame's stack base.
Definition: object.h:130
size_t deathday
Instruction offset that this local name becomes invalid on.
Definition: object.h:132
Representation of a loaded module.
Definition: object.h:359
Managed binding to a C function.
Definition: object.h:283
KrkNative * krk_newNative(NativeFn function, const char *name, int type)
Create a native function binding object.
Definition: object.c:277
The most basic object type.
Definition: object.h:41
uint32_t hash
Cached hash value for table keys.
Definition: object.h:44
uint16_t flags
General object flags, mostly related to garbage collection.
Definition: object.h:43
uint16_t type
Tag indicating core type.
Definition: object.h:42
Immutable sequence of Unicode codepoints.
Definition: object.h:93
void * krk_unicodeString(KrkString *string)
Ensure that a codepoint representation of a string is available.
Definition: object.c:152
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
Definition: object.c:221
char * chars
UTF8 canonical data.
Definition: object.h:97
One (key,value) pair in a table.
Definition: table.h:20
Simple hash table of arbitrary keys to values.
Definition: table.h:28
int krk_tableGet(KrkTable *table, KrkValue key, KrkValue *value)
Obtain the value associated with a key in a table.
Definition: table.c:178
int krk_tableSet(KrkTable *table, KrkValue key, KrkValue value)
Assign a value to a key in a table.
Definition: table.c:145
void krk_attachNamedObject(KrkTable *table, const char name[], KrkObj *obj)
Attach an object to an attribute table.
Definition: vm.c:839
KrkNative * krk_defineNative(KrkTable *table, const char *name, NativeFn function)
Attach a native C function to an attribute table.
Definition: vm.c:194
void krk_attachNamedValue(KrkTable *table, const char name[], KrkValue obj)
Attach a value to an attribute table.
Definition: vm.c:825
KrkNative * krk_defineNativeProperty(KrkTable *table, const char *name, NativeFn func)
Attach a native dynamic property to an attribute table.
Definition: builtins.c:1183
void krk_tableAddAll(KrkTable *from, KrkTable *to)
Add all key-value pairs from 'from' into 'to'.
Definition: table.c:169
size_t frameCount
Definition: vm.h:165
KrkValue * stack
Definition: vm.h:167
KrkValue * stackTop
Definition: vm.h:168
KrkCallFrame * frames
Definition: vm.h:164
int flags
Definition: vm.h:174
Immutable sequence of arbitrary values.
Definition: object.h:297
KrkValueArray values
Stores the length, capacity, and actual values of the tuple.
Definition: object.h:299
KrkTuple * krk_newTuple(size_t length)
Create a new tuple.
Definition: object.c:353
Storage for values referenced from nested functions.
Definition: object.h:115
KrkValue closed
Heap storage for closed value.
Definition: object.h:118
KrkUpvalue * krk_newUpvalue(int slot)
Create an upvalue slot.
Definition: object.c:311
KrkValue * values
Definition: value.h:73
void krk_writeValueArray(KrkValueArray *array, KrkValue value)
Add a value to a value array.
Definition: value.c:17
size_t count
Definition: value.h:72
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.
Definition: vm.c:317
int krk_valuesEqual(KrkValue a, KrkValue b)
Compare two values for equality.
void krk_printValue(FILE *f, KrkValue value)
Print a string representation of a value.
Definition: value.c:33
int krk_valuesSame(KrkValue a, KrkValue b)
Compare two values by identity.
Definition: value.c:151
KrkClass * krk_getType(KrkValue value)
Get the class representing a value.
Definition: vm.c:275
int krk_isFalsey(KrkValue value)
Determine the truth of a value.
Definition: vm.c:852
int krk_hashValue(KrkValue value, uint32_t *hashOut)
Calculate the hash for a value.
Definition: table.c:25
KrkValue krk_set_of(int argc, const KrkValue argv[], int hasKw)
Create a set object.
Definition: obj_set.c:346
Inline flexible string array.
Definition: util.h:150
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
Definition: util.h:348
KrkValue krk_discardStringBuilder(struct StringBuilder *sb)
Discard the contents of a string builder.
Definition: obj_str.c:1091
int krk_unpackIterable(KrkValue iterable, void *context, int callback(void *, const KrkValue *, size_t))
Unpack an iterable.
Definition: builtins.c:380
KrkValue krk_finishStringBuilder(struct StringBuilder *sb)
Finalize a string builder into a string object.
Definition: obj_str.c:1079
void krk_pushStringBuilder(struct StringBuilder *sb, char c)
Add a character to the end of a string builder.
Definition: obj_str.c:1050
#define KRK_DOC(thing, text)
Attach documentation to a thing of various types.
Definition: util.h:292
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
int krk_getAttribute(KrkString *name)
Implementation of the GET_PROPERTY instruction.
Definition: vm.c:1801
int krk_setAttribute(KrkString *name)
Implementation of the SET_PROPERTY instruction.
Definition: vm.c:1936
KrkValue krk_callStack(int argCount)
Call a callable on the stack with argCount arguments.
Definition: vm.c:763
#define vm
Convenience macro for namespacing.
Definition: vm.h:267
int krk_doRecursiveModuleLoad(KrkString *name)
Load a module by a dotted name.
Definition: vm.c:1610
int krk_delAttribute(KrkString *name)
Implementation of the DEL_PROPERTY instruction.
Definition: vm.c:1861
KrkValue krk_operator_lt(KrkValue, KrkValue)
Compare two values, returning True if the left is less than the right.
KrkValue krk_pop(void)
Pop the top of the stack.
Definition: vm.c:170
threadLocal KrkThreadState krk_currentThread
Thread-local VM state.
KrkValue krk_valueGetAttribute_default(KrkValue value, char *name, KrkValue defaultVal)
See krk_valueGetAttribute.
Definition: vm.c:1816
void krk_swap(int distance)
Swap the top of the stack of the value distance slots down.
Definition: vm.c:184
KrkValue krk_dirObject(int argc, const KrkValue argv[], int hasKw)
Obtain a list of properties for an object.
Definition: builtins.c:13
void krk_push(KrkValue value)
Push a stack value.
Definition: vm.c:157
KrkValue krk_callDirect(KrkObj *callable, int argCount)
Call a closure or native function with argCount arguments.
Definition: vm.c:771
KrkValue krk_instanceSetAttribute_wrapper(KrkValue owner, KrkString *name, KrkValue to)
Set an attribute of an instance object, bypassing __setattr__.
Definition: vm.c:1898
KrkValue krk_peek(int distance)
Peek down from the top of the stack.
Definition: vm.c:178
KrkValue krk_operator_gt(KrkValue, KrkValue)
Compare to values, returning True if the left is greater than the right.