Alternate signing constructs #1
			
				
			
		
		
		
	
							
								
								
									
										13
									
								
								ucl/ast.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								ucl/ast.go
									
									
									
									
									
								
							|  | @ -105,8 +105,7 @@ type astDot struct { | |||
| type astCmd struct { | ||||
| 	Pos        lexer.Position | ||||
| 	Name       astDot   `parser:"@@"` | ||||
| 	Assign     *astDot  `parser:"( EQ @@"` | ||||
| 	InvokeArgs []astDot `parser:" | @@+ )?"` | ||||
| 	InvokeArgs []astDot `parser:"@@*"` | ||||
| } | ||||
| 
 | ||||
| type astPipeline struct { | ||||
|  | @ -114,9 +113,15 @@ type astPipeline struct { | |||
| 	Rest  []*astCmd `parser:"( PIPE @@ )*"` | ||||
| } | ||||
| 
 | ||||
| type astAssignOrPipeline struct { | ||||
| 	First    *astCmd      `parser:"@@"` | ||||
| 	Assign   *astPipeline `parser:"( EQ @@ "` | ||||
| 	Pipeline []*astCmd    `parser:"| ( PIPE @@ )+ )?"` | ||||
| } | ||||
| 
 | ||||
| type astStatements struct { | ||||
| 	First *astPipeline   `parser:"@@"` | ||||
| 	Rest  []*astPipeline `parser:"( NL+ @@ )*"` // TODO: also add support for newlines
 | ||||
| 	First *astAssignOrPipeline   `parser:"@@"` | ||||
| 	Rest  []*astAssignOrPipeline `parser:"( NL+ @@ )*"` // TODO: also add support for newlines
 | ||||
| } | ||||
| 
 | ||||
| type astScript struct { | ||||
|  |  | |||
							
								
								
									
										49
									
								
								ucl/eval.go
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								ucl/eval.go
									
									
									
									
									
								
							|  | @ -32,7 +32,7 @@ func (e evaluator) evalStatement(ctx context.Context, ec *evalCtx, n *astStateme | |||
| 		return nil, nil | ||||
| 	} | ||||
| 
 | ||||
| 	res, err := e.evalPipeline(ctx, ec, n.First) | ||||
| 	res, err := e.evalAssignOrPipeline(ctx, ec, n.First) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -41,7 +41,7 @@ func (e evaluator) evalStatement(ctx context.Context, ec *evalCtx, n *astStateme | |||
| 	} | ||||
| 
 | ||||
| 	for _, rest := range n.Rest { | ||||
| 		out, err := e.evalPipeline(ctx, ec, rest) | ||||
| 		out, err := e.evalAssignOrPipeline(ctx, ec, rest) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | @ -50,6 +50,36 @@ func (e evaluator) evalStatement(ctx context.Context, ec *evalCtx, n *astStateme | |||
| 	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) { | ||||
| 	res, err := e.evalCmd(ctx, ec, nil, n.First) | ||||
| 	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) { | ||||
| 	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: | ||||
| 		name := ast.Name.Arg.Ident.String() | ||||
| 
 | ||||
|  | @ -114,6 +136,13 @@ func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, currentPipe Object, | |||
| 	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) { | ||||
| 	var ( | ||||
| 		pargs   ListObject | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue