Skip to content

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

 
 
 

Contributors

Languages

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