Fixed bug in which commands could not be assigned to pipeline results
All checks were successful
Test / build (push) Successful in 59s

This commit is contained in:
Leon Mika 2025-05-18 07:39:37 +10:00
parent 33d04ba18d
commit 94aad41712
2 changed files with 48 additions and 14 deletions

View file

@ -105,8 +105,7 @@ type astDot struct {
type astCmd struct { type astCmd struct {
Pos lexer.Position Pos lexer.Position
Name astDot `parser:"@@"` Name astDot `parser:"@@"`
Assign *astDot `parser:"( EQ @@"` InvokeArgs []astDot `parser:"@@*"`
InvokeArgs []astDot `parser:" | @@+ )?"`
} }
type astPipeline struct { type astPipeline struct {
@ -114,9 +113,15 @@ type astPipeline struct {
Rest []*astCmd `parser:"( PIPE @@ )*"` Rest []*astCmd `parser:"( PIPE @@ )*"`
} }
type astAssignOrPipeline struct {
First *astCmd `parser:"@@"`
Assign *astPipeline `parser:"( EQ @@ "`
Pipeline []*astCmd `parser:"| ( PIPE @@ )+ )?"`
}
type astStatements struct { type astStatements struct {
First *astPipeline `parser:"@@"` First *astAssignOrPipeline `parser:"@@"`
Rest []*astPipeline `parser:"( NL+ @@ )*"` // TODO: also add support for newlines Rest []*astAssignOrPipeline `parser:"( NL+ @@ )*"` // TODO: also add support for newlines
} }
type astScript struct { type astScript struct {

View file

@ -32,7 +32,7 @@ func (e evaluator) evalStatement(ctx context.Context, ec *evalCtx, n *astStateme
return nil, nil return nil, nil
} }
res, err := e.evalPipeline(ctx, ec, n.First) res, err := e.evalAssignOrPipeline(ctx, ec, n.First)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -41,7 +41,7 @@ func (e evaluator) evalStatement(ctx context.Context, ec *evalCtx, n *astStateme
} }
for _, rest := range n.Rest { for _, rest := range n.Rest {
out, err := e.evalPipeline(ctx, ec, rest) out, err := e.evalAssignOrPipeline(ctx, ec, rest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -50,6 +50,36 @@ func (e evaluator) evalStatement(ctx context.Context, ec *evalCtx, n *astStateme
return res, nil return res, nil
} }
func (e evaluator) evalAssignOrPipeline(ctx context.Context, ec *evalCtx, n *astAssignOrPipeline) (Object, error) {
switch {
case n.Assign != nil:
// Assignment
assignVal, err := e.evalPipeline(ctx, ec, n.Assign)
if err != nil {
return nil, err
}
return e.assignCmd(ctx, ec, n.First, assignVal)
case len(n.Pipeline) > 0:
res, err := e.evalCmd(ctx, ec, nil, n.First)
if err != nil {
return nil, err
}
for _, rest := range n.Pipeline {
out, err := e.evalCmd(ctx, ec, res, rest)
if err != nil {
return nil, err
}
res = out
}
return res, nil
}
return e.evalCmd(ctx, ec, nil, n.First)
}
func (e evaluator) evalPipeline(ctx context.Context, ec *evalCtx, n *astPipeline) (Object, error) { func (e evaluator) evalPipeline(ctx context.Context, ec *evalCtx, n *astPipeline) (Object, error) {
res, err := e.evalCmd(ctx, ec, nil, n.First) res, err := e.evalCmd(ctx, ec, nil, n.First)
if err != nil { if err != nil {
@ -72,14 +102,6 @@ func (e evaluator) evalPipeline(ctx context.Context, ec *evalCtx, n *astPipeline
func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, currentPipe Object, ast *astCmd) (Object, error) { func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, currentPipe Object, ast *astCmd) (Object, error) {
switch { switch {
case ast.Assign != nil:
// Assignment
assignVal, err := e.evalDot(ctx, ec, *ast.Assign)
if err != nil {
return nil, err
}
return e.assignDot(ctx, ec, ast.Name, assignVal)
case (ast.Name.Arg.Ident != nil) && len(ast.Name.DotSuffix) == 0: case (ast.Name.Arg.Ident != nil) && len(ast.Name.DotSuffix) == 0:
name := ast.Name.Arg.Ident.String() name := ast.Name.Arg.Ident.String()
@ -114,6 +136,13 @@ func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, currentPipe Object,
return nameElem, nil return nameElem, nil
} }
func (e evaluator) assignCmd(ctx context.Context, ec *evalCtx, ast *astCmd, toVal Object) (Object, error) {
if len(ast.InvokeArgs) != 0 {
return nil, errors.New("cannot assign to multiple values")
}
return e.assignDot(ctx, ec, ast.Name, toVal)
}
func (e evaluator) evalInvokable(ctx context.Context, ec *evalCtx, currentPipe Object, ast *astCmd, cmd invokable) (Object, error) { func (e evaluator) evalInvokable(ctx context.Context, ec *evalCtx, currentPipe Object, ast *astCmd, cmd invokable) (Object, error) {
var ( var (
pargs ListObject pargs ListObject