Skip to content

Commit efc7426

Browse files
committed
refactor: unify Func,Macro interfaces to Op interface
1 parent f3d9e28 commit efc7426

File tree

10 files changed

+106
-85
lines changed

10 files changed

+106
-85
lines changed

dsl/deparse.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ func deparse(value types.Value) (interface{}, error) {
4141
case *types.Expr:
4242
a := make([]interface{}, 0, len(val.Args())+1)
4343
// Do not include "@" in array literal
44-
if val.Func().String() != op.ArrayOp.String() {
45-
a = append(a, types.NewString(val.Func().String()))
44+
if val.Op().String() != op.ArrayOp.String() {
45+
a = append(a, types.NewString(val.Op().String()))
4646
}
4747
for i := range a {
4848
v, err := deparse(val.Args()[i])

dsl/op/array.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
package op
22

33
import (
4+
"context"
5+
46
"github.com/vim-volt/volt/dsl/types"
57
)
68

79
func init() {
8-
s := arrayOp("$array")
9-
ArrayOp = &s
10-
macroMap[string(*ArrayOp)] = ArrayOp
10+
opsMap[ArrayOp.String()] = ArrayOp
11+
}
12+
13+
type arrayOp struct {
14+
macroBase
1115
}
1216

13-
type arrayOp string
17+
// ArrayOp is "$array" operator
18+
var ArrayOp = &arrayOp{macroBase("$array")}
1419

15-
// ArrayOp is "$array" operation
16-
var ArrayOp *arrayOp
20+
func (op *arrayOp) InvertExpr(args []types.Value) (types.Value, error) {
21+
return op.macroInvertExpr(op.Execute(context.Background(), args))
22+
}
1723

18-
// String returns "$array"
19-
func (*arrayOp) String() string {
20-
return string(*ArrayOp)
24+
func (*arrayOp) Bind(args ...types.Value) (*types.Expr, error) {
25+
expr := types.NewExpr(ArrayOp, args, types.NewArrayType(types.AnyValue))
26+
return expr, nil
2127
}
2228

23-
// Execute executes "$array" operation
24-
func (*arrayOp) Expand(args []types.Value) (types.Value, func(), error) {
29+
func (*arrayOp) Execute(ctx context.Context, args []types.Value) (types.Value, func(), error) {
2530
return types.NewArray(args, types.AnyValue), NoRollback, nil
2631
}

dsl/op/do.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,22 @@ import (
99
func init() {
1010
opName := doOp("do")
1111
DoOp = &opName
12-
funcMap["do"] = DoOp
12+
opsMap["do"] = DoOp
1313
}
1414

1515
type doOp string
1616

1717
// DoOp is "do" operation
1818
var DoOp *doOp
1919

20-
// String returns operator name
2120
func (*doOp) String() string {
2221
return string(*DoOp)
2322
}
2423

25-
// Bind binds its arguments, and check if the types of values are correct.
24+
func (*doOp) IsMacro() bool {
25+
return false
26+
}
27+
2628
func (*doOp) Bind(args ...types.Value) (*types.Expr, error) {
2729
sig := make([]types.Type, 0, len(args))
2830
for i := 0; i < len(args); i++ {
@@ -35,9 +37,7 @@ func (*doOp) Bind(args ...types.Value) (*types.Expr, error) {
3537
return types.NewExpr(DoOp, args, retType), nil
3638
}
3739

38-
// InvertExpr returns inverted expression: Call Value.Invert() for each argument,
39-
// and reverse arguments order.
40-
func (*doOp) InvertExpr(args []types.Value) (*types.Expr, error) {
40+
func (*doOp) InvertExpr(args []types.Value) (types.Value, error) {
4141
newargs := make([]types.Value, len(args))
4242
for i := range args {
4343
a, err := args[i].Invert()
@@ -49,7 +49,6 @@ func (*doOp) InvertExpr(args []types.Value) (*types.Expr, error) {
4949
return DoOp.Bind(newargs...)
5050
}
5151

52-
// Execute executes "do" operation
5352
func (*doOp) Execute(ctx context.Context, args []types.Value) (val types.Value, rollback func(), err error) {
5453
g := funcGuard(DoOp.String())
5554
defer func() { err = g.rollback(recover()) }()

dsl/op/eval.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,26 @@ import (
77
)
88

99
func init() {
10-
s := evalOp("$eval")
11-
EvalOp = &s
12-
macroMap[string(*EvalOp)] = EvalOp
10+
opsMap[EvalOp.String()] = EvalOp
1311
}
1412

15-
type evalOp string
13+
type evalOp struct {
14+
macroBase
15+
}
16+
17+
// EvalOp is "$eval" operator
18+
var EvalOp = &evalOp{macroBase("$eval")}
1619

17-
// EvalOp is "$eval" operation
18-
var EvalOp *evalOp
20+
func (op *evalOp) InvertExpr(args []types.Value) (types.Value, error) {
21+
return op.macroInvertExpr(op.Execute(context.Background(), args))
22+
}
1923

20-
// String returns "$eval"
21-
func (*evalOp) String() string {
22-
return string(*EvalOp)
24+
func (*evalOp) Bind(args ...types.Value) (*types.Expr, error) {
25+
expr := types.NewExpr(ArrayOp, args, types.NewArrayType(types.AnyValue))
26+
return expr, nil
2327
}
2428

25-
// Execute executes "$eval" operation
26-
func (*evalOp) Expand(args []types.Value) (types.Value, func(), error) {
29+
func (*evalOp) Execute(ctx context.Context, args []types.Value) (types.Value, func(), error) {
2730
if err := signature(types.AnyValue).check(args); err != nil {
2831
return nil, NoRollback, err
2932
}

dsl/op/invert.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
package op
22

33
import (
4+
"context"
5+
46
"github.com/vim-volt/volt/dsl/types"
57
)
68

79
func init() {
8-
s := invertOp("$invert")
9-
InvertOp = &s
10-
macroMap[string(*InvertOp)] = InvertOp
10+
opsMap[InvertOp.String()] = InvertOp
11+
}
12+
13+
type invertOp struct {
14+
macroBase
1115
}
1216

13-
type invertOp string
17+
// InvertOp is "$invert" operator
18+
var InvertOp = &invertOp{macroBase("$invert")}
1419

15-
// InvertOp is "$invert" operation
16-
var InvertOp *invertOp
20+
func (op *invertOp) InvertExpr(args []types.Value) (types.Value, error) {
21+
return op.macroInvertExpr(op.Execute(context.Background(), args))
22+
}
1723

18-
// String returns "$invert"
19-
func (*invertOp) String() string {
20-
return string(*InvertOp)
24+
func (*invertOp) Bind(args ...types.Value) (*types.Expr, error) {
25+
expr := types.NewExpr(ArrayOp, args, types.NewArrayType(types.AnyValue))
26+
return expr, nil
2127
}
2228

23-
// Execute executes "$invert" operation
24-
func (*invertOp) Expand(args []types.Value) (types.Value, func(), error) {
29+
func (*invertOp) Execute(ctx context.Context, args []types.Value) (types.Value, func(), error) {
2530
if err := signature(types.AnyValue).check(args); err != nil {
2631
return nil, NoRollback, err
2732
}

dsl/op/lookup.go

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,12 @@ package op
22

33
import "github.com/vim-volt/volt/dsl/types"
44

5-
// funcMap holds all operation structs.
5+
// opsMap holds all operation structs.
66
// All operations in dsl/op/*.go sets its struct to this in init()
7-
var funcMap map[string]types.Func
7+
var opsMap map[string]types.Op
88

9-
// LookupFunc looks up function name
10-
func LookupFunc(name string) (types.Func, bool) {
11-
op, exists := funcMap[name]
12-
return op, exists
13-
}
14-
15-
// macroMap holds all operation structs.
16-
// All operations in dsl/op/*.go sets its struct to this in init()
17-
var macroMap map[string]types.Macro
18-
19-
// LookupMacro looks up macro name
20-
func LookupMacro(name string) (types.Macro, bool) {
21-
op, exists := macroMap[name]
9+
// Lookup looks up operator name
10+
func Lookup(name string) (types.Op, bool) {
11+
op, exists := opsMap[name]
2212
return op, exists
2313
}

dsl/op/macro.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package op
2+
3+
import (
4+
"github.com/vim-volt/volt/dsl/types"
5+
)
6+
7+
type macroBase string
8+
9+
// String returns "$array"
10+
func (m *macroBase) String() string {
11+
return string(*m)
12+
}
13+
14+
func (*macroBase) IsMacro() bool {
15+
return true
16+
}
17+
18+
// Invert the result of op.Execute() which expands an expression
19+
func (*macroBase) macroInvertExpr(val types.Value, _ func(), err error) (types.Value, error) {
20+
if err != nil {
21+
return nil, err
22+
}
23+
return val.Invert()
24+
}

dsl/parse.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,16 @@ func parseArray(array []interface{}) (types.Value, error) {
5151
}
5252
args = append(args, v)
5353
}
54-
if macro, exists := op.LookupMacro(opName); exists {
55-
val, _, err := macro.Expand(args)
56-
return val, err
54+
op, exists := op.Lookup(opName)
55+
if !exists {
56+
return nil, fmt.Errorf("no such operation '%s'", opName)
5757
}
58-
if fn, exists := op.LookupFunc(opName); exists {
59-
return fn.Bind(args...)
58+
// Expand macro's expression at parsing time
59+
if op.IsMacro() {
60+
val, _, err := op.Execute(args)
61+
return val, err
6062
}
61-
return nil, fmt.Errorf("no such operation '%s'", opName)
63+
return op.Bind(args...)
6264
}
6365

6466
func parse(value interface{}) (types.Value, error) {

dsl/types/expr.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import "context"
44

55
// Expr has an operation and its arguments
66
type Expr struct {
7-
fun Func
7+
op Op
88
args []Value
99
retType Type
1010
}
1111

12-
// Func returns function of Expr
13-
func (expr *Expr) Func() Func {
14-
return expr.fun
12+
// Op returns operator of Expr
13+
func (expr *Expr) Op() Op {
14+
return expr.op
1515
}
1616

1717
// Args returns arguments of Expr
@@ -25,19 +25,19 @@ func (expr *Expr) RetType() Type {
2525
}
2626

2727
// NewExpr creates Expr instance
28-
func NewExpr(fun Func, args []Value, retType Type) *Expr {
29-
return &Expr{fun: fun, args: args, retType: retType}
28+
func NewExpr(op Op, args []Value, retType Type) *Expr {
29+
return &Expr{op: op, args: args, retType: retType}
3030
}
3131

3232
// Eval evaluates given expression expr with given transaction ID trxID.
3333
func (expr *Expr) Eval(ctx context.Context) (val Value, rollback func(), err error) {
34-
return expr.fun.Execute(ctx, expr.args)
34+
return expr.op.Execute(ctx, expr.args)
3535
}
3636

3737
// Invert inverts this expression.
38-
// This just calls Func.InvertExpr() with arguments.
38+
// This just calls Op().InvertExpr() with saved arguments.
3939
func (expr *Expr) Invert() (Value, error) {
40-
return expr.fun.InvertExpr(expr.args)
40+
return expr.op.InvertExpr(expr.args)
4141
}
4242

4343
// Type returns the type.

dsl/types/op.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,20 @@ package types
22

33
import "context"
44

5-
// Func is an operation of JSON DSL
6-
type Func interface {
5+
// Op is an operation of JSON DSL
6+
type Op interface {
77
// String returns function name
88
String() string
99

1010
// InvertExpr returns inverted expression
11-
InvertExpr(args []Value) (*Expr, error)
11+
InvertExpr(args []Value) (Value, error)
1212

13-
// Bind binds its arguments, and check if the types of values are correct.
13+
// Bind binds its arguments, and check if the types of values are correct
1414
Bind(args ...Value) (*Expr, error)
1515

1616
// Execute executes this operation and returns its result value and error
1717
Execute(ctx context.Context, args []Value) (ret Value, rollback func(), err error)
18-
}
19-
20-
// Macro is an operation of JSON DSL
21-
type Macro interface {
22-
// String returns macro name
23-
String() string
2418

25-
// Expand expands this expression (operator + args).
26-
// If argument type or arity is different, this returns non-nil error.
27-
Expand(args []Value) (val Value, rollback func(), err error)
19+
// IsMacro returns true if this operator is a macro
20+
IsMacro() bool
2821
}

0 commit comments

Comments
 (0)