18 AS_slice(outSlice)->start = (argc > 0) ? argv[0] : NONE_VAL();
19 AS_slice(outSlice)->end = (argc > 1) ? argv[1] : NONE_VAL();
20 AS_slice(outSlice)->step = (argc > 2) ? argv[2] : NONE_VAL();
25 static inline krk_integer_type _wrap(krk_integer_type count, krk_integer_type val) {
26 if (val < 0) val += count;
28 if (val > count) val = count;
32 static inline krk_integer_type _wrapn(krk_integer_type count, krk_integer_type val) {
33 if (val < 0) val += count;
34 if (val < -1) val = -1;
35 if (val > count) val = count;
39 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) {
40 if (!(IS_slice(slicerVal))) {
41 TYPE_ERROR(slice, slicerVal);
45 struct KrkSlice * slicer = AS_slice(slicerVal);
51 if (!(IS_INTEGER(_start) || IS_NONE(_start))) {
52 TYPE_ERROR(
int or None, _start);
56 if (!(IS_INTEGER(_end) || IS_NONE(_end))) {
57 TYPE_ERROR(
int or None, _end);
61 if (!(IS_INTEGER(_step) || IS_NONE(_step))) {
62 TYPE_ERROR(
int or None, _step);
73 *step = IS_NONE(_step) ? 1 : AS_INTEGER(_step);
82 *start = _wrap(count, IS_NONE(_start) ? 0 : AS_INTEGER(_start));
83 *end = _wrap(count, IS_NONE(_end) ? count : AS_INTEGER(_end));
84 if (*end < *start) *end = *start;
86 *start = IS_NONE(_start) ? (count-1) : _wrap(count, AS_INTEGER(_start));
87 if (*start >= count) *start = count -1;
88 *end = IS_NONE(_end) ? -1 : _wrapn(count, AS_INTEGER(_end));
89 if (*end > *start) *end = *start;
95 #define CURRENT_CTYPE struct KrkSlice *
96 #define CURRENT_NAME self
98 KRK_Method(slice,__init__) {
99 METHOD_TAKES_AT_LEAST(1);
100 METHOD_TAKES_AT_MOST(3);
103 self->start = NONE_VAL();
105 self->step = NONE_VAL();
107 self->start = argv[1];
110 self->step = argv[3];
112 self->step = NONE_VAL();
119 KRK_Method(slice,__repr__) {
121 if (((
KrkObj*)
self)->
flags & KRK_OBJ_FLAGS_IN_REPR)
return OBJECT_VAL(S(
"slice(...)"));
122 ((
KrkObj*)
self)->flags |= KRK_OBJ_FLAGS_IN_REPR;
124 pushStringBuilderStr(&sb,
"slice(",6);
126 if (!krk_pushStringBuilderFormat(&sb,
"%R", self->start))
goto _error;
127 pushStringBuilderStr(&sb,
", ",2);
128 if (!krk_pushStringBuilderFormat(&sb,
"%R", self->end))
goto _error;
129 pushStringBuilderStr(&sb,
", ",2);
130 if (!krk_pushStringBuilderFormat(&sb,
"%R", self->step))
goto _error;
131 pushStringBuilder(&sb,
')');
132 ((
KrkObj*)
self)->flags &= ~(KRK_OBJ_FLAGS_IN_REPR);
133 return finishStringBuilder(&sb);
136 ((
KrkObj*)
self)->flags &= ~(KRK_OBJ_FLAGS_IN_REPR);
141 KRK_Method(slice,start) {
142 ATTRIBUTE_NOT_ASSIGNABLE();
146 KRK_Method(slice,end) {
147 ATTRIBUTE_NOT_ASSIGNABLE();
151 KRK_Method(slice,step) {
152 ATTRIBUTE_NOT_ASSIGNABLE();
157 #define CURRENT_CTYPE KrkInstance *
158 #define IS_ellipsis(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(ellipsis)))
159 #define AS_ellipsis(o) ((KrkInstance*)AS_INSTANCE(o))
161 KRK_StaticMethod(ellipsis,__new__) {
163 if (!
krk_parseArgs(
"O!", (
const char*[]){
"cls"}, KRK_BASE_CLASS(type), &_class))
return NONE_VAL();
164 if (!krk_isSubClass(_class, KRK_BASE_CLASS(ellipsis))) {
165 return krk_runtimeError(
vm.exceptions->typeError,
"%S is not a subclass of %S", _class->
name, KRK_BASE_CLASS(ellipsis)->name);
173 KRK_Method(ellipsis,__repr__) {
174 return OBJECT_VAL(S(
"Ellipsis"));
178 void _createAndBind_sliceClass(
void) {
179 KrkClass * slice = ADD_BASE_CLASS(KRK_BASE_CLASS(slice),
"slice", KRK_BASE_CLASS(
object));
182 slice->
obj.
flags |= KRK_OBJ_FLAGS_NO_INHERIT;
183 BIND_METHOD(slice,__init__);
184 BIND_METHOD(slice,__repr__);
185 BIND_PROP(slice,start);
186 BIND_PROP(slice,end);
187 BIND_PROP(slice,step);
191 KrkClass * ellipsis = ADD_BASE_CLASS(KRK_BASE_CLASS(ellipsis),
"ellipsis", KRK_BASE_CLASS(
object));
193 ellipsis->
obj.
flags |= KRK_OBJ_FLAGS_NO_INHERIT;
194 BIND_STATICMETHOD(ellipsis,__new__);
195 BIND_METHOD(ellipsis,__repr__);
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Functions for dealing with garbage collection and memory allocation.
void krk_markValue(KrkValue value)
During a GC scan cycle, mark a value as used.
KrkCleanupCallback _ongcscan
C function to call when the garbage collector visits an instance of this class in the scan phase.
KrkString * name
Name of the class.
size_t allocSize
Size to allocate when creating instances of this class.
KrkTable methods
General attributes table.
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
KrkInstance * krk_newInstance(KrkClass *_class)
Create a new instance of the given class.
The most basic object type.
uint16_t flags
General object flags, mostly related to garbage collection.
KrkValue krk_slice_of(int argc, const KrkValue argv[], int hasKw)
Create a slice object.
void krk_attachNamedObject(KrkTable *table, const char name[], KrkObj *obj)
Attach an object to an attribute table.
void krk_attachNamedValue(KrkTable *table, const char name[], KrkValue obj)
Attach a value to an attribute table.
int krk_tableGet_fast(KrkTable *table, struct KrkString *str, KrkValue *value)
Obtain the value associated with a string key in a table.
Stack reference or primative value.
Inline flexible string array.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
KrkValue krk_discardStringBuilder(struct StringBuilder *sb)
Discard the contents of a string builder.
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
#define vm
Convenience macro for namespacing.
KrkValue krk_pop(void)
Pop the top of the stack.
void krk_push(KrkValue value)
Push a stack value.