Skip to content

Commit

Permalink
more overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
ascandone committed Dec 6, 2024
1 parent 80ee485 commit 535a014
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 63 deletions.
110 changes: 65 additions & 45 deletions internal/interpreter/evaluate_expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,21 +148,22 @@ func (st *programState) subOp(left parser.ValueExpr, right parser.ValueExpr) (Va
return (*leftValue).evalSub(st, right)
}

func (st *programState) numOp(left parser.ValueExpr, right parser.ValueExpr, op func(left *big.Int, right *big.Int) Value) (Value, InterpreterError) {
parsedLeft, err := evaluateExprAs(st, left, expectNumber)
func (st *programState) eqOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
parsedLeft, err := evaluateExprAs(st, left, expectAnything)
if err != nil {
return nil, err
}

parsedRight, err := evaluateExprAs(st, right, expectNumber)
parsedRight, err := evaluateExprAs(st, right, expectAnything)
if err != nil {
return nil, err
}

Check warning on line 160 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L159-L160

Added lines #L159 - L160 were not covered by tests

return op(parsedLeft, parsedRight), nil
// TODO remove reflect usage
return Bool(reflect.DeepEqual(parsedLeft, parsedRight)), nil
}

func (st *programState) eqOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
func (st *programState) neqOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
parsedLeft, err := evaluateExprAs(st, left, expectAnything)
if err != nil {
return nil, err
Expand All @@ -174,66 +175,85 @@ func (st *programState) eqOp(left parser.ValueExpr, right parser.ValueExpr) (Val
}

Check warning on line 175 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L174-L175

Added lines #L174 - L175 were not covered by tests

// TODO remove reflect usage
return Bool(reflect.DeepEqual(parsedLeft, parsedRight)), nil
return Bool(!(reflect.DeepEqual(parsedLeft, parsedRight))), nil
}

func (st *programState) neqOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
parsedLeft, err := evaluateExprAs(st, left, expectAnything)
func (st *programState) ltOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
cmp, err := st.evaluateExprAsCmp(left)
if err != nil {
return nil, err
}

Check warning on line 185 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L184-L185

Added lines #L184 - L185 were not covered by tests

parsedRight, err := evaluateExprAs(st, right, expectAnything)
cmpResult, err := (*cmp).evalCmp(st, right)
if err != nil {
return nil, err
}

Check warning on line 190 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L189-L190

Added lines #L189 - L190 were not covered by tests

// TODO remove reflect usage
return Bool(!(reflect.DeepEqual(parsedLeft, parsedRight))), nil
}
switch *cmpResult {
case -1:
return Bool(true), nil
default:
return Bool(false), nil
}

func (st *programState) ltOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
return st.numOp(left, right, func(left, right *big.Int) Value {
switch left.Cmp(right) {
case -1:
return Bool(true)
default:
return Bool(false)
}
})
}

func (st *programState) gtOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
return st.numOp(left, right, func(left, right *big.Int) Value {
switch left.Cmp(right) {
case 1:
return Bool(true)
default:
return Bool(false)
}
})
cmp, err := st.evaluateExprAsCmp(left)
if err != nil {
return nil, err
}

Check warning on line 205 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L204-L205

Added lines #L204 - L205 were not covered by tests

cmpResult, err := (*cmp).evalCmp(st, right)
if err != nil {
return nil, err
}

Check warning on line 210 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L209-L210

Added lines #L209 - L210 were not covered by tests

switch *cmpResult {
case 1:
return Bool(true), nil
default:
return Bool(false), nil
}
}

func (st *programState) lteOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
return st.numOp(left, right, func(left, right *big.Int) Value {
switch left.Cmp(right) {
case -1, 0:
return Bool(true)
default:
return Bool(false)
}
})
cmp, err := st.evaluateExprAsCmp(left)
if err != nil {
return nil, err
}

Check warning on line 224 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L223-L224

Added lines #L223 - L224 were not covered by tests

cmpResult, err := (*cmp).evalCmp(st, right)
if err != nil {
return nil, err
}

Check warning on line 229 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L228-L229

Added lines #L228 - L229 were not covered by tests

switch *cmpResult {
case -1, 0:
return Bool(true), nil
default:
return Bool(false), nil
}

}

func (st *programState) gteOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
return st.numOp(left, right, func(left, right *big.Int) Value {
switch left.Cmp(right) {
case 1, 0:
return Bool(true)
default:
return Bool(false)
}
})
cmp, err := st.evaluateExprAsCmp(left)
if err != nil {
return nil, err
}

