Skip to content

Commit 3e9893b

Browse files
committed
Update documentation
1 parent 107f6ef commit 3e9893b

File tree

6 files changed

+287
-257
lines changed

6 files changed

+287
-257
lines changed

docs/Getting-Started.md

Lines changed: 82 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Getting Started
22

3-
**Expr** provides a package for evaluating arbitrary expressions as well as type
4-
checking of such expression.
3+
**Expr** is a simple, fast and extensible expression language for Go. It is
4+
designed to be easy to use and integrate into your application.
5+
56

67
## Evaluate
78

@@ -34,22 +35,11 @@ func main() {
3435

3536
## Compile
3637

37-
Usually we want to compile, type check and verify what the expression returns a
38-
boolean (or another type).
39-
40-
For example, if a user saves an expression from a
38+
Usually, we want to compile, type check and verify that the expression returns a
39+
boolean (or another type). For example, if a user saves an expression from a
4140
[web UI](https://antonmedv.github.io/expr/).
4241

4342
```go
44-
package main
45-
46-
import (
47-
"fmt"
48-
49-
"github.com/antonmedv/expr"
50-
)
51-
52-
func main() {
5343
env := map[string]interface{}{
5444
"greet": "Hello, %v!",
5545
"names": []string{"world", "you"},
@@ -58,8 +48,8 @@ func main() {
5848

5949
code := `sprintf(greet, names[0])`
6050

61-
// Compile the code into a bytecode. This step can be done once
62-
// and program may be reused. Specify an environment for type check.
51+
// Compile the code into a bytecode. This step can be done only once and
52+
// the program may be reused. Specify an environment for the type check.
6353
program, err := expr.Compile(code, expr.Env(env))
6454
if err != nil {
6555
panic(err)
@@ -71,40 +61,28 @@ func main() {
7161
}
7262

7363
fmt.Print(output)
74-
}
7564
```
7665

77-
You may use existing types.
78-
79-
For example, an environment can be a struct. And structs methods can be used as
80-
functions. Expr supports embedded structs and methods defines on them too.
66+
An environment can be a struct and structs methods can be used as
67+
functions. Expr supports embedded structs and methods defined on them too.
8168

8269
The struct fields can be renamed by adding struct tags such as `expr:"name"`.
8370

8471
```go
85-
package main
86-
87-
import (
88-
"fmt"
89-
"time"
90-
91-
"github.com/antonmedv/expr"
92-
)
93-
9472
type Env struct {
95-
Tweets []Tweet
73+
Messages []Message `expr:"messages"`
9674
}
9775

9876
// Methods defined on the struct become functions.
9977
func (Env) Format(t time.Time) string { return t.Format(time.RFC822) }
10078

101-
type Tweet struct {
79+
type Message struct {
10280
Text string
103-
Date time.Time `expr:"timestamp"`
81+
Date time.Time
10482
}
10583

10684
func main() {
107-
code := `map(filter(Tweets, {len(.Text) > 0}), {.Text + Format(.timestamp)})`
85+
code := `map(filter(messages, len(.Text) > 0), .Text + Format(.timestamp))`
10886

10987
// We can use an empty instance of the struct as an environment.
11088
program, err := expr.Compile(code, expr.Env(Env{}))
@@ -113,7 +91,7 @@ func main() {
11391
}
11492

11593
env := Env{
116-
Tweets: []Tweet{
94+
Messages: []Message{
11795
{"Oh My God!", time.Now()},
11896
{"How you doin?", time.Now()},
11997
{"Could I be wearing any more clothes?", time.Now()},
@@ -129,4 +107,72 @@ func main() {
129107
}
130108
```
131109

110+
## Configuration
111+
112+
Expr can be configured to do more things. For example, with [AllowUndefinedVariables](https://pkg.go.dev/github.com/antonmedv/expr#AllowUndefinedVariables) or [AsBool](https://pkg.go.dev/github.com/antonmedv/expr#AsBool) to expect the boolean result from the expression.
113+
114+
```go
115+
program, err := expr.Compile(code, expr.Env(Env{}), expr.AllowUndefinedVariables(), expr.AsBool())
116+
```
117+
118+
## Functions
119+
120+
Expr supports any Go functions. For example, you can use `fmt.Sprintf` or methods of your structs.
121+
Also, Expr supports functions configured via [`expr.Function(name, fn[, ...types])`](https://pkg.go.dev/github.com/antonmedv/expr#Function) option.
122+
123+
```go
124+
atoi := expr.Function(
125+
"atoi",
126+
func(params ...any) (any, error) {
127+
return strconv.Atoi(params[0].(string))
128+
},
129+
)
130+
131+
program, err := expr.Compile(`atoi("42")`, atoi)
132+
```
133+
134+
Expr sees the `atoi` function as a function with a variadic number of arguments of type `any` and returns a value of type `any`. But, we can specify the types of arguments and the return value by adding the correct function
135+
signature or multiple signatures.
136+
137+
```go
138+
atoi := expr.Function(
139+
"atoi",
140+
func(params ...any) (any, error) {
141+
return strconv.Atoi(params[0].(string))
142+
},
143+
new(func(string) int),
144+
)
145+
```
146+
147+
Or we can simply reuse the `strconv.Atoi` function.
148+
149+
```go
150+
atoi := expr.Function(
151+
"atoi",
152+
func(params ...any) (any, error) {
153+
return strconv.Atoi(params[0].(string))
154+
},
155+
strconv.Atoi,
156+
)
157+
```
158+
159+
Here is another example with a few function signatures:
160+
161+
```go
162+
toInt := expr.Function(
163+
"toInt",
164+
func(params ...any) (any, error) {
165+
switch params[0].(type) {
166+
case float64:
167+
return int(params[0].(float64)), nil
168+
case string:
169+
return strconv.Atoi(params[0].(string))
170+
}
171+
return nil, fmt.Errorf("invalid type")
172+
},
173+
new(func(float64) int),
174+
new(func(string) int),
175+
)
176+
```
177+
132178
* Next: [Operator Overloading](Operator-Overloading.md)

docs/Internals.md

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# Internals
22

3-
Expr is a stack based virtual machine. It compiles expressions to bytecode and
4-
runs it.
5-
6-
Compilation is done in a few steps:
3+
Expr is a stack-based virtual machine. It compiles expressions to bytecode and
4+
runs it. The compilation is done in a few steps:
75

86
- Parse expression to AST
97
- Type check AST
@@ -12,72 +10,70 @@ Compilation is done in a few steps:
1210
- Optimize AST
1311
- Compile AST to a bytecode
1412

15-
Compiler has a bunch of optimization which will produce a more optimal program.
13+
The compiler has a bunch of optimization which will produce a more optimal program.
1614

1715
## In array
1816

19-
```js
17+
```
2018
value in ['foo', 'bar', 'baz']
2119
```
2220

2321
If Expr finds an `in` or `not in` expression with an array, it will be
2422
transformed into:
2523

26-
```js
24+
```
2725
value in {"foo": true, "bar": true, "baz": true}
2826
```
2927

3028
## Constant folding
3129

32-
Arithmetic expressions with constants is computed on compile step and replaced
30+
Arithmetic expressions with constants are computed on compile step and replaced
3331
with the result.
3432

35-
```js
33+
```
3634
-(2 - 5) ** 3 - 2 / (+4 - 3) + -2
3735
```
3836

39-
Will be compiled to just single number:
37+
Will be compiled into just a single number:
4038

41-
```js
39+
```
4240
23
4341
```
4442

4543
## In range
4644

47-
```js
48-
user.Age in 18.
49-
.32
45+
```
46+
user.Age in 18..32
5047
```
5148

5249
Will be replaced with a binary operator:
5350

54-
```js
51+
```
5552
18 <= user.Age && user.Age <= 32
5653
```
5754

5855
## Const range
5956

60-
```js
61-
1.
62-
.10_000
57+
```
58+
1..10_000
6359
```
6460

65-
Ranges computed on compile stage, replaced with precreated slices.
61+
Ranges computed on the compile stage, are replaced with pre-created slices.
6662

6763
## Const expr
6864

69-
If some function marked as constant expression with `expr.ConstExpr`. It will be
70-
replaced with result of the call, if all arguments are constants.
65+
If some function is marked as a constant expression with `expr.ConstExpr`. It will be
66+
replaced with the result of the call if all arguments are constants.
7167

7268
```go
7369
expr.ConstExpt("fib")
7470
```
7571

76-
```js
72+
```
7773
fib(42)
7874
```
7975

80-
Will be replaced with result of `fib(42)` on the compile step.
76+
Will be replaced with the result of `fib`(42)` on the compile step.
8177

8278
[ConstExpr Example](https://pkg.go.dev/github.com/antonmedv/expr?tab=doc#ConstExpr)
8379

0 commit comments

Comments
 (0)