Skip to content

Commit

Permalink
added debug logging and better reporting of errors
Browse files Browse the repository at this point in the history
  • Loading branch information
seborama committed May 6, 2024
1 parent 23c9d2a commit 23b5732
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ In addition to boolean expressions, sepcial contants `True` and `False` may be u

Do not double-quote them, or they will become plain strings!

## MultiValue

This is container `Value`. It can contain zero or any number of `Value`'s. Currently, this is only truly useful with functions, mostly because it is yet undecided how to define what operations would mean on a `MultiValue`.

## Supported operations

* Operators: `+` `-` `*` `/` `%` `**` `<<` `>>` `<` `<=` `==` `!=` `>` `>=` `And` `&&` `Or` `||`
Expand All @@ -144,6 +148,7 @@ Do not double-quote them, or they will become plain strings!
* Go classifies bit shift operators with the higher `*`.
* `&&` is synonymous of `And`.
* `||` is synonymous of `Or`.
* Worded operators such as `And` and `Or` are **case-sensitive** and must be followed by a blank character. `True Or (False)` is a Bool expression with the `Or` operator but `True Or(False)` is an invalid expression attempting to call a user-defined function called `Or()`.
* Types: String, Number, Bool, MultiValue
* Associativity with parentheses: `(` and `)`
* Functions:
Expand Down
10 changes: 10 additions & 0 deletions gal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ func TestEval_Boolean(t *testing.T) {
expr = `True Or False`
val = gal.Parse(expr).Eval()
assert.Equal(t, gal.True.String(), val.String())

expr = `True Or (False)`
val = gal.Parse(expr).Eval()
assert.Equal(t, gal.True.String(), val.String())

// in this expression, the `()` are attached to `Or` which makes `Or()` a user-defined
// function, rather than the `Or` operator.
expr = `True Or(False)`
val = gal.Parse(expr).Eval()
assert.Equal(t, `undefined: unknown function 'Or'`, val.String())
}

func TestWithVariablesAndFunctions(t *testing.T) {
Expand Down
23 changes: 21 additions & 2 deletions tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,13 @@ func (tree Tree) Calc(isOperatorInPrecedenceGroup func(Operator) bool, cfg *tree
var val entry
var op Operator = invalidOperator //nolint: stylecheck

slog.Debug("Tree.Calc: start walking Tree", "tree", tree.String())
for i := 0; i < tree.TrunkLen(); i++ {
if v, ok := val.(Undefined); ok {
slog.Debug("Tree.Calc: val is Undefined", "i", i, "val", v.String())
return Tree{v}
}

e := tree[i]
slog.Debug("Tree.Calc: entry in Tree", "i", i, "kind", e.kind().String())
if e == nil {
Expand Down Expand Up @@ -211,6 +217,10 @@ func (tree Tree) Calc(isOperatorInPrecedenceGroup func(Operator) bool, cfg *tree
}

rhsVal := e.(Tree).Eval(WithFunctions(cfg.functions), WithVariables(cfg.variables))
if v, ok := rhsVal.(Undefined); ok {
slog.Debug("Tree.Calc: val is Undefined", "i", i, "val", v.String())
return Tree{v}
}
if val == nil {
val = rhsVal
continue
Expand All @@ -230,6 +240,7 @@ func (tree Tree) Calc(isOperatorInPrecedenceGroup func(Operator) bool, cfg *tree
outTree = append(outTree, val)
}
outTree = append(outTree, op)
// just found and process the current operator - now, reset val and op and start again from fresh
val = nil
op = invalidOperator

Expand All @@ -239,14 +250,20 @@ func (tree Tree) Calc(isOperatorInPrecedenceGroup func(Operator) bool, cfg *tree
if f.BodyFn == nil {
f.BodyFn = cfg.functions.Function(f.Name)
}

rhsVal := f.Eval(WithFunctions(cfg.functions), WithVariables(cfg.variables))
if v, ok := rhsVal.(Undefined); ok {
slog.Debug("Tree.Calc: val is Undefined", "i", i, "val", v.String())
return Tree{v}
}
if val == nil {
val = rhsVal
continue
}

lhsVal := val
val = calculate(val.(Value), op, rhsVal)
slog.Debug("Tree.Calc: functionEntryKind - calculate", "i", i, "val", val.(Value).String(), "op", op.String(), "rhsVal", rhsVal.String(), "result", val.(Value).String())
slog.Debug("Tree.Calc: functionEntryKind - calculate", "i", i, "lhsVal", lhsVal.(Value).String(), "op", op.String(), "rhsVal", rhsVal.String(), "result", val.(Value).String())

case variableEntryKind:
slog.Debug("Tree.Calc: variableEntryKind", "i", i, "name", e.(Variable).Name)
Expand All @@ -268,11 +285,13 @@ func (tree Tree) Calc(isOperatorInPrecedenceGroup func(Operator) bool, cfg *tree
slog.Debug("Tree.Calc: variableEntryKind - calculate", "i", i, "val", val.(Value).String(), "op", op.String(), "rhsVal", rhsVal.String(), "result", val.(Value).String())

case unknownEntryKind:
slog.Debug("Tree.Calc: unknownEntryKind", "i", i, "val", val, "op", op.String(), "e", e)
return Tree{e}

default:
slog.Debug("Tree.Calc: default case", "i", i, "val", val, "op", op.String(), "e", e)
return Tree{
NewUndefinedWithReasonf("internal error: unknown entry kind: '%v'", e.kind()),
NewUndefinedWithReasonf("internal error: unknown entry kind: '%s'", e.kind().String()),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions value.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (m MultiValue) AsString() String {

func (m MultiValue) Get(i int) Value {
if i > len(m.values) {
return NewUndefinedWithReasonf(fmt.Sprintf("out of bounds: trying to get arg #%d on MultiValue that has %d arguments", i, len(m.values)))
return NewUndefinedWithReasonf("out of bounds: trying to get arg #%d on MultiValue that has %d arguments", i, len(m.values))
}

return m.values[i]
Expand Down Expand Up @@ -400,7 +400,7 @@ func (n Number) Trunc(precision int32) Number {

func (n Number) Factorial() Value {
if !n.value.IsInteger() || n.value.IsNegative() {
return NewUndefinedWithReasonf(fmt.Sprintf("Factorial: requires a positive integer, cannot accept %s", n.String()))
return NewUndefinedWithReasonf("Factorial: requires a positive integer, cannot accept %s", n.String())
}

res := decimal.NewFromInt(1)
Expand Down

0 comments on commit 23b5732

Please sign in to comment.