Skip to content
This repository was archived by the owner on Mar 23, 2023. It is now read-only.

Commit 39a7d60

Browse files
authored
Implement ilshift and irshift operators. (#248)
Addresses #56
1 parent b2da45f commit 39a7d60

4 files changed

Lines changed: 24 additions & 0 deletions

File tree

compiler/stmt.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,11 @@ def visit_While(self, node):
571571
ast.Add: 'πg.IAdd(πF, {lhs}, {rhs})',
572572
ast.BitAnd: 'πg.IAnd(πF, {lhs}, {rhs})',
573573
ast.Div: 'πg.IDiv(πF, {lhs}, {rhs})',
574+
ast.LShift: 'πg.ILShift(πF, {lhs}, {rhs})',
574575
ast.Mod: 'πg.IMod(πF, {lhs}, {rhs})',
575576
ast.Mult: 'πg.IMul(πF, {lhs}, {rhs})',
576577
ast.BitOr: 'πg.IOr(πF, {lhs}, {rhs})',
578+
ast.RShift: 'πg.IRShift(πF, {lhs}, {rhs})',
577579
ast.Sub: 'πg.ISub(πF, {lhs}, {rhs})',
578580
ast.BitXor: 'πg.IXor(πF, {lhs}, {rhs})',
579581
}

runtime/core.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,12 @@ func IDiv(f *Frame, v, w *Object) (*Object, *BaseException) {
287287
return inplaceOp(f, v, w, v.typ.slots.IDiv, Div)
288288
}
289289

290+
// ILShift returns the result of v.__ilshift__ if defined, otherwise falls back
291+
// to lshift.
292+
func ILShift(f *Frame, v, w *Object) (*Object, *BaseException) {
293+
return inplaceOp(f, v, w, v.typ.slots.ILShift, LShift)
294+
}
295+
290296
// IMod returns the result of v.__imod__ if defined, otherwise falls back to
291297
// mod.
292298
func IMod(f *Frame, v, w *Object) (*Object, *BaseException) {
@@ -314,6 +320,12 @@ func IOr(f *Frame, v, w *Object) (*Object, *BaseException) {
314320
return inplaceOp(f, v, w, v.typ.slots.IOr, Or)
315321
}
316322

323+
// IRShift returns the result of v.__irshift__ if defined, otherwise falls back
324+
// to rshift.
325+
func IRShift(f *Frame, v, w *Object) (*Object, *BaseException) {
326+
return inplaceOp(f, v, w, v.typ.slots.IRShift, RShift)
327+
}
328+
317329
// IsInstance returns true if the type o is an instance of classinfo, or an
318330
// instance of an element in classinfo (if classinfo is a tuple). It returns
319331
// false otherwise. The argument classinfo must be a type or a tuple whose

runtime/core_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ func TestBinaryOps(t *testing.T) {
8383
"__idiv__": newBuiltinFunction("__idiv__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
8484
return args[1], nil
8585
}).ToObject(),
86+
"__ilshift__": newBuiltinFunction("__ilshift__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
87+
return args[1], nil
88+
}).ToObject(),
8689
"__imod__": newBuiltinFunction("__imod__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
8790
return args[1], nil
8891
}).ToObject(),
@@ -92,6 +95,9 @@ func TestBinaryOps(t *testing.T) {
9295
"__ior__": newBuiltinFunction("__ior__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
9396
return args[1], nil
9497
}).ToObject(),
98+
"__irshift__": newBuiltinFunction("__irshift__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
99+
return args[1], nil
100+
}).ToObject(),
95101
"__isub__": newBuiltinFunction("__isub__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
96102
return args[1], nil
97103
}).ToObject(),
@@ -121,6 +127,7 @@ func TestBinaryOps(t *testing.T) {
121127
{IAnd, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for &: 'object' and 'Foo'")},
122128
{IDiv, NewInt(123).ToObject(), newObject(bazType), NewStr("123").ToObject(), nil},
123129
{IDiv, newObject(inplaceType), NewInt(42).ToObject(), NewInt(42).ToObject(), nil},
130+
{ILShift, newObject(inplaceType), NewInt(123).ToObject(), NewInt(123).ToObject(), nil},
124131
{IMod, NewInt(24).ToObject(), NewInt(6).ToObject(), NewInt(0).ToObject(), nil},
125132
{IMod, newObject(inplaceType), NewFloat(3.14).ToObject(), NewFloat(3.14).ToObject(), nil},
126133
{IMul, NewStr("foo").ToObject(), NewInt(3).ToObject(), NewStr("foofoofoo").ToObject(), nil},
@@ -129,6 +136,7 @@ func TestBinaryOps(t *testing.T) {
129136
{IOr, newObject(inplaceType), NewInt(42).ToObject(), NewInt(42).ToObject(), nil},
130137
{IOr, NewInt(9).ToObject(), NewInt(12).ToObject(), NewInt(13).ToObject(), nil},
131138
{IOr, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for |: 'object' and 'Foo'")},
139+
{IRShift, newObject(inplaceType), NewInt(123).ToObject(), NewInt(123).ToObject(), nil},
132140
{ISub, NewInt(3).ToObject(), NewInt(-3).ToObject(), NewInt(6).ToObject(), nil},
133141
{ISub, newObject(inplaceType), None, None, nil},
134142
{IXor, newObject(inplaceType), None, None, nil},

runtime/slots.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ type typeSlots struct {
392392
IAdd *binaryOpSlot
393393
IAnd *binaryOpSlot
394394
IDiv *binaryOpSlot
395+
ILShift *binaryOpSlot
395396
IMod *binaryOpSlot
396397
IMul *binaryOpSlot
397398
Index *unaryOpSlot
@@ -400,6 +401,7 @@ type typeSlots struct {
400401
Invert *unaryOpSlot
401402
IOr *binaryOpSlot
402403
IPow *binaryOpSlot
404+
IRShift *binaryOpSlot
403405
ISub *binaryOpSlot
404406
Iter *unaryOpSlot
405407
IXor *binaryOpSlot

0 commit comments

Comments
 (0)