diff --git a/src/compiler.c b/src/compiler.c index 0a01ad9..2c0da41 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -808,6 +808,7 @@ static void binary(int exprType, RewindState *rewind) { case TOKEN_DOUBLE_SOLIDUS: emitByte(OP_FLOORDIV); break; case TOKEN_MODULO: emitByte(OP_MODULO); break; case TOKEN_IN: emitByte(OP_EQUAL); break; + case TOKEN_AT: emitByte(OP_MATMUL); break; default: return; } } @@ -868,6 +869,7 @@ static void assignmentValue(void) { case TOKEN_SOLIDUS_EQUAL: emitByte(OP_INPLACE_DIVIDE); break; case TOKEN_DSOLIDUS_EQUAL: emitByte(OP_INPLACE_FLOORDIV); break; case TOKEN_MODULO_EQUAL: emitByte(OP_INPLACE_MODULO); break; + case TOKEN_AT_EQUAL: emitByte(OP_INPLACE_MATMUL); break; default: error("Unexpected operand in assignment"); @@ -3646,7 +3648,6 @@ ParseRule krk_parseRules[] = { RULE(TOKEN_SEMICOLON, NULL, NULL, PREC_NONE), RULE(TOKEN_EQUAL, NULL, NULL, PREC_NONE), RULE(TOKEN_WALRUS, NULL, NULL, PREC_NONE), - RULE(TOKEN_AT, NULL, NULL, PREC_NONE), RULE(TOKEN_PLUS_EQUAL, NULL, NULL, PREC_NONE), RULE(TOKEN_MINUS_EQUAL, NULL, NULL, PREC_NONE), RULE(TOKEN_PLUS_PLUS, NULL, NULL, PREC_NONE), @@ -3660,6 +3661,7 @@ ParseRule krk_parseRules[] = { RULE(TOKEN_DSOLIDUS_EQUAL,NULL, NULL, PREC_NONE), RULE(TOKEN_ASTERISK_EQUAL,NULL, NULL, PREC_NONE), RULE(TOKEN_MODULO_EQUAL, NULL, NULL, PREC_NONE), + RULE(TOKEN_AT_EQUAL, NULL, NULL, PREC_NONE), RULE(TOKEN_ARROW, NULL, NULL, PREC_NONE), RULE(TOKEN_MINUS, unary, binary, PREC_SUM), RULE(TOKEN_PLUS, unary, binary, PREC_SUM), @@ -3669,6 +3671,7 @@ ParseRule krk_parseRules[] = { RULE(TOKEN_DOUBLE_SOLIDUS,NULL, binary, PREC_TERM), RULE(TOKEN_ASTERISK, NULL, binary, PREC_TERM), RULE(TOKEN_MODULO, NULL, binary, PREC_TERM), + RULE(TOKEN_AT, NULL, binary, PREC_TERM), RULE(TOKEN_POW, NULL, binary, PREC_EXPONENT), RULE(TOKEN_PIPE, NULL, binary, PREC_BITOR), RULE(TOKEN_CARET, NULL, binary, PREC_BITXOR), diff --git a/src/kuroko/chunk.h b/src/kuroko/chunk.h index 5612dfb..b5fede0 100644 --- a/src/kuroko/chunk.h +++ b/src/kuroko/chunk.h @@ -71,6 +71,7 @@ typedef enum { OP_FLOORDIV, OP_UNSET, OP_RAISE_FROM, + OP_MATMUL, OP_INPLACE_ADD, OP_INPLACE_BITAND, @@ -84,6 +85,7 @@ typedef enum { OP_INPLACE_FLOORDIV, OP_INPLACE_MODULO, OP_INPLACE_MULTIPLY, + OP_INPLACE_MATMUL, /* One-opcode instructions */ OP_CALL, diff --git a/src/kuroko/object.h b/src/kuroko/object.h index 9d883fd..ffb9e59 100644 --- a/src/kuroko/object.h +++ b/src/kuroko/object.h @@ -235,6 +235,7 @@ typedef struct KrkClass { KrkObj * _lt, * _gt, * _le, * _ge; KrkObj * _invert, * _negate; KrkObj * _set_name; + KrkObj * _matmul, * _rmatmul, * _imatmul; } KrkClass; /** diff --git a/src/kuroko/scanner.h b/src/kuroko/scanner.h index 5671660..bea40b2 100644 --- a/src/kuroko/scanner.h +++ b/src/kuroko/scanner.h @@ -52,8 +52,9 @@ typedef enum { TOKEN_SOLIDUS_EQUAL, TOKEN_ASTERISK_EQUAL, TOKEN_POW_EQUAL, - TOKEN_MODULO_EQUAL, TOKEN_DSOLIDUS_EQUAL, + TOKEN_AT_EQUAL, + TOKEN_MODULO_EQUAL, TOKEN_STRING, TOKEN_BIG_STRING, diff --git a/src/methods.h b/src/methods.h index 61423e8..1a4065b 100644 --- a/src/methods.h +++ b/src/methods.h @@ -35,6 +35,7 @@ BINOPTRIO(lshift) BINOPTRIO(rshift) BINOPTRIO(floordiv) BINOPTRIO(truediv) +BINOPTRIO(matmul) CACHED_METHOD(LT, "__lt__", _lt) CACHED_METHOD(GT, "__gt__", _gt) diff --git a/src/opcodes.h b/src/opcodes.h index 2378fef..bb4db24 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -5,6 +5,7 @@ SIMPLE(OP_MULTIPLY) SIMPLE(OP_DIVIDE) SIMPLE(OP_NEGATE) SIMPLE(OP_MODULO) +SIMPLE(OP_MATMUL) SIMPLE(OP_NONE) SIMPLE(OP_TRUE) SIMPLE(OP_FALSE) @@ -57,6 +58,7 @@ SIMPLE(OP_INPLACE_POW) SIMPLE(OP_INPLACE_FLOORDIV) SIMPLE(OP_INPLACE_MODULO) SIMPLE(OP_INPLACE_MULTIPLY) +SIMPLE(OP_INPLACE_MATMUL) CONSTANT(OP_DEFINE_GLOBAL,(void)0) CONSTANT(OP_CONSTANT,(void)0) CONSTANT(OP_GET_GLOBAL,(void)0) diff --git a/src/scanner.c b/src/scanner.c index 419b5bd..052b213 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -349,7 +349,6 @@ KrkToken krk_scanToken() { case ',': return makeToken(TOKEN_COMMA); case '.': return makeToken(TOKEN_DOT); case ';': return makeToken(TOKEN_SEMICOLON); - case '@': return makeToken(TOKEN_AT); case '~': return makeToken(TOKEN_TILDE); case ':': return makeToken(match('=') ? TOKEN_WALRUS : TOKEN_COLON); @@ -365,6 +364,7 @@ KrkToken krk_scanToken() { case '/': return makeToken(match('=') ? TOKEN_SOLIDUS_EQUAL : (match('/') ? (match('=') ? TOKEN_DSOLIDUS_EQUAL : TOKEN_DOUBLE_SOLIDUS) : TOKEN_SOLIDUS)); case '*': return makeToken(match('=') ? TOKEN_ASTERISK_EQUAL: (match('*') ? (match('=') ? TOKEN_POW_EQUAL : TOKEN_POW) : TOKEN_ASTERISK)); case '%': return makeToken(match('=') ? TOKEN_MODULO_EQUAL : TOKEN_MODULO); + case '@': return makeToken(match('=') ? TOKEN_AT_EQUAL : TOKEN_AT); case '"': return string('"'); case '\'': return string('\''); diff --git a/src/vm.c b/src/vm.c index f17d887..2e7105c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1695,6 +1695,7 @@ MAKE_BIN_OP(rshift,">>",rrshift) MAKE_BIN_OP(mod,"%",rmod) MAKE_BIN_OP(truediv,"/",rtruediv) MAKE_BIN_OP(floordiv,"//",rfloordiv) +MAKE_BIN_OP(matmul,"@",rmatmul) MAKE_COMPARE_OP(lt, "<", gt) MAKE_COMPARE_OP(gt, ">", lt) @@ -2636,6 +2637,7 @@ _finishReturn: (void)0; case OP_SHIFTLEFT: BINARY_OP(lshift) case OP_SHIFTRIGHT: BINARY_OP(rshift) case OP_POW: BINARY_OP(pow) + case OP_MATMUL: BINARY_OP(matmul) case OP_EQUAL: BINARY_OP(eq); case OP_IS: BINARY_OP(is); case OP_BITNEGATE: LIKELY_INT_UNARY_OP(invert,~) @@ -2659,6 +2661,7 @@ _finishReturn: (void)0; case OP_INPLACE_SHIFTLEFT: INPLACE_BINARY_OP(lshift) case OP_INPLACE_SHIFTRIGHT: INPLACE_BINARY_OP(rshift) case OP_INPLACE_POW: INPLACE_BINARY_OP(pow) + case OP_INPLACE_MATMUL: INPLACE_BINARY_OP(matmul) case OP_RAISE: { raiseException(krk_peek(0), NONE_VAL());