/kcalc

Math expression evaluation as Linux kernel module

Primary LanguageCMIT LicenseMIT

kcalc: in-kernel math expression evaluation for Linux

kcalc is a mathematical expression evaluator and takes string as input, returning fixed-point numbers.

Features

  • Arithmetic, bitwise and logical operators;
  • Flexible variables;
  • Customized functions;

Fixed-point representation

kcalc introduces a fixed-point number representation for fractional values: one 32-bit size is divided into mantissa (28 bits), sign (1 bit) and exponent (3 bits).

MSB   31                               4    3   2    1   0  LSB
     +----------------------------------+------+----------+
     |     mantissa                     | sign | exponent |
     +----------------------------------+------+----------+

Usage:

Build and install the module

$ make
$ sudo insmod calc.ko
$ sudo chmod 0666 /dev/calc

Then simply send the expression to the module

$ echo -ne "3*5\0" > /dev/calc

The expected output in dmesg should be:

calc: Received 3 -> 3*5
Result: 240

The result seems incorrect because we did not transform the value to normal representation. You can use the utlity to convert values into human readable form:

$ source scripts/eval.sh
$ fromfixed 240

Then, you can get 15, which is the exact result for expression 3*5.

You can check file scripts/test.sh for more examples about the expressions. Alteratively, execue make check for the same script.

$ scripts/test.sh

... Information generated by modinfo ...

Testing  6*7 ...
42
Testing  1980+1 ...
1981
Testing  2019-1 ...
2018
Testing  42/6 ...
7
Testing  1/3 ...
.33333330000000000000
Testing  1/3*6+2/4 ...
2.49999980000000000000
Testing  (1/3)+(2/3) ...
.99999990000000000000
Testing  (2145%31)+23 ...
29

Internals

struct expr *expr_create(const char *s, size_t len, struct expr_var_list *vars, struct expr_func *funcs) - returns compiled expression from the given string. If expression uses variables - they are bound to vars, so you can modify values before evaluation or check the results after the evaluation.

int expr_eval(struct expr *e) - evaluates compiled expression.

void expr_destroy(struct expr *e, struct expr_var_list *vars) - cleans up memory. Parameters can be NULL (e.g. if you want to clean up expression, but reuse variables for another expression).

struct expr_var *expr_var(struct expr_var *vars, const char *s, size_t len) - returns/creates variable of the given name in the given list. This can be used to get variable references to get/set them manually.

Supported operators

  • Arithmetics: +, -, *, /, % (remainder), ** (power)
  • Bitwise: <<, >>, &, |, ^ (xor or unary bitwise negation)
  • Logical: <, >, ==, !=, <=, >=, &&, ||, ! (unary not)
  • Other: = (assignment, e.g. x=y=5), , (separates expressions or function parameters)

License

kcalcis released under the MIT License. Use of this source code is governed by a MIT License that can be found in the LICENSE file.