15 #define S(c) (krk_copyString(c,sizeof(c)-1))
17 #define likely(cond) __builtin_expect((cond), 1)
18 #define unlikely(cond) __builtin_expect((cond), 0)
20 #if !defined(__has_attribute)
21 # define __has_attribute(attr) 0
24 #if __has_attribute(protected)
25 # define _protected __attribute__((protected))
30 #if !defined(_WIN32) && !defined(EFI_PLATFORM)
31 #define _noexport __attribute__((visibility("hidden")))
36 #if __has_attribute(unused)
37 # define _unused __attribute__((unused))
42 #if __has_attribute(hot)
43 # define _hot __attribute__((hot))
48 #if __has_attribute(cold)
49 # define _cold __attribute__((cold))
54 #if __has_attribute(nonnull)
55 # define _nonnull __attribute__((nonnull))
60 #define ADD_BASE_CLASS(obj, name, baseClass) krk_makeClass(vm.builtins, &obj, name, baseClass)
62 #define ATTRIBUTE_NOT_ASSIGNABLE() do { if (unlikely(argc != 1)) return krk_runtimeError(vm.exceptions->attributeError, "'%T' object has no attribute '%s'", \
63 argv[0], _method_name); } while (0)
65 #define METHOD_TAKES_NONE() do { if (unlikely(argc != 1)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \
66 _method_name, (argc-1)); } while (0)
68 #define METHOD_TAKES_EXACTLY(n) do { if (unlikely(argc != (n+1))) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \
69 _method_name, "exactly", n, (n != 1) ? "s" : "", (argc-1)); } while (0)
71 #define METHOD_TAKES_AT_LEAST(n) do { if (unlikely(argc < (n+1))) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \
72 _method_name, "at least", n, (n != 1) ? "s" : "", (argc-1)); } while (0)
74 #define METHOD_TAKES_AT_MOST(n) do { if (unlikely(argc > (n+1))) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \
75 _method_name, "at most", n, (n != 1) ? "s" : "", (argc-1)); } while (0)
77 #define FUNCTION_TAKES_NONE() do { if (unlikely(argc != 0)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \
78 _method_name, (argc)); } while (0)
80 #define FUNCTION_TAKES_EXACTLY(n) do { if (unlikely(argc != n)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \
81 _method_name, "exactly", n, (n != 1) ? "s" : "", (argc)); } while (0)
83 #define FUNCTION_TAKES_AT_LEAST(n) do { if (unlikely(argc < n)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \
84 _method_name, "at least", n, (n != 1) ? "s" : "", (argc)); } while (0)
86 #define FUNCTION_TAKES_AT_MOST(n) do { if (unlikely(argc > n)) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes %s %d argument%s (%d given)", \
87 _method_name, "at most", n, (n != 1) ? "s" : "", (argc)); } while (0)
89 #define TYPE_ERROR(expected,value) krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%T'", \
90 _method_name, #expected, value)
92 #define NOT_ENOUGH_ARGS(name) krk_runtimeError(vm.exceptions->argumentError, "Expected more args.")
94 #define CHECK_ARG(i, type, ctype, name) \
95 if (unlikely(argc < (i+1))) return NOT_ENOUGH_ARGS(name); \
96 if (unlikely(!IS_ ## type (argv[i]))) return TYPE_ERROR(type,argv[i]); \
97 ctype name _unused = AS_ ## type (argv[i])
99 #define FUNC_NAME(klass, name) _ ## klass ## _ ## name
100 #define FUNC_SIG(klass, name) _noexport KrkValue FUNC_NAME(klass,name) (int argc, const KrkValue argv[], int hasKw)
103 #define MAKE_CLASS(klass) do { krk_makeClass(module,&klass,#klass,vm.baseClasses->objectClass); klass ->allocSize = sizeof(struct klass); } while (0)
104 #define BIND_METHOD(klass,method) krk_defineNative(&klass->methods, #method, _ ## klass ## _ ## method)
105 #define BIND_PROP(klass,method) krk_defineNativeProperty(&klass->methods, #method, _ ## klass ## _ ## method)
106 #define BIND_FUNC(module,func) krk_defineNative(&module->fields, #func, _krk_ ## func)
108 static inline KrkNative * krk_defineNativeStaticMethod(
KrkTable * table,
const char * name, NativeFn
function) {
110 out->
obj.
flags |= KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
113 #define BIND_STATICMETHOD(klass,method) krk_defineNativeStaticMethod(&klass->methods, #method, _ ## klass ## _ ## method)
115 static inline KrkNative * krk_defineNativeClassMethod(
KrkTable * table,
const char * name, NativeFn
function) {
117 out->
obj.
flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
120 #define BIND_CLASSMETHOD(klass,method) krk_defineNativeClassMethod(&klass->methods, #method, _ ## klass ## _ ## method)
122 #define KRK_Method_internal_name(klass, name) \
123 _krk_method_ ## klass ## _ ## name
124 #define KRK_Method_internal_sig(klass, name) \
125 static inline KrkValue KRK_Method_internal_name(klass,name) (const char * _method_name, CURRENT_CTYPE CURRENT_NAME, int argc, const KrkValue argv[], int hasKw)
127 #define KRK_Method(klass, name) \
128 KRK_Method_internal_sig(klass, name); \
129 FUNC_SIG(klass, name) { \
130 static const char * _method_name = # name; \
131 CHECK_ARG(0,klass,CURRENT_CTYPE,CURRENT_NAME); \
132 return KRK_Method_internal_name(klass,name)(_method_name, CURRENT_NAME, argc, argv, hasKw); \
134 KRK_Method_internal_sig(klass,name)
136 #define KRK_Function_internal_name(name) \
137 _krk_function_ ## name
138 #define KRK_Function_internal_sig(name) \
139 static inline KrkValue KRK_Function_internal_name(name) (const char * _method_name, int argc, const KrkValue argv[], int hasKw)
141 #define KRK_Function(name) \
142 KRK_Function_internal_sig(name); \
143 static KrkValue _krk_ ## name (int argc, const KrkValue argv[], int hasKw) { \
144 static const char* _method_name = # name; \
145 return KRK_Function_internal_name(name)(_method_name,argc,argv,hasKw); \
147 KRK_Function_internal_sig(name)
149 #define KRK_StaticMethod_internal_sig(klass, name) \
150 static inline KrkValue KRK_Method_internal_name(klass, name) (const char * _method_name, int argc, const KrkValue argv[], int hasKw)
151 #define KRK_StaticMethod(klass, name) \
152 KRK_StaticMethod_internal_sig(klass, name); \
153 FUNC_SIG(klass, name) { \
154 static const char * _method_name = # name; \
155 return KRK_Method_internal_name(klass,name)(_method_name,argc,argv,hasKw); \
157 KRK_StaticMethod_internal_sig(klass,name)
175 #define pushStringBuilder krk_pushStringBuilder
185 #define pushStringBuilderStr krk_pushStringBuilderStr
198 #define finishStringBuilder krk_finishStringBuilder
210 #define finishStringBuilderBytes krk_finishStringBuilderBytes
223 #define discardStringBuilder krk_discardStringBuilder
225 #define IS_int(o) (IS_INTEGER(o))
226 #define AS_int(o) (AS_INTEGER(o))
228 #define IS_bool(o) (IS_BOOLEAN(o))
229 #define AS_bool(o) (AS_BOOLEAN(o))
231 #define IS_float(o) (IS_FLOATING(o))
232 #define AS_float(o) (AS_FLOATING(o))
234 #define IS_list(o) ((IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->listClass) || krk_isInstanceOf(o,vm.baseClasses->listClass))
235 #define AS_list(o) (KrkList*)AS_OBJECT(o)
237 #define IS_tuple(o) IS_TUPLE(o)
238 #define AS_tuple(o) AS_TUPLE(o)
240 #define IS_bytes(o) IS_BYTES(o)
241 #define AS_bytes(o) AS_BYTES(o)
243 #define IS_class(o) IS_CLASS(o)
244 #define AS_class(o) AS_CLASS(o)
246 #define IS_str(o) (IS_STRING(o)||krk_isInstanceOf(o,vm.baseClasses->strClass))
247 #define AS_str(o) (KrkString*)AS_OBJECT(o)
249 #define IS_striterator(o) (krk_isInstanceOf(o,vm.baseClasses->striteratorClass))
250 #define AS_striterator(o) (AS_INSTANCE(o))
252 #define IS_dict(o) ((IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->dictClass) || krk_isInstanceOf(o,vm.baseClasses->dictClass))
253 #define AS_dict(o) (KrkDict*)AS_OBJECT(o)
255 #define IS_dictitems(o) krk_isInstanceOf(o,vm.baseClasses->dictitemsClass)
256 #define AS_dictitems(o) ((struct DictItems*)AS_OBJECT(o))
258 #define IS_dictkeys(o) krk_isInstanceOf(o,vm.baseClasses->dictkeysClass)
259 #define AS_dictkeys(o) ((struct DictKeys*)AS_OBJECT(o))
261 #define IS_dictvalues(o) krk_isInstanceOf(o,vm.baseClasses->dictvaluesClass)
262 #define AS_dictvalues(o) ((struct DictValues*)AS_OBJECT(o))
264 #define IS_bytearray(o) (krk_isInstanceOf(o,vm.baseClasses->bytearrayClass))
265 #define AS_bytearray(o) ((struct ByteArray*)AS_INSTANCE(o))
267 #define IS_slice(o) krk_isInstanceOf(o,vm.baseClasses->sliceClass)
268 #define AS_slice(o) ((struct KrkSlice*)AS_INSTANCE(o))
274 #define krk_string_get FUNC_NAME(str,__getitem__)
275 #define krk_string_split FUNC_NAME(str,split)
276 #define krk_string_format FUNC_NAME(str,format)
278 static inline void _setDoc_class(
KrkClass * thing,
const char * text,
size_t size) {
281 static inline void _setDoc_instance(
KrkInstance * thing,
const char * text,
size_t size) {
284 static inline void _setDoc_native(
KrkNative * thing,
const char * text,
size_t size) {
301 #ifdef KRK_NO_DOCUMENTATION
302 # define KRK_DOC(thing, text) (thing);
304 # define KRK_DOC(thing, text) \
305 _Generic(&((thing)[0]), \
306 KrkClass*: _setDoc_class, \
307 KrkInstance*: _setDoc_instance, \
308 KrkNative*: _setDoc_native \
309 )(thing,text,sizeof(text)-1)
312 #define BUILTIN_FUNCTION(name, func, docStr) KRK_DOC(krk_defineNative(&vm.builtins->fields, name, func), docStr)
314 extern int krk_extractSlicer(
const char * _method_name,
KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step);
315 #define KRK_SLICER(arg,count) \
316 krk_integer_type start; \
317 krk_integer_type end; \
318 krk_integer_type step; \
319 if (krk_extractSlicer(_method_name, arg, count, &start, &end, &step))
335 #define KRK_BASE_CLASS(cls) (vm.baseClasses->cls ## Class)
336 #define KRK_EXC(exc) (vm.exceptions->exc)
340 const char * _method_name,
341 int argc,
const KrkValue argv[],
int hasKw,
342 const char * fmt,
const char ** names, va_list args);
345 const char * _method_name,
346 int argc,
const KrkValue argv[],
int hasKw,
347 const char * format,
const char ** names, ...);
360 #define krk_parseArgs(f,n,...) krk_parseArgs_impl(_method_name,argc,argv,hasKw,f,n,__VA_ARGS__)
363 extern int krk_pushStringBuilderFormatV(
struct StringBuilder * sb,
const char * fmt, va_list args);
364 extern int krk_pushStringBuilderFormat(
struct StringBuilder * sb,
const char * fmt, ...);
365 extern KrkValue krk_stringFromFormat(
const char * fmt, ...);
369 #define KRK_Module_internal_name(name) \
370 _krk_module_onload_ ## name
371 #define KRK_Module_internal_sig(name) \
372 static inline void KRK_Module_internal_name(name) (KrkInstance * module, KrkString * runAs)
373 #define KRK_Module(name) \
374 KRK_Module_internal_sig(name); \
375 KrkValue krk_module_onload_ ## name (KrkString * runAs) { \
376 KrkInstance * module = krk_newInstance(KRK_BASE_CLASS(module)); \
377 krk_push(OBJECT_VAL(module)); \
378 krk_attachNamedObject(&module->fields, "__name__", (KrkObj*)runAs); \
379 KRK_Module_internal_name(name)(module, runAs); \
382 KRK_Module_internal_sig(name)
Functions for dealing with garbage collection and memory allocation.
Struct definitions for core object types.
KrkTable methods
General attributes table.
KrkTable fields
Attributes table.
Managed binding to a C function.
const char * doc
Docstring to supply from __doc__.
The most basic object type.
uint16_t flags
General object flags, mostly related to garbage collection.
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
One (key,value) pair in a table.
Simple hash table of arbitrary keys to values.
void krk_attachNamedObject(KrkTable *table, const char name[], KrkObj *obj)
Attach an object to an attribute table.
KrkNative * krk_defineNative(KrkTable *table, const char *name, NativeFn function)
Attach a native C function to an attribute table.
Stack reference or primative value.
Inline flexible string array.
void krk_pushStringBuilderStr(struct StringBuilder *sb, const char *str, size_t len)
Append a string to the end of a string builder.
KrkValue krk_finishStringBuilderBytes(struct StringBuilder *sb)
Finalize a string builder in a bytes object.
int krk_long_to_int(KrkValue val, char size, void *out)
Convert an int or long to a C integer.
KrkValue krk_discardStringBuilder(struct StringBuilder *sb)
Discard the contents of a string builder.
int krk_unpackIterable(KrkValue iterable, void *context, int callback(void *, const KrkValue *, size_t))
Unpack an iterable.
KrkValue krk_finishStringBuilder(struct StringBuilder *sb)
Finalize a string builder into a string object.
int krk_parseArgs_impl(const char *_method_name, int argc, const KrkValue argv[], int hasKw, const char *format, const char **names,...)
Variable argument version of krk_parseVArgs.
void krk_pushStringBuilder(struct StringBuilder *sb, char c)
Add a character to the end of a string builder.
int krk_parseVArgs(const char *_method_name, int argc, const KrkValue argv[], int hasKw, const char *fmt, const char **names, va_list args)
Validate and parse arguments to a function similar to how managed function arguments are handled.
Core API for the bytecode virtual machine.