# evaler

https://github.com/soniah/evaler

Package evaler implements a simple floating point arithmetic expression evaluator.

Evaler uses Dijkstra's Shunting Yard algorithm to convert an infix expression to postfix/RPN format, then evaluates the RPN expression. The implementation is adapted from a Java implementation. The results are returned as a `*big.Rat`

.

## Usage

`result, err := evaler.Eval("1+2")`

## Operators

The operators supported are:

`+ - * / ^ ** () < > <= >= == !=`

(`^`

and `**`

are both exponent operators)

Logical operators like `<`

(less than) or `>`

(greater than) get lowest precedence, all other precedence is as expected - BODMAS.

Logical tests like `<`

and `>`

tests will evaluate to 0.0 for false and 1.0 for true, allowing expressions like:

```
3 * (1 < 2) # returns 3.0
3 * (1 > 2) # returns 0.0
```

Minus implements both binary and unary operations.

See `evaler_test.go`

for more examples of using operators.

## Trigonometric Operators

The trigonometric operators supported are:

`sin, cos, tan, ln, arcsin, arccos, arctan`

For example:

```
cos(1)
sin(2-1)
sin(1)+2**2
```

See `evaler_test.go`

for more examples of using trigonometric operators.

## Variables

`EvalWithVariables()`

allows variables to be passed into expressions, for example evaluate `"x + 1"`

, where `x=5`

.

See `evaler_test.go`

for more examples of using variables.

## Issues

The `math/big`

library doesn't have an exponent function `**`

and implenting one for `big.Rat`

numbers is non-trivial. As a work around, arguments are converted to float64's, the calculation is done using the `math.Pow()`

function, the result is converted to a `big.Rat`

and placed back on the stack.

- floating point numbers missing leading digits (like
`".5 * 2"`

) are failing - PR's welcome

## Documentation

http://godoc.org/github.com/soniah/evaler

There are also a number of utility functions e.g. `BigratToFloat()`

, `BigratToInt()`

that may be useful when working with evaler.

## Contributions

Contributions are welcome.

If you've never contributed to a Go project before here is an example workflow.

- fork this repo on the GitHub webpage
`go get github.com/soniah/evaler`

`cd $GOPATH/src/github.com/soniah/evaler`

`git remote rename origin upstream`

`git remote add origin [email protected]:<your-github-username>/evaler.git`

`git checkout -b development`

`git push -u origin development`

(setup where you push to, check it works)

## Author

Sonia Hamilton [email protected]

Dem Waffles [email protected] - trigonometric operators

## License

Modified BSD License (BSD-3)

## Links

[1] http://en.wikipedia.org/wiki/Shunting-yard_algorithm

[2] http://en.wikipedia.org/wiki/Reverse_Polish_notation