mathcat

package module
v0.0.0-...-588f3d3 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2020 License: MIT Imports: 7 Imported by: 8

README

mathcat Build Status GoDoc

mathcat is an expression evaluating library and REPL in Go with basic arithmetic, functions, variables and more.

Features

mathcat doesn't just evaluate basic expressions, it has some tricks up its sleeve. Here's a list with some of its features:

  • Hex literals (0xDEADBEEF)
  • Binary literals (0b1101001)
  • Octal literals (0o126632)
  • Scientific notation (24e3)
  • Variables (with UTF-8 support)
  • Functions (list)
  • Bitwise operators
  • Relational operators
  • Some handy predefined variables
  • Its own REPL

Installation

Library
go get github.com/soudy/mathcat
REPL
go get github.com/soudy/mathcat/cmd/mc

REPL usage

The REPL can be used by simply launching mc:

mc> 8**8
16777216
mc> (8**8) - e # Look, a comment!
16777213.281718171541

Or it can read from stdin like so:

$ echo "3**pi * (6 - -7)" | mc
Arguments
Name Description Default
precision bits of decimal precision used in decimal float results 64
mode type of literal used as result. can be decimal, hex, binary or octal decimal

Library usage

There are three different ways to evaluate expressions, the first way is by calling Eval, the second way is by creating a new instance and using Run, and the final way is to use Exec in which you can pass a map with variables to use in the expression.

Eval

If you're not planning on declaring variables, you can use Eval. Eval will evaluate an expression and return its result.

res, err := mathcat.Eval("2 * pi * 5") // pi is a predefined variable
if err != nil {
    // handle errors
}
fmt.Printf("Result: %s\n", res.FloatString(6)) // Result: 31.415927
Run

You can use Run for a more featureful approach. With this method you can assign and use variables across the Parser instance.

p := mathcat.New()
p.Run("a = 1")
p.Run("b = 3")
res, err := p.Run("a + b * b") // 10
Exec

To pass external variables to an expression without using Run, you can use Exec to pass a map of variables.

res, err := mathcat.Exec("a + b * b", map[string]*big.Rat{
    "a": big.NewRat(1, 1),
    "b": big.NewRat(3, 1),
}) // 10

Besides evaluating expressions, mathcat also offers some other handy functions.

GetVar

You can get a defined variable at any time with GetVar.

p := mathcat.New()
p.Run("酷 = -33")
if val, err := p.GetVar("酷"); !err {
    fmt.Printf("%f\n", val) // -33
}
IsValidIdent

Check if a string qualifies as a valid identifier

mathcat.IsValidIdent("a2") // true
mathcat.IsValidIdent("6a") // false
RationalToInteger

Convert a big.Rat to a big.Int. Useful for printing in other bases or when you're only working with integers.

integer := mathcat.RationalToInteger(big.NewRat(42, 1))
fmt.Printf("%#x\n", integer) // prints 0x2a
Supported operators
Operator Description
= assignment
+ addition
- subtraction
/ division
* multiply
** power
% remainder
& bitwise and
| bitwise or
^ bitwise xor
<< bitwise left shift
>> bitwise right shift
~ bitwise not
== equal
!= not equal
> greater than
>= greater than or equal
< less than
<= less than or equal

All of these except ~ and relational operators also have an assignment variant (+=, -=, **= etc.) that can be used to assign values to variables.

Functions

mathcat has a big list of functions you can use. A function call is invoked like in most programming languages, with an identifier followed by a left parentheses like this: max(5, 10).

Function Arguments Description
abs(n) 1 returns the absolute value of given number
sin(n) 1 returns the sine of given number
cos(n) 1 returns the cosine of given number
tan(n) 1 returns the tangent of given number
asin(n) 1 returns the arcsine of given number
acos(n) 1 returns the acosine of given number
atan(n) 1 returns the arctangent of given number
ceil(n) 1 returns the smallest integer greater than or equal to a given number
floor(n) 1 returns the largest integer less than or equal to a given number
ln(n) 1 returns the natural logarithm of given number
log(n) 1 returns the the decimal logarithm of given number
logn(k, n) 2 returns the the k logarithm of n
max(a, b) 2 returns the larger of the two given numbers
min(a, b) 2 returns the smaller of the two given numbers
sqrt(n) 1 returns the square root of given number
rand() 0 returns a random float between 0.0 and 1.0
fact(n) 1 returns the factorial of given number
list() 0 list all functions
Predefined variables

There are some handy predefined variables you can use (and change) throughout your expressions:

  • pi
  • tau
  • phi
  • e
  • true (set to 1)
  • false (set to 0)

Documentation

For a more technical description of mathcat, see here.

License

This project is licensed under the MIT License. See the LICENSE file for the full license.

Documentation

Index

Constants

View Source
const (
	AssocLeft association = iota
	AssocRight
)

Variables

