package object import "fmt" type Integer struct { Value int64 } func (i Integer) Bool() bool { return i.Value != 0 } func (i Integer) Type() Type { return IntegerType } func (i Integer) Inspect() string { return fmt.Sprintf("%d", i.Value) } func (i Integer) Copy() Object { return Integer{Value: i.Value} } // Hash implements the Hasher interface func (i Integer) Hash() HashKey { return HashKey{Type: i.Type(), Value: uint64(i.Value)} } func (i Integer) String() string { return i.Inspect() } func (i Integer) Add(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value + obj.Value}, nil case Float: return Float{float64(i.Value) + obj.Value}, nil default: return nil, NewBinaryOpError(i, other, "+") } } func (i Integer) Sub(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value - obj.Value}, nil case Float: return Float{float64(i.Value) - obj.Value}, nil default: return nil, NewBinaryOpError(i, other, "-") } } func (i Integer) Mul(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value * obj.Value}, nil case Float: return Float{float64(i.Value) * obj.Value}, nil case String: return obj.Mul(i) case *Array: return obj.Mul(i) default: return nil, NewBinaryOpError(i, other, "*") } } func (i Integer) Div(other Object) (Object, error) { switch obj := other.(type) { case Integer: if obj.Value == 0 { return nil, NewDivisionByZeroError(i) } return Integer{i.Value / obj.Value}, nil case Float: if obj.Value == 0.0 { return nil, NewDivisionByZeroError(i) } return Float{float64(i.Value) / obj.Value}, nil default: return nil, NewBinaryOpError(i, other, "/") } } func (i Integer) Mod(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value % obj.Value}, nil case Float: return Float{float64(i.Value % int64(obj.Value))}, nil default: return nil, NewBinaryOpError(i, other, "%") } } func (i Integer) BitwiseOr(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value | obj.Value}, nil default: return nil, NewBinaryOpError(i, other, "|") } } func (i Integer) BitwiseXor(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value ^ obj.Value}, nil default: return nil, NewBinaryOpError(i, other, "^") } } func (i Integer) BitwiseAnd(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value & obj.Value}, nil default: return nil, NewBinaryOpError(i, other, "") } } func (i Integer) BitwiseNot() Object { return Integer{^i.Value} } func (i Integer) LeftShift(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value << obj.Value}, nil default: return nil, NewBinaryOpError(i, other, "<<") } } func (i Integer) RightShift(other Object) (Object, error) { switch obj := other.(type) { case Integer: return Integer{i.Value >> obj.Value}, nil default: return nil, NewBinaryOpError(i, other, ">>") } } func (i Integer) LogicalNot() Object { return Boolean{!i.Bool()} } func (i Integer) Negate() Object { return Integer{-i.Value} } func (i Integer) Compare(other Object) int { switch obj := other.(type) { case Integer: if i.Value < obj.Value { return -1 } if i.Value > obj.Value { return 1 } return 0 default: return -1 } }