Skip to content

Commit

Permalink
ast: IndexExpr and SliceExpr (#5100)
Browse files Browse the repository at this point in the history
This commit makes index and slice expressions their own ast Nodes instead
of representing them as BinaryExpr.
  • Loading branch information
mattnibs authored Apr 8, 2024
1 parent aeeb21a commit f1fa646
Show file tree
Hide file tree
Showing 11 changed files with 3,624 additions and 2,921 deletions.
15 changes: 15 additions & 0 deletions compiler/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ type Cast struct {
Type Expr `json:"type"`
}

type IndexExpr struct {
Kind string `json:"kind" unpack:""`
Expr Expr `json:"expr"`
Index Expr `json:"index"`
}

type SliceExpr struct {
Kind string `json:"kind" unpack:""`
Expr Expr `json:"expr"`
From Expr `json:"from"`
To Expr `json:"to"`
}

type Grep struct {
Kind string `json:"kind" unpack:""`
Pattern Expr `json:"pattern"`
Expand Down Expand Up @@ -187,6 +200,8 @@ func (*Conditional) ExprAST() {}
func (*Call) ExprAST() {}
func (*Cast) ExprAST() {}
func (*ID) ExprAST() {}
func (*IndexExpr) ExprAST() {}
func (*SliceExpr) ExprAST() {}

func (*Assignment) ExprAST() {}
func (*Agg) ExprAST() {}
Expand Down
13 changes: 13 additions & 0 deletions compiler/ast/dag/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ type (
Params []string `json:"params"`
Expr Expr `json:"expr"`
}
IndexExpr struct {
Kind string `json:"kind" unpack:""`
Expr Expr `json:"expr"`
Index Expr `json:"index"`
}
Literal struct {
Kind string `json:"kind" unpack:""`
Value string `json:"value"`
Expand Down Expand Up @@ -101,6 +106,12 @@ type (
Kind string `json:"kind" unpack:""`
Elems []VectorElem `json:"elems"`
}
SliceExpr struct {
Kind string `json:"kind" unpack:""`
Expr Expr `json:"expr"`
From Expr `json:"from"`
To Expr `json:"to"`
}
This struct {
Kind string `json:"kind" unpack:""`
Path []string `json:"path"`
Expand All @@ -125,6 +136,7 @@ func (*Call) ExprDAG() {}
func (*Conditional) ExprDAG() {}
func (*Dot) ExprDAG() {}
func (*Func) ExprDAG() {}
func (*IndexExpr) ExprDAG() {}
func (*Literal) ExprDAG() {}
func (*MapCall) ExprDAG() {}
func (*MapExpr) ExprDAG() {}
Expand All @@ -134,6 +146,7 @@ func (*RegexpMatch) ExprDAG() {}
func (*RegexpSearch) ExprDAG() {}
func (*Search) ExprDAG() {}
func (*SetExpr) ExprDAG() {}
func (*SliceExpr) ExprDAG() {}
func (*This) ExprDAG() {}
func (*UnaryExpr) ExprDAG() {}
func (*Var) ExprDAG() {}
Expand Down
2 changes: 2 additions & 0 deletions compiler/ast/dag/unpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var unpacker = unpack.New(
Fuse{},
Head{},
HTTPScan{},
IndexExpr{},
Join{},
Lister{},
Literal{},
Expand All @@ -49,6 +50,7 @@ var unpacker = unpack.New(
SeqScan{},
SetExpr{},
Shape{},
SliceExpr{},
Slicer{},
Sort{},
Spread{},
Expand Down
2 changes: 2 additions & 0 deletions compiler/ast/unpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var unpacker = unpack.New(
HTTP{},
ID{},
astzed.ImpliedValue{},
IndexExpr{},
Join{},
Load{},
Merge{},
Expand Down Expand Up @@ -65,6 +66,7 @@ var unpacker = unpack.New(
Spread{},
SQLExpr{},
SQLOrderBy{},
SliceExpr{},
Sort{},
String{},
OpDecl{},
Expand Down
42 changes: 25 additions & 17 deletions compiler/kernel/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ func (b *Builder) compileExpr(e dag.Expr) (expr.Evaluator, error) {
return b.compileConditional(*e)
case *dag.Call:
return b.compileCall(*e)
case *dag.IndexExpr:
return b.compileIndexExpr(e)
case *dag.SliceExpr:
return b.compileSliceExpr(e)
case *dag.RegexpMatch:
return b.compileRegexpMatch(e)
case *dag.RegexpSearch:
Expand Down Expand Up @@ -108,9 +112,6 @@ func (b *Builder) compileExprWithEmpty(e dag.Expr) (expr.Evaluator, error) {
}

func (b *Builder) compileBinary(e *dag.BinaryExpr) (expr.Evaluator, error) {
if slice, ok := e.RHS.(*dag.BinaryExpr); ok && slice.Op == ":" {
return b.compileSlice(e.LHS, slice)
}
if e.Op == "in" {
// Do a faster comparison if the LHS is a compile-time constant expression.
if in, err := b.compileConstIn(e); in != nil && err == nil {
Expand Down Expand Up @@ -141,8 +142,6 @@ func (b *Builder) compileBinary(e *dag.BinaryExpr) (expr.Evaluator, error) {
return expr.NewCompareRelative(b.zctx(), lhs, rhs, op)
case "+", "-", "*", "/", "%":
return expr.NewArithmetic(b.zctx(), lhs, rhs, op)
case "[":
return expr.NewIndexExpr(b.zctx(), lhs, rhs), nil
default:
return nil, fmt.Errorf("invalid binary operator %s", op)
}
Expand Down Expand Up @@ -210,16 +209,16 @@ func (b *Builder) compileSearch(search *dag.Search) (expr.Evaluator, error) {
return expr.NewSearch(search.Text, val, e)
}

func (b *Builder) compileSlice(container dag.Expr, slice *dag.BinaryExpr) (expr.Evaluator, error) {
from, err := b.compileExprWithEmpty(slice.LHS)
func (b *Builder) compileSliceExpr(slice *dag.SliceExpr) (expr.Evaluator, error) {
e, err := b.compileExpr(slice.Expr)
if err != nil {
return nil, err
}
to, err := b.compileExprWithEmpty(slice.RHS)
from, err := b.compileExprWithEmpty(slice.From)
if err != nil {
return nil, err
}
e, err := b.compileExpr(container)
to, err := b.compileExprWithEmpty(slice.To)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -267,20 +266,17 @@ func (b *Builder) compileDotExpr(dot *dag.Dot) (expr.Evaluator, error) {

func (b *Builder) compileLval(e dag.Expr) (*expr.Lval, error) {
switch e := e.(type) {
case *dag.BinaryExpr:
if e.Op != "[" {
return nil, fmt.Errorf("internal error: invalid lval %#v", e)
}
lhs, err := b.compileLval(e.LHS)
case *dag.IndexExpr:
container, err := b.compileLval(e.Expr)
if err != nil {
return nil, err
}
rhs, err := b.compileExpr(e.RHS)
index, err := b.compileExpr(e.Index)
if err != nil {
return nil, err
}
lhs.Elems = append(lhs.Elems, expr.NewExprLvalElem(b.zctx(), rhs))
return lhs, nil
container.Elems = append(container.Elems, expr.NewExprLvalElem(b.zctx(), index))
return container, nil
case *dag.Dot:
lhs, err := b.compileLval(e.LHS)
if err != nil {
Expand Down Expand Up @@ -374,6 +370,18 @@ func (b *Builder) compileExprs(in []dag.Expr) ([]expr.Evaluator, error) {
return exprs, nil
}

func (b *Builder) compileIndexExpr(e *dag.IndexExpr) (expr.Evaluator, error) {
container, err := b.compileExpr(e.Expr)
if err != nil {
return nil, err
}
index, err := b.compileExpr(e.Index)
if err != nil {
return nil, err
}
return expr.NewIndexExpr(b.zctx(), container, index), nil
}

func (b *Builder) compileRegexpMatch(match *dag.RegexpMatch) (expr.Evaluator, error) {
e, err := b.compileExpr(match.Expr)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion compiler/parser/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ endif
ifeq "$(shell go version -m $(deps)/bin/pigeon 2>&1 | fgrep $(PIGEON_VERSION))" ""
GOBIN=$(deps)/bin go install github.com/mna/pigeon@$(PIGEON_VERSION)
endif
$(cpp) -DGO parser.peg | $(deps)/bin/pigeon -o $@
$(cpp) -DGO parser.peg | $(deps)/bin/pigeon -support-left-recursion -o $@
$(deps)/bin/goimports -w $@
Loading

0 comments on commit f1fa646

Please sign in to comment.