Make 'self' not a keyword
It's still implicitly the first argument to a method and can not be used in a method signature outside of the first argument, which is ignored in the compiler. Actually, we allowed 'self' to be quietly stuck in other slots but now we should correctly error on it.
This commit is contained in:
parent
84817c45cf
commit
1c5c2577e9
@ -1044,20 +1044,27 @@ static void function(FunctionType type, size_t blockWidth) {
|
||||
if (isMethod(type)) current->codeobject->requiredArgs = 1;
|
||||
|
||||
int hasCollectors = 0;
|
||||
KrkToken self = syntheticToken("self");
|
||||
|
||||
consume(TOKEN_LEFT_PAREN, "Expected start of parameter list after function name.");
|
||||
startEatingWhitespace();
|
||||
if (!check(TOKEN_RIGHT_PAREN)) {
|
||||
do {
|
||||
if (match(TOKEN_SELF)) {
|
||||
if (!isMethod(type)) {
|
||||
error("Invalid use of `self` as a function paramenter.");
|
||||
if (isMethod(type) && check(TOKEN_IDENTIFIER) &&
|
||||
identifiersEqual(&parser.current, &self)) {
|
||||
if (hasCollectors || current->codeobject->requiredArgs != 1) {
|
||||
errorAtCurrent("Argument name `self` in a method signature is reserved for the implicit first argument.");
|
||||
break;
|
||||
}
|
||||
advance();
|
||||
if (check(TOKEN_COLON)) {
|
||||
KrkToken name = parser.previous;
|
||||
match(TOKEN_COLON);
|
||||
typeHint(name);
|
||||
}
|
||||
if (check(TOKEN_EQUAL)) {
|
||||
errorAtCurrent("`self` can not be a keyword argument.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (match(TOKEN_ASTERISK) || check(TOKEN_POW)) {
|
||||
@ -2358,14 +2365,6 @@ static void variable(int canAssign) {
|
||||
namedVariable(parser.previous, canAssign);
|
||||
}
|
||||
|
||||
static void self(int canAssign) {
|
||||
if (currentClass == NULL) {
|
||||
error("Invalid reference to `self` outside of a class method.");
|
||||
return;
|
||||
}
|
||||
variable(0);
|
||||
}
|
||||
|
||||
static void super_(int canAssign) {
|
||||
if (currentClass == NULL) {
|
||||
error("Invalid reference to `super` outside of a class.");
|
||||
@ -2375,7 +2374,7 @@ static void super_(int canAssign) {
|
||||
consume(TOKEN_DOT, "Expected a field of `super()` to be referenced.");
|
||||
consume(TOKEN_IDENTIFIER, "Expected a field name.");
|
||||
size_t ind = identifierConstant(&parser.previous);
|
||||
namedVariable(syntheticToken("self"), 0);
|
||||
EMIT_CONSTANT_OP(OP_GET_LOCAL, 0);
|
||||
namedVariable(syntheticToken("super"), 0);
|
||||
EMIT_CONSTANT_OP(OP_GET_SUPER, ind);
|
||||
}
|
||||
@ -2726,7 +2725,6 @@ ParseRule krk_parseRules[] = {
|
||||
RULE(TOKEN_NONE, literal, NULL, PREC_NONE),
|
||||
RULE(TOKEN_OR, NULL, or_, PREC_OR),
|
||||
RULE(TOKEN_RETURN, NULL, NULL, PREC_NONE),
|
||||
RULE(TOKEN_SELF, self, NULL, PREC_NONE),
|
||||
RULE(TOKEN_SUPER, super_, NULL, PREC_NONE),
|
||||
RULE(TOKEN_TRUE, literal, NULL, PREC_NONE),
|
||||
RULE(TOKEN_WHILE, NULL, NULL, PREC_NONE),
|
||||
|
@ -81,7 +81,6 @@ typedef enum {
|
||||
TOKEN_ELIF,
|
||||
TOKEN_PASS,
|
||||
TOKEN_RETURN,
|
||||
TOKEN_SELF,
|
||||
TOKEN_SUPER,
|
||||
TOKEN_TRUE,
|
||||
TOKEN_WHILE,
|
||||
|
@ -248,10 +248,7 @@ static KrkTokenType identifierType() {
|
||||
case 'e': return checkKeyword(2, "turn", TOKEN_RETURN);
|
||||
case 'a': return checkKeyword(2, "ise", TOKEN_RAISE);
|
||||
} break;
|
||||
case 's': if (MORE(1)) switch(scanner.start[1]) {
|
||||
case 'e': return checkKeyword(2, "lf", TOKEN_SELF);
|
||||
case 'u': return checkKeyword(2, "per", TOKEN_SUPER);
|
||||
} break;
|
||||
case 's': return checkKeyword(1, "uper", TOKEN_SUPER);
|
||||
case 't': return checkKeyword(1, "ry", TOKEN_TRY);
|
||||
case 'T': return checkKeyword(1, "rue", TOKEN_TRUE);
|
||||
case 'w': if (MORE(1)) switch(scanner.start[1]) {
|
||||
|
Loading…
Reference in New Issue
Block a user