Skip to content

Commit

Permalink
Implement Ellipsis (...)
Browse files Browse the repository at this point in the history
  • Loading branch information
klange committed Jan 1, 2024
1 parent 7f397b2 commit ae6ec7f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 4 deletions.
15 changes: 13 additions & 2 deletions src/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,16 @@ static void literal(struct GlobalState * state, int exprType, RewindState *rewin
}
}

static void ellipsis(struct GlobalState * state, int exprType, RewindState *rewind) {
invalidTarget(state, exprType, "literal");
KrkValue value;
if (!krk_tableGet_fast(&vm.builtins->fields, S("Ellipsis"), &value)) {
error("internal compiler error");
return;
}
emitConstant(value);
}

static void typeHintLocal(struct GlobalState * state) {
state->current->enclosing->enclosed = state->current;
state->current = state->current->enclosing;
Expand Down Expand Up @@ -2588,8 +2598,8 @@ static void fromImportStatement(struct GlobalState * state) {
return;
}

while (match(TOKEN_DOT)) {
leadingDots++;
while (match(TOKEN_DOT) || match(TOKEN_ELLIPSIS)) {
leadingDots += state->parser.previous.length;
}

importModule(state, &startOfName, leadingDots);
Expand Down Expand Up @@ -4204,6 +4214,7 @@ ParseRule krk_parseRules[] = {
RULE(FALSE, literal, NULL, PREC_NONE),
RULE(NONE, literal, NULL, PREC_NONE),
RULE(TRUE, literal, NULL, PREC_NONE),
RULE(ELLIPSIS, ellipsis, NULL, PREC_NONE),
RULE(YIELD, yield, NULL, PREC_NONE),
RULE(AWAIT, await, NULL, PREC_NONE),
RULE(LAMBDA, lambda, NULL, PREC_NONE),
Expand Down
2 changes: 2 additions & 0 deletions src/kuroko/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ typedef enum {
TOKEN_RETRY,
TOKEN_ERROR,
TOKEN_EOF,

TOKEN_ELLIPSIS, /* ... */
} KrkTokenType;

/**
Expand Down
1 change: 1 addition & 0 deletions src/kuroko/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ struct BaseClasses {
KrkClass * setiteratorClass; /**< Iterator over values in a set */
KrkClass * ThreadClass; /**< Threading.Thread */
KrkClass * LockClass; /**< Threading.Lock */
KrkClass * ellipsisClass; /**< Type of the Ellipsis (...) singleton */
};

/**
Expand Down
31 changes: 30 additions & 1 deletion src/obj_slice.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,30 @@ KRK_Method(slice,step) {
return self->step;
}

#undef CURRENT_CTYPE
#define CURRENT_CTYPE KrkInstance *
#define IS_ellipsis(o) (krk_isInstanceOf(o,KRK_BASE_CLASS(ellipsis)))
#define AS_ellipsis(o) ((KrkInstance*)AS_INSTANCE(o))

KRK_StaticMethod(ellipsis,__new__) {
KrkClass * _class = NULL;
if (!krk_parseArgs("O!", (const char*[]){"cls"}, KRK_BASE_CLASS(type), &_class)) return NONE_VAL();
if (!krk_isSubClass(_class, KRK_BASE_CLASS(ellipsis))) {
return krk_runtimeError(vm.exceptions->typeError, "%S is not a subclass of %S", _class->name, KRK_BASE_CLASS(ellipsis)->name);
}

KrkValue out;
if (!krk_tableGet_fast(&vm.builtins->fields, S("Ellipsis"), &out)) return krk_runtimeError(vm.exceptions->typeError, "Ellipsis is missing");
return out;
}

KRK_Method(ellipsis,__repr__) {
return OBJECT_VAL(S("Ellipsis"));
}

_noexport
void _createAndBind_sliceClass(void) {
KrkClass * slice = ADD_BASE_CLASS(vm.baseClasses->sliceClass, "slice", vm.baseClasses->objectClass);
KrkClass * slice = ADD_BASE_CLASS(KRK_BASE_CLASS(slice), "slice", KRK_BASE_CLASS(object));
slice->allocSize = sizeof(struct KrkSlice);
slice->_ongcscan = _slice_gcscan;
slice->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
Expand All @@ -179,4 +200,12 @@ void _createAndBind_sliceClass(void) {
BIND_PROP(slice,step);
krk_attachNamedValue(&slice->methods, "__hash__", NONE_VAL());
krk_finalizeClass(slice);

KrkClass * ellipsis = ADD_BASE_CLASS(KRK_BASE_CLASS(ellipsis), "ellipsis", KRK_BASE_CLASS(object));
krk_attachNamedObject(&vm.builtins->fields, "Ellipsis", (KrkObj*)krk_newInstance(ellipsis));
ellipsis->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
BIND_STATICMETHOD(ellipsis,__new__);
BIND_METHOD(ellipsis,__repr__);
krk_finalizeClass(ellipsis);

}
2 changes: 1 addition & 1 deletion src/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,9 @@ KrkToken krk_scanToken(KrkScanner * scanner) {
case '[': return makeToken(scanner, TOKEN_LEFT_SQUARE);
case ']': return makeToken(scanner, TOKEN_RIGHT_SQUARE);
case ',': return makeToken(scanner, TOKEN_COMMA);
case '.': return makeToken(scanner, TOKEN_DOT);
case ';': return makeToken(scanner, TOKEN_SEMICOLON);
case '~': return makeToken(scanner, TOKEN_TILDE);
case '.': return makeToken(scanner, peek(scanner) == '.' ? (peekNext(scanner,1) == '.' ? (advance(scanner), advance(scanner), TOKEN_ELLIPSIS) : TOKEN_DOT) : TOKEN_DOT);

case ':': return makeToken(scanner, match(scanner, '=') ? TOKEN_WALRUS : TOKEN_COLON);
case '!': return makeToken(scanner, match(scanner, '=') ? TOKEN_BANG_EQUAL : TOKEN_BANG);
Expand Down

0 comments on commit ae6ec7f

Please sign in to comment.