View Source
var (
	// RatTrue represents true in boolean operations
	RatTrue = big.NewRat(1, 1)
	// RatFalse represents false in boolean operations
	RatFalse = big.NewRat(0, 1)

	ErrUnmatchedParentheses = errors.New("Unmatched parentheses")
	ErrMisplacedComma       = errors.New("Misplaced ‘,’")
	ErrAssignToLiteral      = errors.New("Can't assign to literal")
)
View Source
var ErrDivisionByZero = errors.New("Division by zero")
View Source
var FunctionNames []string

FunctionNames holds all the function names that are available for use

Functions

func Ceil

func Ceil(n *big.Rat) *big.Rat

Ceil returns the ceil of a rational number

func Eval

func Eval(expr string) (*big.Rat, error)

Eval evaluates an expression and returns its result and any errors found.

Example:

res, err := mathcat.Eval("2 * 2 * 2") // 8

func Exec

func Exec(expr string, vars map[string]*big.Rat) (*big.Rat, error)

Exec executes an expression with a given map of variables.

Example:

res, err := mathcat.Exec("a + b * b", map[string]*big.Rat{
    "a": big.NewRat(1, 1),
    "b": big.NewRat(3, 1),
}) // 10

func Factorial

func Factorial(n *big.Rat) *big.Rat

Factorial calculates the factorial of rational number n

func Floor

func Floor(n *big.Rat) *big.Rat

Floor returns the floor of a rational number

func Gcd

func Gcd(x, y *big.Rat) *big.Rat

Gcd calculates the greatest common divisor of the numbers x and y

func IsValidIdent

func IsValidIdent(s string) bool

IsValidIdent checks if a string qualifies as a valid identifier.

func Max

func Max(a, b *big.Rat) *big.Rat

Max gives the maximum of two rational numbers

func Min

func Min(a, b *big.Rat) *big.Rat

Min gives the minimum of two rational numbers

func Mod

func Mod(x, y *big.Rat) *big.Rat

Mod returns x % y

func RationalToInteger

func RationalToInteger(n *big.Rat) *big.Int

RationalToInteger converts a rational number to an integer

Types

type Parser

type Parser struct {
	Tokens    Tokens
	Variables map[string]*big.Rat
	// contains filtered or unexported fields
}

Parser holds the lexed tokens, token position, declared variables and stacks used throughout the parsing of an expression.

By default, variables always contains the constants defined below. These can however be overwritten.

func New

func New() *Parser

New initializes a new Parser instance, useful when you want to run multiple expression and/or use variables.

func (Parser) GetVar

func (p Parser) GetVar(index string) (*big.Rat, error)

GetVar gets an existing variable.

Example:

p.Run("酷 = -33")
if val, err := p.GetVar("酷"); !err {
    fmt.Printf("%f\n", val) // -33
}

func (*Parser) Run

func (p *Parser) Run(expr string) (*big.Rat, error)

Run executes an expression on an existing parser instance. Useful for variable assignment.

Example:

p.Run("a = 555")
p.Run("a += 45")
res, err := p.Run("a + a") // 1200

type Token

type Token struct {
	Type  TokenType
	Value string
	Pos   int
}

Token is an entity in an expression

func (Token) Is

func (tok Token) Is(toktype TokenType) bool

Is checks if the token is given token type

func (Token) IsAssignment

func (tok Token) IsAssignment() bool

IsAssignment checks if the token is an assignment operator

func (Token) IsBitwise

func (tok Token) IsBitwise() bool

IsBitwise checks if the token type is a bitwise operator

func (Token) IsLiteral

func (tok Token) IsLiteral() bool

IsLiteral checks if the token is a literal

func (Token) IsOperator

func (tok Token) IsOperator() bool

IsOperator checks if the token is an operator

func (Token) String

func (tok Token) String() string

type TokenType

type TokenType int

TokenType represents the type of token

const (
	Eol TokenType = iota // end of line

	Ident   // x
	Decimal // 3
	Hex     // 0xDEADBEEF
	Binary  // 0b10101101100
	Octal   // 0o666

	Add      // +
	Sub      // -
	Div      // /
	Mul      // *
	Pow      // **
	Rem      // %
	UnaryMin // -

	And // &
	Or  // |
	Xor // ^
	Lsh // <<
	Rsh // >>
	Not // ~

	AndEq // &=
	OrEq  // |=
	XorEq // ^=
	LshEq // <<=
	RshEq // >>=

	Eq    // =
	AddEq // +=
	SubEq // -=
	DivEq // /=
	MulEq // *=
	PowEq // **=
	RemEq // %=

	NotEq // !=
	EqEq  // ==
	Gt    // >
	GtEq  // >=
	Lt    // <
	LtEq  // <=

	Lparen // (
	Rparen // )
	Comma  // ,
)

func (TokenType) String

func (t TokenType) String() string

type Tokens

type Tokens []*Token

Tokens is a slice of pointers to a token

func Lex

func Lex(expr string) (Tokens, error)

Lex starts lexing an expression, converting an input string into a stream of tokens later passed on to the parser.

Returns the generated tokens and any error found.

Directories

Path Synopsis
cmd
mc

Jump to

Keyboard shortcuts

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