Check warning on line 244 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L243-L244

Added lines #L243 - L244 were not covered by tests

cmpResult, err := (*cmp).evalCmp(st, right)
if err != nil {
return nil, err
}

Check warning on line 249 in internal/interpreter/evaluate_expr.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/evaluate_expr.go#L248-L249

Added lines #L248 - L249 were not covered by tests

switch *cmpResult {
case 1, 0:
return Bool(true), nil
default:
return Bool(false), nil
}
}

func (st *programState) andOp(left parser.ValueExpr, right parser.ValueExpr) (Value, InterpreterError) {
Expand Down
64 changes: 54 additions & 10 deletions internal/interpreter/overloads.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,15 @@ func (m MonetaryInt) evalAdd(st *programState, other parser.ValueExpr) (Value, I
}

func (m Monetary) evalAdd(st *programState, other parser.ValueExpr) (Value, InterpreterError) {
m2, err := evaluateExprAs(st, other, expectMonetary)
b2, err := evaluateExprAs(st, other, expectMonetaryOfAsset(string(m.Asset)))
if err != nil {
return nil, err
}

if m.Asset != m2.Asset {
return nil, MismatchedCurrencyError{
Expected: m.Asset.String(),
Got: m2.Asset.String(),
}
}

b1 := big.Int(m.Amount)
sum := new(big.Int).Add(&b1, b2)
return Monetary{
Asset: m.Asset,
Amount: m.Amount.Add(m2.Amount),
Amount: MonetaryInt(*sum),
}, nil

}
Expand Down Expand Up @@ -80,3 +74,53 @@ func (m Monetary) evalSub(st *programState, other parser.ValueExpr) (Value, Inte
}, nil

}

type opCmp interface {
evalCmp(st *programState, other parser.ValueExpr) (*int, InterpreterError)
}

var _ opCmp = (*MonetaryInt)(nil)
var _ opCmp = (*Monetary)(nil)

func (m MonetaryInt) evalCmp(st *programState, other parser.ValueExpr) (*int, InterpreterError) {
b2, err := evaluateExprAs(st, other, expectNumber)
if err != nil {
return nil, err
}

Check warning on line 89 in internal/interpreter/overloads.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/overloads.go#L88-L89

Added lines #L88 - L89 were not covered by tests

b1 := big.Int(m)

cmp := b1.Cmp(b2)
return &cmp, nil
}

func (m Monetary) evalCmp(st *programState, other parser.ValueExpr) (*int, InterpreterError) {
b2, err := evaluateExprAs(st, other, expectMonetaryOfAsset(string(m.Asset)))
if err != nil {
return nil, err
}

Check warning on line 101 in internal/interpreter/overloads.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/overloads.go#L97-L101

Added lines #L97 - L101 were not covered by tests

b1 := big.Int(m.Amount)

cmp := b1.Cmp(b2)
return &cmp, nil

Check warning on line 106 in internal/interpreter/overloads.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/overloads.go#L103-L106

Added lines #L103 - L106 were not covered by tests
}

func (st *programState) evaluateExprAsCmp(expr parser.ValueExpr) (*opCmp, InterpreterError) {
exprCmp, err := evaluateExprAs(st, expr, expectOneOf(
expectMapped(expectMonetary, func(m Monetary) opCmp {
return m
}),

Check warning on line 113 in internal/interpreter/overloads.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/overloads.go#L112-L113

Added lines #L112 - L113 were not covered by tests

// while "x.map(identity)" is the same as "x", just writing "expectNumber" would't typecheck
expectMapped(expectNumber, func(bi big.Int) opCmp {
return MonetaryInt(bi)
}),
))

if err != nil {
return nil, err
}

Check warning on line 123 in internal/interpreter/overloads.go

View check run for this annotation

Codecov / codecov/patch

internal/interpreter/overloads.go#L122-L123

Added lines #L122 - L123 were not covered by tests

return exprCmp, nil
}
8 changes: 0 additions & 8 deletions internal/interpreter/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,6 @@ func NewMonetaryInt(n int64) MonetaryInt {
return MonetaryInt(*bi)
}

func (m MonetaryInt) Add(other MonetaryInt) MonetaryInt {
bi := big.Int(m)
otherBi := big.Int(other)

sum := new(big.Int).Add(&bi, &otherBi)
return MonetaryInt(*sum)
}

func (m MonetaryInt) Sub(other MonetaryInt) MonetaryInt {
bi := big.Int(m)
otherBi := big.Int(other)
Expand Down

0 comments on commit 535a014

Please sign in to comment.