It's very common to evaluate an expression dynamicly, so that's why we are here.

Build Status Coverage Status GoDoc Go Report Card

It's very common to evaluate an expression dynamicly, so that's why we are here.

S-expression

We use s-epxression syntax to parse and evaluate.

In computing, s-expressions, sexprs or sexps (for "symbolic expression") are a notation for nested list (tree-structured) data, invented for and popularized by the programming language Lisp, which uses them for source code as well as data.

For example, for expression in common way: ​ ( (gender = "female") and
((age % 2) != 0) ) it's coresponding format in s-expression is: ​ (and (= gender "female") (!= (% age 2) 0 ) )

Element types within expression

  • number
    For convenience, we treat float64, int64 and so on as type of number. For example, float 100.0 is equal to int 100, but not euqal to string "100"

  • string
    character string quoted with `, ', or " are treated as type of string. You can convert type string to any other defined type you like by type convert functions which are mentioned later

  • function or variable
    character string without quotes are regarded as type of function or variable which depends on whether this function exists. For example in expression (age birthdate), both age and birthdate is unquoted. age is type of function because we have registered a function named age, while birthdate is type of variable for not found. The program will come to errors if there is neither parameter nor function named birthdate when evaluating

How to

You can evaluate directly:

params := evaluator.MapParams{
    "gender": "female",
}
res, err := evaluator.EvalBool(`(in gender ("female" "male"))`, params)
if err != nil {
    log.Fatal(err)
}
fmt.Println(res)
# true	

or you can reuse the Expression to evaluate multiple times:

params := evaluator.MapParams{
    "gender": "female",
}
exp, err := evaluator.New(`(in gender ("female" "male"))`)
if err != nil {
    log.Fatal(err)
}
res, err := exp.EvalBool(params)
if err != nil {
    log.Fatal(err)
}
fmt.Println(res)
# true
And you can write expressions like this
  • (in gender ("male", "female"))

  • (between now (td_time "2017-01-02 12:00:00") (td_time "2017-12-02 12:00:00"))

  • (ne (mod (age birthdate) 7) 5)

  • or multiple-line for clarity

    (and
    	(ne os "ios")
    	(eq gender "male")
    	(beteen version (t_version "2.7.1") (t_version "2.9.1"))
    )
    

Functions

Implemented functions
operand function example description
- in (in 1 (1 2)) also suport array like (in (1) ((1)))
- between (between age 18 20)
- overlap (overlap region (3142 1860))
& and (and (eq gender "femal") (between age 18 20))
` ` or
! not
= eq equal
!= ne not equal
> gt greater than
< lt less than
>= ge greater than or equal to
<= le less than or equal to
% mod
+ - plus
- - minus
* - multiply
/ - divide
- t_version convert type to version
- t_time (t_time "2006-01-02 15:04" "2017-09-09 12:00") convert type to time, first param must be the layout for the time
- td_time (td_time "2017:09:09 12:00:00) convert type to time of default layout format 2006-01-02 15:04:05
_ td_date (in (td_date now) (td_date ("2017-01-02" "2017-02-01")) ) convert type to time of default layout format 2006-01-02

p.s. either operand or function can be used in expression

How to use self-defined functions

Yes, you can write your own function by following thses steps:

  1. implement your function
  2. regist to functions
  3. enjoy it

here is an example:

package main


import (
	"errors"
	"log"
	"time"

	"github.com/nullne/evaluator"
	"github.com/nullne/evaluator/function"
)

// define your own function and don't forget to register
func age(params ...interface{}) (interface{}, error) {
	if len(params) != 1 {
		return nil, errors.New("only one params accepted")
	}
	birth, ok := params[0].(string)
	if !ok {
		return nil, errors.New("birth format need to be string")
	}
	r, err := time.Parse("2006-01-02", birth)
	if err != nil {
		return nil, err
	}
	now := time.Now()
	a := r.Year() - now.Year()
	if r.Month() < now.Month() {
		a--
	} else if r.Month() == now.Month() {
		if r.Day() < now.Day() {
			a--
		}
	}
	return a, nil
}

func main() {
	if err := function.Regist("age", age); err != nil {
		log.Print(err)
	}

	exp := `(not (between (age birthdate) 18 20))`
	vvf := evaluator.MapParams{
		"birthdate": "1980-02-01",
	}
	e, err := evaluator.New(exp)
	if err != nil {
		log.Print(err)
	}
	r, err := e.Eval(vvf)
	if err != nil {
		log.Print(err)
	}
	log.Printf("expression: `%s`, wanna: %+v, got: %+v\r", exp, true, r)
}

Params

  • Params interface, which has a method named Get to get all params needed
  • MapParams a simple implemented Params in map

Bench

BenchmarkEqualString-8   	 3000000	       473 ns/op
BenchmarkInString-8      	 2000000	       916 ns/op
BenchmarkBetweenInt-8    	 3000000	       467 ns/op
BenchmarkBetweenTime-8   	 1000000	      2089 ns/op
BenchmarkOverlapInt-8    	  500000	      2966 ns/op
BenchmarkTypeTime-8      	 2000000	       638 ns/op
BenchmarkTypeVersion-8   	 3000000	       539 ns/op

p.s. on MacBook Pro (Retina, 15-inch, Mid 2015), Memory: 16 GB 1600 MHz DDR3, Processor: 2.2 GHz Intel Core i7

Owner
Le Yu
1LkUJG52jbhpJYP5j332WN9f1oMENTXcHE
Le Yu
Similar Resources

Common Expression Language -- specification and binary representation

The Common Expression Language (CEL) implements common semantics for expression evaluation, enabling different applications to more easily interoperate.

Jan 8, 2023

A very very simple CLI tool to know the next and previous SpaceX flights.

Rocket A very very simple CLI tool to know the next and previous SpaceX flights. Commands rocket Get the next flight. rocket latest Get the last fligh

Apr 19, 2021

A very simple and powerful package for making REST requests with very little effort

Welcome to KRest KRest stands for Keep it simple REST Package. It's a very simple and powerful package wrapper over the standard http package for maki

Dec 1, 2022

Go-Suit is a very very wacky version of a bash terminal but in go, however with a little twitst

Go-Suit Go-Suit is a very very wacky version of a bash terminal but in go, however with a little twitst languages - Go-Lang packages Third Party - g

May 19, 2022

Extract data or evaluate value from HTML/XML documents using XPath

xquery NOTE: This package is deprecated. Recommends use htmlquery and xmlquery package, get latest version to fixed some issues. Overview Golang packa

Nov 9, 2022

Auto-evaluate your Golang code.

Auto-evaluate your Golang code.

Ginker Ginker is a GUI application for auto-evaluating your Golang code. It allows you to write and run Golang code on the fly and it will help you to

Jun 24, 2021

Opsani Ignite for Kubernetes: Evaluate Applications for Optimization

Opsani Ignite for Kubernetes: Evaluate Applications for Optimization

Opsani Ignite for Kubernetes Opsani Ignite analyzes applications running on a Kubernetes cluster in order to identify performance and reliability risk

Aug 5, 2022

Navmux - Test project evaluate writing the equivalent of boat repro using go

navmux Test project evaluate writing the equivalent of boat repro using go. The

Jan 10, 2022

A Telegram bot that asks you a question and evaluate the response you provide.

A Telegram bot that asks you a question and evaluate the response you provide.

PiSquared A Telegram bot that asks you a question and evaluate the response you provide. Thanks to the labse_bert model, the evaluation of the answer

Nov 13, 2022

Common case conversions covering common initialisms.

kace go get "github.com/codemodus/kace" Package kace provides common case conversion functions which take into consideration common initialisms. Usag

Sep 27, 2022

Turbine-common - This package contains the common interfaces for Turbine that are shared with other software

turbine-common This package contains the common interfaces for Turbine that are

Feb 12, 2022

Hprose 1.0 for Golang (Deprecated). Hprose 2.0 for Golang is here:

Hprose for Golang Introduction Installation Usage Http Server Http Client Synchronous Invoking Synchronous Exception Handling Asynchronous Invoking As

Dec 15, 2022

The devs are over here at devzat, chat over SSH!

Devzat Where are the devs at? Devzat! Devzat is chat over SSH Try it out: ssh sshchat.hackclub.com Add this to ~/.ssh/config: Host chat HostName s

Jan 7, 2023

Aboriginal Generics: the future is here!

Aboriginal Generics: the future is here!

Aboriginal Generics: the future is here! Inspired by this gem of an idea (click the image to go to the original comment): Installation go get github.c

Oct 3, 2022

SLOs, Error windows and alerts are complicated. Here an attempt to make it easy

slo-computer SLOs, Error windows and alerts are complicated. Here's an attempt to make it easy SLO, burn_rate, error_rate, budget_spend are convoluted

Dec 30, 2022

Here is the collection of beginner friendly golang projects

Golang Mini Projects for Beginners Here is the collection of beginner friendly golang projects Mini Projects Book Store cli app to list, add, update,

Dec 29, 2022

Here is Go WebAPI

Go WebAPI About I make this Repo just for study purpose, when i was learning Go Language Go WebAPI using several third parties Web Framework, : GIN Gi

Apr 4, 2022

Golang interface for local/remote DRM CDM services (NO DRM IMPLEMENTATION HERE)

NO DRM IMPLEMENTATION HERE! ONLY ABSTRAT INTERFACE! What It's a generalized interface for different types of CDM for WEBDL use. A remote CDM JSON-RPC

Oct 24, 2022

Fast, portable, non-Turing complete expression evaluation with gradual typing (Go)

Common Expression Language The Common Expression Language (CEL) is a non-Turing complete language designed for simplicity, speed, safety, and portabil

Jan 3, 2023
Comments
  • 乘法表达式有问题

    乘法表达式有问题

    func (f SuccessiveBinaryOperator) Eval(params ...interface{}) (interface{}, error) { if l := len(params); l < 2 { return 0.0, fmt.Errorf("SuccessiveBinaryOperator: need at leat two params, but got %d", l) } var res float64 for _, p := range params { v, err := toFloat64(p) if err != nil { return 0.0, fmt.Errorf("SuccessiveBinaryOperator: %+v", err) } switch f.Mode { case ModeAdd: res += v case ModeMultiply: res *= v default: return 0.0, errors.New("SuccessiveBinaryOperator: only support add and multiply") } } return res, nil }

    如果是乘法时 res默认为0 无论乘什么都是0 需要在for循环前添加 if f.Mode==ModeMultiply{ res=1 }

Expression evaluation in golang
Expression evaluation in golang

Gval Gval (Go eVALuate) provides support for evaluating arbitrary expressions, in particular Go-like expressions. Evaluate Gval can evaluate expressio

Dec 27, 2022
Expression evaluation engine for Go: fast, non-Turing complete, dynamic typing, static typing
Expression evaluation engine for Go: fast, non-Turing complete, dynamic typing, static typing

Expr Expr package provides an engine that can compile and evaluate expressions. An expression is a one-liner that returns a value (mostly, but not lim

Dec 30, 2022
Arbitrary expression evaluation for golang

govaluate Provides support for evaluating arbitrary C-like artithmetic/string expressions. Why can't you just write these expressions in code? Sometim

Jan 2, 2023
Logexp - Logical expression compiler for golang

Logical Expression Compiler Functions: - Compile(exp string) - Match(text string

Jan 24, 2022
Suan - Mathematical expression calculation tool

suan Suan( 算 ) is a CLI tool to calculate given mathematical expression. Current

Feb 14, 2022
A toy repo used to test the functionality of "go mod why".

Mod Why Test Discussion From a module perspective: The main module (github.com/ejweber/mod-why-test) has a single direct dependency (github.com/ejwebe

Dec 1, 2021
Go-mongodb - Practice Go with MongoDB because why not

Practice Mongo DB with Go Because why not. Dependencies gin-gonic go mongodb dri

Jan 5, 2022
its a simple backdoor service that im making cuz i think that it could be cool its not finished but this is a cool project
  its a simple backdoor service that im making cuz i think that it could be cool its not finished but this is a cool project

yackdoor its a simple backdoor service that im making cuz i think that it could be cool its not finished but this is a cool project how it looks backd

Aug 18, 2022
a decision & trigger framework backed by Google's Common Expression Language used in graphikDB

a decision & trigger framework backed by Google's Common Expression Language used in graphikDB

Nov 15, 2022