gel

package
v1.2.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2025 License: MIT Imports: 13 Imported by: 0

README

Pango GEL

A Go language expression package.

What is EL?

EL = expression language.
pango/gel calculate this expression and return it's result.

Simple usage
gel.Calculate("3+4*5")  // Output: 23
Variable support
m := map[string]any{"a": 10}
gel.Calculate("a*10", m)  // Output: 100 
Supported operator
Operator Operator Number Priority Description
() * 100 Parenthesis
, * 90 Comma between parameter
@ 2 1 Static method call
. 2 1 Property or method accessor
{1,2} * 1 Java Array
['abc'] 2 1 Object Property or Map Element
[3] 2 1 Number indexed array/collection
* 2 3 Multiply
/ 2 3 Divide
% 2 3 Mod
+ 2 4 Plus
- 2 4 Minus
- 2 2 Negative
>= 2 6 Great Equal
<= 2 5 Less Equal
== 2 7 Equal
!= 2 6 Not Equal
! 2 7 Not
!! 1 7 Ignore exception and return null
> 2 6 Greater
< 2 6 Less
&& 2 11 Logical And
|| 2 12 Logical Or
A|||B 2 12 Return B if A is empty or false, else return A
?: 2 13 Ternary
& 2 8 Bit AND
~ 2 2 Bit NOT
| 2 10 Bit OR
^ 2 9 Bit XOR
<< 2 5 Bit Left Shift
>> 2 5 Bit Right Shift
Like Golang

GEL is completely faithful to Golang basic arithmetic rules and does not do some extensions, such as the most common data type conversions.
In the process of numerical computation in Golang, the type of the operation result is finally determined according to the type of both sides of the operator.

Example:

7/3            // return int
(1.0 * 7)/3    // return float64
Some simple examples
General operation
gel.Calculate("3+2*5") // Output:  13
String manipulation
gel.Calculate("'a'+'b'+'c'") // Output:  abc
struct field
m := map[string]any{
	"pet": struct{
		Name string
	}{"GFW"},
}
gel.Calculate("pet.name", m) // Output:  GFW
Method call
type Pet struct {
	name string
}

func (p *Pet) SetName(name string) {
	p.name = name
}

func (p *Pet) GetName() string {
	return p.name
}

m := map[string]any{
	"pet": &Pet{},
}
gel.Calculate("pet.SetName('XiaoBai')", m)

gel.Calculate("pet.GetName()", m) // Output:  XiaoBai
Array element
m := map[string]any{
	"x": []string { "A", "B", "C" },
}

gel.Calculate("x[0]", m) // Output:  A
Map
m := map[string]any{
	"a": map[string]int{
		"x": 10,
		"y": 5,
	}
}

gel.Calculate("a['x'] * a.y", m) // Output:  50
Logical
m := map[string]any{
	"a": 5,
}

gel.Calculate("a>10", m) // Output:  false

m["a"] = 20
gel.Calculate("a>10", m) // Output:  true
A or B
m := map[string]any{
	"obj": map[string]any{},
}
gel.Calculate("!!(obj.pet.name) ||| 'cat'", m) // Output:  cat
strict mode

Defautly, EL use none strict mode (call method of null object will not cause error)
Example:

m := map[string]any{
	"obj": map[string]any{},
}
gel.Calculate("(obj.pet.name) == nil", m)  // true

Run in strict mode will return error. Example:

m := map[string]any{
	"obj": map[string]any{},
}
gel.CalculateStrict("(obj.pet.name) == nil", m)  // error
How about EL's speed?

I think it's not very fast. The principle of its work is such that each parse passes through 3 steps as below:

  • Parse the expression to a suffix expression array
  • Parse the suffix expression array into a operation tree
  • Evaluate the root node of the operation tree

Of course, I also provide a method to improve efficiency, because if each evaluation passes through these 3 steps is certainly slow, we can precompile it first:

el := gel.Compile("a*10")  // Compile a expression and got a EL instance

m := map[string]any{"a": 10}

el.Calculate(m))  // Output: 100 

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Calculate

func Calculate(expr string, data any) (any, error)

func CalculateStrict

func CalculateStrict(expr string, data any) (any, error)

Types

type EL

type EL struct {
	// contains filtered or unexported fields
}

func Compile

func Compile(expr string) (*EL, error)

func (*EL) Calculate

func (el *EL) Calculate(data any) (any, error)

func (*EL) CalculateStrict

func (el *EL) CalculateStrict(data any) (any, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL