obj_function.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 /* Check for and return the name of a native function as a string object */
9 static KrkValue nativeFunctionName(KrkValue func) {
10  const char * string = ((KrkNative*)AS_OBJECT(func))->name;
11  if (!string) return OBJECT_VAL(S("<unnamed>"));
12  size_t len = strlen(string);
13  return OBJECT_VAL(krk_copyString(string,len));
14 }
15 
16 static KrkTuple * functionArgs(KrkCodeObject * _self) {
17  KrkTuple * tuple = krk_newTuple(_self->totalArguments);
18  krk_push(OBJECT_VAL(tuple));
19 
20  for (short i = 0; i < _self->potentialPositionals; ++i) {
21  tuple->values.values[tuple->values.count++] = _self->positionalArgNames.values[i];
22  }
23 
24  if (_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
25  tuple->values.values[tuple->values.count++] = krk_stringFromFormat("*%S", AS_STRING(_self->positionalArgNames.values[_self->potentialPositionals]));
26  }
27 
28  for (short i = 0; i < _self->keywordArgs; ++i) {
29  tuple->values.values[tuple->values.count++] = krk_stringFromFormat("%S=", AS_STRING(_self->keywordArgNames.values[i]));
30  }
31 
32  if (_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
33  tuple->values.values[tuple->values.count++] = krk_stringFromFormat("**%S", AS_STRING(_self->keywordArgNames.values[_self->keywordArgs]));
34  }
35 
36  krk_pop();
37  return tuple;
38 }
39 
40 #define IS_method(o) IS_BOUND_METHOD(o)
41 #define IS_function(o) (IS_CLOSURE(o)|IS_NATIVE(o))
42 
43 #define AS_method(o) AS_BOUND_METHOD(o)
44 #define AS_function(o) (o)
45 
46 #define CURRENT_NAME self
47 #define CURRENT_CTYPE KrkValue
48 
49 KRK_StaticMethod(function,__new__) {
50  METHOD_TAKES_EXACTLY(3);
51  CHECK_ARG(1,codeobject,KrkCodeObject*,code);
52 
53  if (!IS_INSTANCE(argv[3]))
54  return TYPE_ERROR(dict or instance object,argv[3]);
55 
56  if (IS_CLOSURE(argv[2]) && AS_CLOSURE(argv[2])->upvalueCount == code->upvalueCount) {
57  /* Option 1: A function with the same upvalue count. Copy the upvalues exactly.
58  * As an example, this can be a lambda with a bunch of unused upvalue
59  * references - like "lambda: a, b, c". These variables will be captured
60  * using the relevant scope - and we don't have to care about whether
61  * they were properly marked, because the compiler took care of it
62  * when the lambda was compiled.
63  */
64  krk_push(OBJECT_VAL(krk_newClosure(code, argv[3])));
65  memcpy(AS_CLOSURE(krk_peek(0))->upvalues, AS_CLOSURE(argv[2])->upvalues,
66  sizeof(KrkUpvalue*) * code->upvalueCount);
67  return krk_pop();
68  } else if (IS_TUPLE(argv[2]) && AS_TUPLE(argv[2])->values.count == code->upvalueCount) {
69  /* Option 2: A tuple of values. New upvalue containers are built for each value,
70  * but they are immediately closed with the value in the tuple. They
71  * exist independently for this closure instance, and are not shared with
72  * any other closures.
73  */
74  krk_push(OBJECT_VAL(krk_newClosure(code, argv[3])));
75  for (size_t i = 0; i < code->upvalueCount; ++i) {
76  AS_CLOSURE(krk_peek(0))->upvalues[i] = krk_newUpvalue(-1);
77  AS_CLOSURE(krk_peek(0))->upvalues[i]->closed = AS_TUPLE(argv[2])->values.values[i];
78  }
79  return krk_pop();
80  }
81 
82  return TYPE_ERROR(managed function with equal upvalue count or tuple,argv[2]);
83 }
84 
85 KRK_Method(function,__doc__) {
86  ATTRIBUTE_NOT_ASSIGNABLE();
87 
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);
92  }
93 
94  return NONE_VAL();
95 }
96 
97 KRK_Method(function,__name__) {
98  ATTRIBUTE_NOT_ASSIGNABLE();
99 
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);
104  }
105 
106  return OBJECT_VAL(S(""));
107 }
108 
109 KRK_Method(function,__qualname__) {
110  ATTRIBUTE_NOT_ASSIGNABLE();
111 
112  if (IS_CLOSURE(self) && AS_CLOSURE(self)->function->qualname) {
113  return OBJECT_VAL(AS_CLOSURE(self)->function->qualname);
114  }
115 
116  return NONE_VAL();
117 }
118 
119 KRK_Method(function,__globals__) {
120  ATTRIBUTE_NOT_ASSIGNABLE();
121 
122  if (IS_CLOSURE(self)) {
123  return AS_CLOSURE(self)->globalsOwner;
124  }
125 
126  return NONE_VAL();
127 }
128 
129 KRK_Method(function,_ip_to_line) {
130  METHOD_TAKES_EXACTLY(1);
131  CHECK_ARG(1,int,krk_integer_type,ip);
132 
133  if (!IS_CLOSURE(self)) return NONE_VAL();
134 
135  size_t line = krk_lineNumber(&AS_CLOSURE(self)->function->chunk, ip);
136 
137  return INTEGER_VAL(line);
138 }
139 
140 KRK_Method(function,__str__) {
141  METHOD_TAKES_NONE();
142 
143  /* Do we have a qualified name? */
144  KrkValue name = FUNC_NAME(function,__qualname__)(1,&self,0);
145  if (IS_NONE(name)) {
146  name = FUNC_NAME(function,__name__)(1,&self,0);
147  }
148 
149  if (!IS_STRING(name)) name = OBJECT_VAL(S("<unnamed>"));
150 
151  krk_push(name);
152 
153  struct StringBuilder sb = {0};
154  krk_pushStringBuilderFormat(&sb, "<function %S at %p>", AS_STRING(name), (void*)AS_OBJECT(self));
155 
156  krk_pop();
157 
158  return krk_finishStringBuilder(&sb);
159 }
160 
161 KRK_Method(function,__file__) {
162  ATTRIBUTE_NOT_ASSIGNABLE();
163 
164  if (IS_NATIVE(self)) return OBJECT_VAL(S("<builtin>"));
165 
166  return AS_CLOSURE(self)->function->chunk.filename ?
167  OBJECT_VAL(AS_CLOSURE(self)->function->chunk.filename) :
168  OBJECT_VAL(S(""));
169 }
170 
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);
176 }
177 
178 KRK_Method(function,__annotations__) {
179  ATTRIBUTE_NOT_ASSIGNABLE();
180  if (!IS_CLOSURE(self)) return NONE_VAL();
181  return AS_CLOSURE(self)->annotations;
182 }
183 
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);
188 }
189 
190 KRK_Method(function,__closure__) {
191  ATTRIBUTE_NOT_ASSIGNABLE();
192  if (!IS_CLOSURE(self)) {
193  return OBJECT_VAL(krk_newTuple(0));
194  }
195 
196  size_t cnt = AS_CLOSURE(self)->upvalueCount;
197  KrkTuple * out = krk_newTuple(cnt);
198  krk_push(OBJECT_VAL(out));
199  for (size_t i = 0; i < cnt; ++i) {
200  out->values.values[out->values.count++] = OBJECT_VAL(AS_CLOSURE(self)->upvalues[i]);
201  }
202 
203  return krk_pop();
204 }
205 
206 #undef CURRENT_CTYPE
207 #define CURRENT_CTYPE KrkCodeObject*
208 
209 KRK_StaticMethod(codeobject,__new__) {
210  return krk_runtimeError(vm.exceptions->typeError, "codeobject object is not instantiable");
211 }
212 
213 KRK_Method(codeobject,__name__) {
214  ATTRIBUTE_NOT_ASSIGNABLE();
215  return self->name ? OBJECT_VAL(self->name) : OBJECT_VAL(S(""));
216 }
217 
218 KRK_Method(codeobject,__str__) {
219  METHOD_TAKES_NONE();
220  KrkValue s = FUNC_NAME(codeobject,__name__)(1,argv,0);
221  if (!IS_STRING(s)) return NONE_VAL();
222  krk_push(s);
223 
224  struct StringBuilder sb = {0};
225  krk_pushStringBuilderFormat(&sb, "<codeobject %S at %p>", AS_STRING(s), (void*)self);
226 
227  krk_pop();
228 
229  return krk_finishStringBuilder(&sb);
230 }
231 
232 KRK_Method(codeobject,_ip_to_line) {
233  METHOD_TAKES_EXACTLY(1);
234  CHECK_ARG(1,int,krk_integer_type,ip);
235  size_t line = krk_lineNumber(&self->chunk, ip);
236  return INTEGER_VAL(line);
237 }
238 
239 KRK_Method(codeobject,__constants__) {
240  ATTRIBUTE_NOT_ASSIGNABLE();
241  krk_push(OBJECT_VAL(krk_newTuple(self->chunk.constants.count)));
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;
246  return krk_pop();
247 }
248 
249 KRK_Method(codeobject,co_code) {
250  return OBJECT_VAL(krk_newBytes(self->chunk.count, self->chunk.code));
251 }
252 
253 KRK_Method(codeobject,co_argcount) {
254  return INTEGER_VAL(self->potentialPositionals);
255 }
256 
257 KRK_Method(codeobject,co_kwonlyargcount) {
258  return INTEGER_VAL(self->keywordArgs);
259 }
260 
261 KRK_Method(codeobject,co_posonlyargcount) {
262  /* This is tricky because we don't store it anywhere */
263  for (size_t i = 0; i < self->potentialPositionals; ++i) {
264  if (!IS_NONE(self->positionalArgNames.values[i])) return INTEGER_VAL(i);
265  }
266  return INTEGER_VAL(0);
267 }
268 
269 KRK_Method(codeobject,__locals__) {
270  krk_push(OBJECT_VAL(krk_newTuple(self->localNameCount)));
271  for (size_t i = 0; i < self->localNameCount; ++i) {
272  krk_push(OBJECT_VAL(krk_newTuple(4)));
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);
277  AS_TUPLE(krk_peek(1))->values.values[AS_TUPLE(krk_peek(1))->values.count++] = krk_peek(0);
278  krk_pop();
279  }
280  return krk_pop();
281 }
282 
283 /* Python-compatibility */
284 KRK_Method(codeobject,co_flags) {
285  ATTRIBUTE_NOT_ASSIGNABLE();
286 
287  int out = 0;
288 
289  /* For compatibility with Python, mostly because these are specified
290  * in at least one doc page with their raw values, we convert
291  * our flags to the useful CPython flag values... */
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;
296 
297  return INTEGER_VAL(out);
298 }
299 
300 KRK_Method(codeobject,__args__) {
301  ATTRIBUTE_NOT_ASSIGNABLE();
302  KrkTuple * tuple = functionArgs(self);
303  return OBJECT_VAL(tuple);
304 }
305 
306 
307 #undef CURRENT_CTYPE
308 #define CURRENT_CTYPE KrkBoundMethod*
309 
310 /* __init__ here will be called with a dummy instance as argv[0]; avoid
311  * complications with method argument checking by not using KRK_METHOD. */
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");
315  return OBJECT_VAL(krk_newBoundMethod(argv[2],AS_OBJECT(argv[1])));
316 }
317 
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("?"));
321 }
322 
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("?"));
326 }
327 
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("?"));
331 }
332 
333 KRK_Method(method,__str__) {
334  METHOD_TAKES_NONE();
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();
338  krk_push(s);
339 
340  struct StringBuilder sb = {0};
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));
343  krk_pushStringBuilder(&sb, '>');
344 
345  krk_pop();
346 
347  return krk_finishStringBuilder(&sb);
348 }
349 
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("?"));
353 }
354 
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("?"));
358 }
359 
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("?"));
363 }
364 
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("?"));
368 }
369 
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("?"));
373 }
374 
375 KRK_Method(method,__func__) {
376  ATTRIBUTE_NOT_ASSIGNABLE();
377  return OBJECT_VAL(self->method);
378 }
379 
380 KRK_Method(method,__self__) {
381  ATTRIBUTE_NOT_ASSIGNABLE();
382  return OBJECT_VAL(self->receiver);
383 }
384 
385 KRK_Function(staticmethod) {
386  KrkObj* method;
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);
391 }
392 
393 KRK_Function(classmethod) {
394  KrkObj* method;
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);
399 }
400 
401 _noexport
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;
405  codeobject->allocSize = 0;
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__);
418  krk_defineNative(&codeobject->methods, "__repr__", FUNC_NAME(codeobject,__str__));
419  krk_finalizeClass(codeobject);
420 
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__));
437  krk_defineNative(&function->methods, "__class_getitem__", krk_GenericAlias)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
438  krk_finalizeClass(function);
439 
440  KrkClass * method = ADD_BASE_CLASS(vm.baseClasses->methodClass, "method", vm.baseClasses->objectClass);
441  method->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
442  method->allocSize = 0;
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__);
455  krk_defineNative(&method->methods, "__repr__", FUNC_NAME(method,__str__));
456  krk_finalizeClass(method);
457 
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.");
460 }
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.
NativeFn krk_GenericAlias
Special value for type hint expressions.
Definition: obj_typing.c:67
KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj *method)
Create a new bound method.
Definition: object.c:346
KrkBytes * krk_newBytes(size_t length, uint8_t *source)
Create a new byte array.
Definition: object.c:363
size_t krk_lineNumber(KrkChunk *chunk, size_t offset)
Obtain the line number for a byte offset into a bytecode chunk.
Definition: chunk.c:74
Type object.
Definition: object.h:189
size_t allocSize
Size to allocate when creating instances of this class.
Definition: object.h:196
KrkObj obj
Base.
Definition: object.h:190
KrkTable methods
General attributes table.
Definition: object.h:192
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.
Definition: object.c:286
Code object.
Definition: object.h:144
unsigned short potentialPositionals
Precalculated positional arguments for complex argument processing.
Definition: object.h:148
KrkValueArray positionalArgNames
Array of names for positional arguments (and *args)
Definition: object.h:154
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
unsigned short totalArguments
Total argument cells we can fill in complex argument processing.
Definition: object.h:149
Managed binding to a C function.
Definition: object.h:283
KrkObj obj
Base.
Definition: object.h:284
The most basic object type.
Definition: object.h:41
uint16_t flags
General object flags, mostly related to garbage collection.
Definition: object.h:43
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
Definition: object.c:221
KrkNative * krk_defineNative(KrkTable *table, const char *name, NativeFn function)
Attach a native C function to an attribute table.
Definition: vm.c:194
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
KrkUpvalue * krk_newUpvalue(int slot)
Create an upvalue slot.
Definition: object.c:311
KrkValue * values
Definition: value.h:73
size_t count
Definition: value.h:72
Stack reference or primative value.
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_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
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
#define vm
Convenience macro for namespacing.
Definition: vm.h:267
KrkValue krk_pop(void)
Pop the top of the stack.
Definition: vm.c:170
void krk_push(KrkValue value)
Push a stack value.
Definition: vm.c:157
KrkValue krk_peek(int distance)
Peek down from the top of the stack.
Definition: vm.c:178