-
Notifications
You must be signed in to change notification settings - Fork 15
/
expr_offset.go
50 lines (43 loc) · 1.28 KB
/
expr_offset.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package rel
import (
"context"
"fmt"
"github.com/arr-ai/wbnf/parser"
"github.com/go-errors/errors"
)
// OffsetExpr is an expression which offsets the provided array by the
// provided offset
type OffsetExpr struct {
ExprScanner
offset, array Expr
}
// NewOffsetExpr returns a new OffsetExpr
func NewOffsetExpr(scanner parser.Scanner, n, s Expr) Expr {
return &OffsetExpr{ExprScanner{scanner}, n, s}
}
func (o *OffsetExpr) Eval(ctx context.Context, local Scope) (_ Value, err error) {
offset, err := o.offset.Eval(ctx, local)
if err != nil {
return nil, WrapContextErr(err, o, local)
}
_, isNumber := offset.(Number)
if !isNumber {
return nil, WrapContextErr(errors.Errorf("\\ not applicable to %T", offset), o, local)
}
array, err := o.array.Eval(ctx, local)
if err != nil {
return nil, WrapContextErr(err, o, local)
}
switch a := array.(type) {
case Array:
return NewOffsetArray(a.offset+int(offset.(Number)), a.values...), nil
case Bytes:
return NewOffsetBytes(a.Bytes(), a.offset+int(offset.(Number))), nil
case String:
return NewOffsetString(a.s, a.offset+int(offset.(Number))), nil
}
return nil, WrapContextErr(errors.Errorf("\\ not applicable to %T", array), o, local)
}
func (o *OffsetExpr) String() string {
return fmt.Sprintf("(%s <: %s)", o.offset, o.array)
}