Skip to content
forked from sysprog21/kcalc

Math expression evaluation as Linux kernel module

License

Notifications You must be signed in to change notification settings

kytimmylai/kcalc

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kcalc: in-kernel math expression evaluation for Linux

kcalc is a mathematical expression evaluator and takes string as input, returning floating-point number as a result.

Features

  • Supports arithmetic, bitwise and logical operators
  • Supports variables
  • Low memory usage

Floating point representation

This is our customized form to represent floating point, one 32-bit size is divided into sign (1 bit), integer (27 bits), and mantissa (4 bits).

msb 0    1                              28        32 lsb
    +----+------------------------------+----------+
    |sign|           integer            | mantissa |
    +----+------------------------------+----------+

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 since we do not transform the value to normal representation.

You can use add additional expression in scripts/test.sh for more examples.

$ 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)

Use Custom function

Sample usage in MathEX

#include "expression.h"

/* Custom function that returns the sum of its two arguments */
static float add(struct expr_func *f, vec_expr_t args, void *c) {
    float a = expr_eval(&vec_nth(&args, 0));
    float b = expr_eval(&vec_nth(&args, 1));
    return a + b;
}

static struct expr_func user_funcs[] = {
    {"add", add, 0}, {NULL, NULL, 0},
};

int main() {
    const char *s = "x = 40, add(2, x)";
    struct expr_var_list vars = {0};
    struct expr *e = expr_create(s, strlen(s), &vars, user_funcs);
    if (!e) { printf("Syntax error"); return 1; }

    printf("result: %f\n", expr_eval(e));

    expr_destroy(e, &vars);
    return 0;
}

Output: result: 42.000000

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.

About

Math expression evaluation as Linux kernel module

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 70.7%
  • Shell 28.6%
  • Makefile 0.7%