Simple calculator REPL, similar to bc(1), with syntax highlighting and persistent history

Overview

heroimg.png

eva

simple calculator REPL, similar to bc(1), with syntax highlighting and persistent history

eva.png

installation

  • Homebrew
$ brew install eva
  • crates.io
$ cargo install eva
  • manual
$ git clone https://github.com/nerdypepper/eva.git
$ cargo run

usage

eva 0.2.4
NerdyPepper <[email protected]>
Calculator REPL similar to bc(1)

USAGE:
    eva [FLAGS] [OPTIONS] [INPUT]

FLAGS:
    -h, --help       Prints help information
    -r, --radian     set eva to radian mode
    -V, --version    Prints version information

OPTIONS:
    -b, --base <RADIX>    set the radix of calculation output (2, 8, 10, 16 etc.)
    -f, --fix <FIX>       set number of decimal places in the output

ARGS:
    <INPUT>    optional expression string to run eva in command mode

type out an expression and hit enter, repeat.

> 1 + sin(30)
1.5
> floor(sqrt(3^2 + 5^2))
5
> 5sin(45) + cos(0)
4.53553

updating

  • crates.io
$ cargo install eva --force
  • manual
$ cargo install --force --path /path/to/eva

operators

  • binary operators: + - * / ^ **
  • unary operators: + -

constants

some constants available in rust standard library.

e      pi

examples:

pi * 5^2  # πr²

functions

all trigonometric functions expect input in degrees.

sin    cos     tan    csc    sec    cot    sinh   cosh   tanh
asin   acos    atan   acsc   asec   acot   ln     log    sqrt
ceil   floor   abs

deg(x) - convert x to degrees
rad(x) - convert x to radians

examples:

sqrt(sin(30)) # parentheses are mandatory for functions

log100        # no
log(100)      # yes

quality of life features

  • auto insertion of * operator
>12sin(45(2))             # 12 * sin(45 * (2))
12
  • auto balancing of parentheses
