Skip to content

setoh2000/TinyExpr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TinyExpr

A minimal, header-only library for dynamically evaluating C-style integer expressions.

Requires: C++11 or later.

Features

  • Header-only: Just copy TinyExpr.hpp.
  • C-style syntax: Arithmetic, bitwise, shift, and ternary operators.
  • Variable support: Variable names start with $, _, or a-zA-Z, followed by any combination of a-zA-Z, 0-9, _, $. Case-sensitive. Provide a dictionary (std::map).
  • Hexadecimal support: Supports 0x1F literals.
  • Whitespace agnostic: Multi-line and indented formulas are supported.

Usage

#include "TinyExpr.hpp"
#include <map>
#include <iostream>

int main() {
    tinyexpr::TinyExpr eval;
    tinyexpr::vars variables = {{"hp", 100}, {"buff", 0x10}};
    
    std::string formula = "(hp + buff) << 1";
    tinyexpr::value result = eval.evaluate(formula, variables);
    
    std::cout << result << std::endl; // 232
    return 0;
}

Supported operators and syntax

This header-only evaluator supports the following tokens and operators (precedence from highest to lowest):

  • Primary: parentheses ( ), numeric literals (decimal, 0x hex), variables (first char: $/_/a-zA-Z; subsequent chars: $/_/a-zA-Z/0-9; case-sensitive).
  • Unary: unary minus -, bitwise NOT ~, logical NOT !.
  • Multiplicative: *, / (division throws on divide-by-zero).
  • Additive: +, -.
  • Shift: <<, >>.
  • Relational: <, <=, >, >=.
  • Equality: ==, !=.
  • Bitwise: &, ^, | (AND, XOR, OR).
  • Logical: &&, || (short-circuiting; && binds tighter than ||).
  • Ternary conditional: cond ? expr1 : expr2.

Notes:

  • Numeric literals are parsed as unsigned long long and truncated to T. Literals exceeding 64 bits cause a parse error. See Choosing an evaluator type for details.
  • Signed integer overflow follows C++ semantics (undefined behavior). Keep values within the signed range of T, or use an unsigned type (e.g. TinyExprT<uint32_t>) for defined wrap-around.

Choosing an evaluator type

tinyexpr::TinyExpr (64-bit signed int64_t) is recommended for general use. It covers the full range of typical integer values, and casting the result to a narrower type at the call site is usually all you need:

tinyexpr::TinyExpr eval;
tinyexpr::vars variables = {{"hp", 100}, {"buff", 0x10}};
int32_t result = static_cast<int32_t>(eval.evaluate("hp + buff", variables));

All available specializations are listed below. The header includes <cstdint> automatically; value and vars convenience aliases use int64_t.

Type Underlying type Value type (Type)
tinyexpr::TinyExpr (default) int64_t (64-bit signed) int64_t
tinyexpr::TinyExpr32 int32_t (32-bit signed) int32_t
tinyexpr::TinyExpr16 int16_t (16-bit signed) int16_t
tinyexpr::TinyExpr8 int8_t (8-bit signed) int8_t

Note on numeric literals: all literals are parsed as unsigned long long via stoull, then truncated to T via static_cast<T>. This means you can freely write values beyond the signed range of T — for example, 0xffffffffffffffff with TinyExpr (64-bit) yields -1, 0xffffffff with TinyExpr32 yields -1, and with TinyExpr8, 255/0xff yield -1 and 128 yields -128. The bit pattern is simply reinterpreted in the target width; there is no restriction on what literals you can write.

For any other integral type, instantiate tinyexpr::TinyExprT<T> directly.

About

A minimal, header-only library for dynamically evaluating C-style integer expressions.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors