Skip to content

Commit

Permalink
add humanely, strictly and pendatically to switch coalescing context
Browse files Browse the repository at this point in the history
  • Loading branch information
xrstf committed Dec 2, 2023
1 parent 05a947d commit 6883ec9
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
38 changes: 38 additions & 0 deletions pkg/eval/builtin/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,41 @@ func isEmptyFunction(ctx types.Context, args []ast.Expression) (any, error) {

return !boolified, nil
}

// (strictly EXPR+)
func strictlyFunction(ctx types.Context, args []ast.Expression) (any, error) {
return coalescingChangerFunction(ctx, args, coalescing.NewStrict())
}

// (humanely EXPR+)
func humanelyFunction(ctx types.Context, args []ast.Expression) (any, error) {
return coalescingChangerFunction(ctx, args, coalescing.NewHumane())
}

// (pedantically EXPR+)
func pedanticallyFunction(ctx types.Context, args []ast.Expression) (any, error) {
return coalescingChangerFunction(ctx, args, coalescing.NewPedantic())
}

func coalescingChangerFunction(ctx types.Context, args []ast.Expression, c coalescing.Coalescer) (any, error) {
if size := len(args); size < 1 {
return nil, fmt.Errorf("expected 1+ arguments, got %d", size)
}

tupleCtx := ctx.WithCoalescer(c)

var (
result any
err error
)

// do not use evalArgs(), as we want to inherit the context between expressions
for i, arg := range args {
tupleCtx, result, err = eval.EvalExpression(tupleCtx, arg)
if err != nil {
return nil, fmt.Errorf("argument #%d: %w", i, err)
}
}

return result, nil
}
19 changes: 11 additions & 8 deletions pkg/eval/builtin/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ import (

var Functions = types.Functions{
// core
"default": types.BasicFunction(defaultFunction, "returns the default value if the first argument is empty"),
"delete": deleteFunction{},
"do": types.BasicFunction(doFunction, "eval a sequence of statements where only one expression is valid"),
"empty?": types.BasicFunction(isEmptyFunction, "returns true when the given value is empty-ish (0, false, null, \"\", ...)"),
"has?": types.BasicFunction(hasFunction, "returns true if the given symbol's path expression points to an existing value"),
"if": types.BasicFunction(ifFunction, "evaluate one of two expressions based on a condition"),
"set": types.BasicFunction(setFunction, "set a value in a variable/document, only really useful with ! modifier (set!)"),
"try": types.BasicFunction(tryFunction, "returns the fallback if the first expression errors out"),
"default": types.BasicFunction(defaultFunction, "returns the default value if the first argument is empty"),
"delete": deleteFunction{},
"do": types.BasicFunction(doFunction, "eval a sequence of statements where only one expression is valid"),
"empty?": types.BasicFunction(isEmptyFunction, "returns true when the given value is empty-ish (0, false, null, \"\", ...)"),
"has?": types.BasicFunction(hasFunction, "returns true if the given symbol's path expression points to an existing value"),
"if": types.BasicFunction(ifFunction, "evaluate one of two expressions based on a condition"),
"set": types.BasicFunction(setFunction, "set a value in a variable/document, only really useful with ! modifier (set!)"),
"try": types.BasicFunction(tryFunction, "returns the fallback if the first expression errors out"),
"strictly": types.BasicFunction(strictlyFunction, "evaluates the child expressions using strict coalescing"),
"pedantically": types.BasicFunction(pedanticallyFunction, "evaluates the child expressions using pedantic coalescing"),
"humanely": types.BasicFunction(humanelyFunction, "evaluates the child expressions using humane coalescing"),

// math
"+": types.BasicFunction(sumFunction, "returns the sum of all of its arguments"),
Expand Down
18 changes: 18 additions & 0 deletions pkg/eval/types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ func (c Context) WithVariable(name string, val any) Context {
}
}

func (c Context) WithCoalescer(coalescer coalescing.Coalescer) Context {
return Context{
document: c.document,
funcs: c.funcs,
variables: c.variables,
coalescer: coalescer,
}
}

type Function interface {
Evaluate(ctx Context, args []ast.Expression) (any, error)

Expand Down Expand Up @@ -134,6 +143,15 @@ func (f Functions) Set(name string, fun Function) Functions {
return f
}

// Add adds all functions from other to the current set.
// The function returns the same Functions to allow fluent access.
func (f Functions) Add(other Functions) Functions {
for k, v := range other {
f[k] = v
}
return f
}

func (f Functions) DeepCopy() Functions {
result := NewFunctions()
for key, val := range f {
Expand Down

0 comments on commit 6883ec9

Please sign in to comment.