Skip to content
This repository was archived by the owner on Mar 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/expr_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ def visit_Yield(self, node):

_UNARY_OP_TEMPLATES = {
ast.Invert: 'πg.Invert(πF, {operand})',
ast.UAdd: 'πg.Pos(πF, {operand})',
ast.USub: 'πg.Neg(πF, {operand})',
}

Expand Down
6 changes: 1 addition & 5 deletions compiler/expr_visitor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,7 @@ def foo():

testUnaryOpNot = _MakeExprTest('not True')
testUnaryOpInvert = _MakeExprTest('~4')

def testUnaryOpNotImplemented(self):
self.assertRaisesRegexp(util.ParseError, 'unary op not implemented',
_ParseAndVisitExpr, '+foo')

testUnaryOpPos = _MakeExprTest('+4')

def _MakeModuleBlock():
return block.ModuleBlock('__main__', 'grumpy', 'grumpy/lib', '<test>', '',
Expand Down
10 changes: 10 additions & 0 deletions runtime/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,16 @@ func Oct(f *Frame, o *Object) (*Object, *BaseException) {
return o, nil
}

// Pos returns the result of o.__pos__ and is equivalent to the Python
// expression "+o".
func Pos(f *Frame, o *Object) (*Object, *BaseException) {
pos := o.typ.slots.Pos
if pos == nil {
return nil, f.RaiseType(TypeErrorType, fmt.Sprintf("bad operand type for unary +: '%s'", o.typ.Name()))
}
return pos.Fn(f, o)
}

// Print implements the Python print statement. It calls str() on the given args
// and outputs the results to stdout separated by spaces. Similar to the Python
// print statement.
Expand Down
20 changes: 20 additions & 0 deletions runtime/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,26 @@ func TestOct(t *testing.T) {
}
}

func TestPos(t *testing.T) {
pos := newTestClass("pos", []*Type{ObjectType}, newStringDict(map[string]*Object{
"__pos__": newBuiltinFunction("__pos__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
return NewInt(-42).ToObject(), nil
}).ToObject(),
}))
cases := []invokeTestCase{
{args: wrapArgs(42), want: NewInt(42).ToObject()},
{args: wrapArgs(1.2), want: NewFloat(1.2).ToObject()},
{args: wrapArgs(NewLong(big.NewInt(123))), want: NewLong(big.NewInt(123)).ToObject()},
{args: wrapArgs(newObject(pos)), want: NewInt(-42).ToObject()},
{args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "bad operand type for unary +: 'str'")},
}
for _, cas := range cases {
if err := runInvokeTestCase(wrapFuncForTest(Pos), &cas); err != "" {
t.Error(err)
}
}
}

func TestPyPrint(t *testing.T) {
fun := wrapFuncForTest(func(f *Frame, args *Tuple, sep, end string) (string, *BaseException) {
return captureStdout(f, func() *BaseException {
Expand Down
5 changes: 5 additions & 0 deletions runtime/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ func floatNonZero(f *Frame, o *Object) (*Object, *BaseException) {
return GetBool(toFloatUnsafe(o).Value() != 0).ToObject(), nil
}

func floatPos(f *Frame, o *Object) (*Object, *BaseException) {
return o, nil
}

func floatPow(f *Frame, v, w *Object) (*Object, *BaseException) {
return floatArithmeticOp(f, "__pow__", v, w, func(v, w float64) float64 { return math.Pow(v, w) })
}
Expand Down Expand Up @@ -257,6 +261,7 @@ func initFloatType(dict map[string]*Object) {
FloatType.slots.Neg = &unaryOpSlot{floatNeg}
FloatType.slots.New = &newSlot{floatNew}
FloatType.slots.NonZero = &unaryOpSlot{floatNonZero}
FloatType.slots.Pos = &unaryOpSlot{floatPos}
FloatType.slots.Pow = &binaryOpSlot{floatPow}
FloatType.slots.RAdd = &binaryOpSlot{floatRAdd}
FloatType.slots.RDiv = &binaryOpSlot{floatRDiv}
Expand Down
5 changes: 5 additions & 0 deletions runtime/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ func intOr(f *Frame, v, w *Object) (*Object, *BaseException) {
return NewInt(toIntUnsafe(v).Value() | toIntUnsafe(w).Value()).ToObject(), nil
}

func intPos(f *Frame, o *Object) (*Object, *BaseException) {
return o, nil
}

func intPow(f *Frame, v, w *Object) (*Object, *BaseException) {
if w.isInstance(IntType) {
// First try to use the faster floating point arithmetic
Expand Down Expand Up @@ -388,6 +392,7 @@ func initIntType(dict map[string]*Object) {
IntType.slots.NonZero = &unaryOpSlot{intNonZero}
IntType.slots.Oct = &unaryOpSlot{intOct}
IntType.slots.Or = &binaryOpSlot{intOr}
IntType.slots.Pos = &unaryOpSlot{intPos}
IntType.slots.Pow = &binaryOpSlot{intPow}
IntType.slots.RAdd = &binaryOpSlot{intRAdd}
IntType.slots.RAnd = &binaryOpSlot{intAnd}
Expand Down
5 changes: 5 additions & 0 deletions runtime/long.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ func longOr(z, x, y *big.Int) {
z.Or(x, y)
}

func longPos(z, x *big.Int) {
z.Set(x)
}

func longRepr(f *Frame, o *Object) (*Object, *BaseException) {
return NewStr(toLongUnsafe(o).value.Text(10) + "L").ToObject(), nil
}
Expand Down Expand Up @@ -355,6 +359,7 @@ func initLongType(dict map[string]*Object) {
LongType.slots.NonZero = longUnaryBoolOpSlot(longNonZero)
LongType.slots.Oct = &unaryOpSlot{longOct}
LongType.slots.Or = longBinaryOpSlot(longOr)
LongType.slots.Pos = longUnaryOpSlot(longPos)
// This operation can return a float, it must use binaryOpSlot directly.
LongType.slots.Pow = &binaryOpSlot{longPow}
LongType.slots.RAdd = longRBinaryOpSlot(longAdd)
Expand Down
1 change: 1 addition & 0 deletions runtime/slots.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ type typeSlots struct {
NonZero *unaryOpSlot
Oct *unaryOpSlot
Or *binaryOpSlot
Pos *unaryOpSlot
Pow *binaryOpSlot
RAdd *binaryOpSlot
RAnd *binaryOpSlot
Expand Down
23 changes: 23 additions & 0 deletions testing/op_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,28 @@ def TestNeg():
assert -x == -100


def TestPos():
x = 12
assert +x == 12

x = 1.1
assert +x == 1.1

x = 0.0
assert +x == 0.0

x = float('inf')
assert math.isinf(+x)

x = +float('inf')
assert math.isinf(+x)

x = float('nan')
assert math.isnan(+x)

x = long(100)
assert +x == 100


if __name__ == '__main__':
weetest.RunTests()