# 2020q3 Homework6 (kcalc)
contributed by < `Rsysz` >.
###### tags: `sysprog`
{%hackmd theme-dark %}
## kcalc原理
首先必須先了解 `Character Device` 程式的結構與原理,接著才看內部數值計算方式,了解完 `Dev` 的使用方式後,這邊先看到 `main.c` 內的 `calc`,這邊使用到了 `struct expr` 這個結構體與 `expr_create` 對其初始化
```cpp
static void calc(void)
{
struct expr_var_list vars = {0};
struct expr *e = expr_create(message, strlen(message), &vars, user_funcs);
if (!e) {
pr_alert("Syntax error");
return;
}
result = expr_eval(e);
pr_info("Result: %" PRIu64 "\n", result);
expr_destroy(e, &vars);
}
```
再來看到 `expression.h` 與 `expression.c` 內定義了對應的結構體
```cpp
struct expr {
int type;
union {
struct {
uint64_t value;
} num;
struct {
uint64_t *value;
} var;
struct {
vec_expr_t args;
} op;
struct {
struct expr_func *f;
vec_expr_t args;
void *context;
} func;
} param;
};
/*
* Functions
*/
struct expr_func {
const char *name;
exprfn_t f;
exprfn_cleanup_t cleanup;
size_t ctxsz;
};
struct expr_func *expr_func(struct expr_func *funcs, const char *s, size_t len);
/*
* Variables
*/
struct expr_var {
uint64_t value;
struct expr_var *next;
char name[];
};
struct expr_var_list {
struct expr_var *head;
};
struct expr_var *expr_var(struct expr_var_list *vars,
const char *s,
size_t len);
```
如下圖所示
```graphviz
digraph EXPR{
rankdir=LR
subgraph cluster{
label = "expr"
type [label="int type" shape=box]
subgraph cluster{
label ="param"
f [label="func" shape=box]
num [label="num" shape=box]
var [label="var" shape=box]
op [label="op" shape=box]
{rank=same}
}
}
}
```