>ceil(sqrt(3^2 + 5^2      # ceil(sqrt(3^2 + 5^2))
6
  • use previous answer with _
> sin(pi)
0.0548036650
> _^2
0.0030034417
>
  • super neat error handling
> 1 + ln(-1)
Domain Error: Out of bounds!
  • syntax highlighting

todo

  • add support for variables (pi, e, _ (previous answer))
  • syntax highlighting
  • multiple arg functions
  • screenshots
  • create logo
  • unary operators (minus, plus)
  • add detailed error handler
  • add unit tests
  • lineditor with syntax highlighting
  • add more functions

contributors

the rust community has helped eva come a long way, but these devs deserve a special mention for their contributions:

Ivan Tham
Milan Marković
asapokl

Comments
  • Factorials

    Factorials

    Whenever I try to calculate the factorial of a number greater than 63 (and less than 66, else it returns 0.0) I get the following error:

    thread 'main' panicked at 'index out of bounds: the len is 36 but the index is 9223372036854775808', /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libcore\slice\mod.rs:2686:10
    note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
    
    bug help wanted high prio 
    opened by federico22598 12
  • CTRL-C causes thread main to panic

    CTRL-C causes thread main to panic

    Exiting continuous mode with Ctrl-C causes it to panic.

    thread 'main' panicked at 'called 'Result::unwrap()' on an 'Err' value: Io(0s { code:13, kind: PermissionDenied, message: "Permission denied" }), src/libcore/result.rs:1009:5

    opened by strangelovephd 6
  • history.txt file is written to current directory

    history.txt file is written to current directory

    Whenever eva is run it writes a history.txt into the current directory. This results in a lot of these files lying around my system. I would prefer if eva used a central history file stored in the appropriate place on the given operating system (The directories crate can help with that).

    opened by wezm 5
  • Implement support for multi-arg functions & implement `nroot`/`log`

    Implement support for multi-arg functions & implement `nroot`/`log`

    ~~:warning: Note: this is based on #51 and thus a draft for now.~~

    The motivation behind this change is to implement / change the following functions:

    • nroot(x,y) returns the y-th root of x.
    • log(x,y) returns the logarithm of x for the base y.
    • log10(x) returns the logarithm of x for the base 10. This is a breaking change as this is what log(x) was doing previously.

    Internally, the following has changed:

    • Each relation of a Token::Function now has the signature fn(Vec<f64>) -> f64 where Vec<f64> represents a list of arguments from the REPL. Via the macros arity_{1,2}! it's still possible to define functions with n arguments:

      arity_2!(|x, y| x+y)
      

      evaluates to a function which takes a Vec<f64> and evaluates x+y with x being vec.get(0).unwrap() and vec.get(1).unwrap(). The data-structure ensures previously that the size of the vector matches the number of required arguments.

    • The parser now evaluates expressions starting from a closing bracket back to the next left bracket (as before) or the next comma and ensures that the latter case can only happen inside a function call.

    opened by Ma27 4
  • Add support for Python-like catching of last result

    Add support for Python-like catching of last result

    Hi !

    eva is for sure a very polished piece of software. However there is one thing I think it is lacking right now (or maybe it has that already, but it is not advertised anywhere in the docs):

    The Python shell has a very nifty shortcut that let's you capture the result of the last expression in the next expression to be evaluated using the _ variable as a special case:

    >>> 1+1
    2
    >>> _ * 3
    6
    

    Would you be interested in implementing that ? This way I'd consider switching to eva as my pocket CLI calculator for good :wink:

    enhancement wip 
    opened by althonos 4
  • --fix appears to truncate versus round

    --fix appears to truncate versus round

    $ eva -f 1
    > .1 + 4
             4.0
    
    $ eva '.1 + 4'
             4.0999999999
    

    I would have expected the result to be rounded to the specified number of decimal places (and produce 4.1) instead of truncated.

    bug 
    opened by wezm 3
  • Publish git tags for each release?

    Publish git tags for each release?

    Would it be possible to publish a git tag for each release here? This would be way more convenient when creating packages for a distro when using the source tarball from github :)

    opened by Ma27 3
  • Crash on large result

    Crash on large result

    When an expression value is large enough the application crashes.

    > 2000000000*200000000*20000000
    thread 'main' panicked at 'index out of bounds: the len is 36 but the index is 9223372036854775808', /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libcore/slice/mod.rs:2686:10
    stack backtrace:
       0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
                 at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
       1: std::sys_common::backtrace::_print
                 at src/libstd/sys_common/backtrace.rs:71
       2: std::panicking::default_hook::{{closure}}
                 at src/libstd/sys_common/backtrace.rs:59
                 at src/libstd/panicking.rs:197
       3: std::panicking::default_hook
                 at src/libstd/panicking.rs:211
       4: std::panicking::rust_panic_with_hook
                 at src/libstd/panicking.rs:474
       5: std::panicking::continue_panic_fmt
                 at src/libstd/panicking.rs:381
       6: rust_begin_unwind
                 at src/libstd/panicking.rs:308
       7: core::panicking::panic_fmt
                 at src/libcore/panicking.rs:85
       8: core::panicking::panic_bounds_check
                 at src/libcore/panicking.rs:61
       9: eva::format::pprint
      10: eva::main
      11: std::rt::lang_start::{{closure}}
      12: std::panicking::try::do_call
                 at src/libstd/rt.rs:49
                 at src/libstd/panicking.rs:293
      13: __rust_maybe_catch_panic
                 at src/libpanic_unwind/lib.rs:87
      14: std::rt::lang_start_internal
                 at src/libstd/panicking.rs:272
                 at src/libstd/panic.rs:388
                 at src/libstd/rt.rs:48
      15: main
      16: __libc_start_main
      17: _start
    
    opened by hepek 3
  • Publish release

    Publish release

    This looks like a handy tool. I'd love to create and AUR package for eva. It's best to build these against publish releases instead of straight from git master though. I would be great if you could tag a release.

    opened by wezm 3
  • Allow function to accept multiple arguments

    Allow function to accept multiple arguments

    Superseeds https://github.com/nerdypepper/eva/pull/52

    Test probably still break, need to add more tests.

    Thanks for @Ma27 for his work on the testing suite and lexer part in #52 that I get to continue to work on this easily.

    cc @Ma27

    opened by pickfire 2
  • use of undeclared type error | commit  39e4e64

    use of undeclared type error | commit 39e4e64

    On current master (39e4e643981d5ac52a440bf7e3691fca3228b1d2) trying to build eva with cargo build --release results in the following error:

    error[E0433]: failed to resolve: use of undeclared type or module `env_logger`
      --> src/main.rs:44:5
       |
    44 |     env_logger::init();
       |     ^^^^^^^^^^ use of undeclared type or module `env_logger`
    
    error: aborting due to previous error
    
    For more information about this error, try `rustc --explain E0433`.
    error: Could not compile `eva`.
    

    Upon commenting out the line cargo check and build --release both finish with the following 2 warnings:

    warning: unused `std::result::Result` that must be used
      --> src/main.rs:79:9
       |
    79 |         std::fs::write(&previous_ans_path, "0");
       |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = note: #[warn(unused_must_use)] on by default
       = note: this `Result` may be an `Err` variant, which should be handled
    
    warning: unused `std::result::Result` that must be used
       --> src/main.rs:103:29
        |
    103 |                             writeln!(file, "{}", ans);
        |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = note: this `Result` may be an `Err` variant, which should be handled
        = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
    

    However eva seems to work properly even with the warnings.

    hacktoberfest 
    opened by JonnyCodewalker 2
  • support for exponential notation

    support for exponential notation

    Right now typing 1e6 will perform 1 * e * 6. I think it would be useful to first check whether the number should be evaluated using exponential notation.

    > 1e6
    1,000,000
    
    > 1e12
    1,000,000,000,000
    

    Etc... Rust itself, Python and JavaScript support this and once you start using it, it's really hard to go without.

    opened by dannyvankooten 0
  • Lockfile out of sync

    Lockfile out of sync

    As of the current 0.3.0 tag (the second iteration of this tag), the Cargo.lock file is not in sync with Cargo.toml. This means distro packages are unable to create reproducible packaging because the dependencies must be bumped dynamically at build time instead of being able to use the ones specified (via --locked or --frozen).

    I'll submit a patch for this release (and have already repackaged the Arch Linux release using that patch), but please also make refreshing the lock file part of the release checklist/process.

    opened by alerque 1
  • Functions over history results

    Functions over history results

    Functions like (sum, avg, etc.) over entire history of results.

    sum(*) (or any other special character) should produce the sum of all results in the current session.

    Or the way bc does it. Mark result as a variable then use the variable tip later in a sum with other variables.

    bill=10+20+30+40+50
    tip=bill*10/100
    bill+tip
    
    enhancement 
    opened by lucianmarin 0
  • [Suggestion] Add let ... in ... expr syntax

    [Suggestion] Add let ... in ... expr syntax

    Add a basic let syntax for simple mathematical functions. Proposed EBNF:

    expr ::= NUMBER
               | NAME
               | NAME '(' args? ')'
               | 'let' NAME+ '=' expr 'in' expr
    args = expr (',' expr)*
    

    Where an expression in the form let name = 5 in expr binds name to 5 in expr, and an expression in the form let name a b = a + b in expr binds name to the function f(a, b) = a + b in expr.

    enhancement help wanted 
    opened by Flexilis-anatis 2
Releases(v0.3.1)
Owner
Akshay
Akshay
A syntax-highlighting pager for git, diff, and grep output

Get Started Install delta and add this to your ~/.gitconfig: [core] pager = delta [interactive] diffFilter = delta --color-only [delta]

Dan Davison 16k Dec 31, 2022
A standalone code editor with syntax highlighting and themes.

CodeEditor A standalone code (and text) editor for people like me who write their own user interfaces utilizing crates like pixels. CodeEditor renders

Markus Moenig 8 Nov 25, 2022
🏭 Convert Markdown documents into themed HTML pages with support for code syntax highlighting, LaTeX and Mermaid diagrams.

Marky Markdown Magician ?? Features Hot reload previewing ?? Conversion to HTML / PDF ?? Themes! ✨ Extensions - Math, diagrams, syntax-highlighting ??

Vadim 12 Feb 19, 2023
🌴 Syntax highlighting in Rust.

?? HL (WIP) Syntax highlighting written in Rust. The project is designed to generate html syntax highlighting for the given file. This software is ins

ahmadrosid 8 Jun 28, 2022
🌈 A nushell plugin for syntax highlighting.

nu-plugin-highlight A nushell plugin for syntax highlighting. About nu-plugin-highlight is a plugin for Nushell that provides syntax highlighting for

Piepmatz 4 Jun 29, 2023
AI-Boosted Solidity REPL

ChiselGPT: AI-Boosted Solidity REPL Chisel-GPT is an extension for Chisel allowing natural language requests. The natural language requests are conver

null 74 Apr 19, 2023
Collection of immutable and persistent data structures written in Rust, inspired by the standard libraries found in Haskell, Closure and OCaml

PRust: (P)ersistent & Immutable Data Structures in (Rust) This library houses a collection of immutable and persistent data structures, inspired by th

Victor Colombo 13 Aug 13, 2023
🗄️ A simple (and safe!) to consume history of Client and Studio deployment versions.

??️ Roblox Version Archive A simple (and safe!) to consume history of Client and Studio deployment versions. About Parsing Roblox's DeployHistory form

Brooke Rhodes 4 Dec 28, 2022
Count your code by tokens, types of syntax tree nodes, and patterns in the syntax tree. A tokei/scc/cloc alternative.

tcount (pronounced "tee-count") Count your code by tokens, types of syntax tree nodes, and patterns in the syntax tree. Quick Start Simply run tcount

Adam P. Regasz-Rethy 48 Dec 7, 2022
Semi-persistent, scoped test directories

Semi-persistent, scoped test directories This crate aims to make it easier to use temporary directories in tests, primarily by calling the testdir!()

Floris Bruynooghe 4 Nov 19, 2022
WIP. Goals: Treesitter highlighting, snippets, and a smooth intergration with neovim.

typst.nvim WIP. Goals: Tree-sitter highlighting, snippets, and a smooth integration with neovim. For the past week, I've been thinking what I want for

SeniorMars 66 Apr 9, 2023
🐢 Atuin replaces your existing shell history with a SQLite database, and records additional context for your commands

Atuin replaces your existing shell history with a SQLite database, and records additional context for your commands. Additionally, it provides optional and fully encrypted synchronisation of your history between machines, via an Atuin server.

Ellie Huxtable 4.6k Jan 1, 2023
git-cliff can generate changelog files from the Git history by utilizing conventional commits as well as regex-powered custom parsers.⛰️

git-cliff can generate changelog files from the Git history by utilizing conventional commits as well as regex-powered custom parsers. The changelog template can be customized with a configuration file to match the desired format.

Orhun Parmaksız 5k Jan 9, 2023
An enhanced history(1) for bash

history This is a replacement for the history builtin in bash. It has a couple of additional features that relative to the one included with bash: Con

Robert T. McGibbon 4 Aug 25, 2022
McFly - fly through your shell history

McFly - fly through your shell history McFly replaces your default ctrl-r shell history search with an intelligent search engine that takes into accou

Andrew Cantino 4.8k Jan 7, 2023
Integrate Mcfly with fzf to combine a solid command history database with a widely-loved fuzzy search UI

McFly fzf integration Integrate McFly with fzf to combine a solid command history database with a widely-loved fuzzy search UI Features: Advanced hist

null 11 Jan 25, 2023
Cork is a simple command-line calculator, mainly targeted towards people who deal with hex numbers

Cork is a simple command-line calculator, mainly targeted towards people who deal with hex numbers. It deals only with integer arithmetic. Expressions may involve mixed bases (limited to decimal, hexadecimal, octal and binary numbers). The global output format may be set to a particular radix - by default it is hex.

Deep Majumder 50 Dec 22, 2022
A simple command line based RPN calculator

stak A simple command line based RPN calculator Usage stak can be used in two modes: one-shot from the command line, or in an interactive shell One-sh

null 1 Nov 17, 2021
A simple calculator, Rust implemention.

Calc A simple calculator. Usage If the name of the binary is calculator, To calculate: $ calculator -c <EXPRESSION> # or $ calculator --calc <EXPRESSI

Umoho Qerty 2 Aug 7, 2022