forked from sysprog21/kcalc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
expression.h
144 lines (124 loc) · 3.28 KB
/
expression.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef EXPRESSION_H_
#define EXPRESSION_H_
#ifdef __cplusplus
extern "C" {
#endif
#define vec(T) \
struct { \
T *buf; \
int len; \
int cap; \
}
#define vec_init() \
{ \
NULL, 0, 0 \
}
#define vec_len(v) ((v)->len)
#define vec_unpack(v) \
(char **) &(v)->buf, &(v)->len, &(v)->cap, sizeof(*(v)->buf)
#define vec_push(v, val) \
vec_expand(vec_unpack(v)) ? -1 : ((v)->buf[(v)->len++] = (val), 0)
#define vec_nth(v, i) (v)->buf[i]
#define vec_peek(v) (v)->buf[(v)->len - 1]
#define vec_pop(v) (v)->buf[--(v)->len]
#define vec_free(v) (kfree((v)->buf), (v)->buf = NULL, (v)->len = (v)->cap = 0)
#define vec_foreach(v, var, iter) \
if ((v)->len > 0) \
for ((iter) = 0; (iter) < (v)->len && (((var) = (v)->buf[(iter)]), 1); \
++(iter))
#include <linux/slab.h>
/* Simple expandable vector implementation */
static inline int vec_expand(char **buf, int *length, int *cap, int memsz)
{
if (*length + 1 > *cap) {
void *ptr;
int n = (*cap == 0) ? 1 : *cap << 1;
ptr = krealloc(*buf, n * memsz, GFP_KERNEL);
if (ptr == NULL) {
return -1; /* allocation failed */
}
*buf = (char *) ptr;
*cap = n;
}
return 0;
}
/*
* Expression data types
*/
struct expr_func;
typedef vec(struct expr) vec_expr_t;
typedef void (*exprfn_cleanup_t)(struct expr_func *f, void *context);
typedef int (*exprfn_t)(struct expr_func *f, vec_expr_t args, void *context);
struct expr {
int type;
union {
struct {
int value;
} num;
struct {
int *value;
} var;
struct {
vec_expr_t args;
} op;
struct {
struct expr_func *f;
vec_expr_t args;
void *context;
} func;
} param;
};
struct expr_string {
const char *s;
int n;
};
struct expr_arg {
int oslen;
int eslen;
vec_expr_t args;
};
typedef vec(struct expr_string) vec_str_t;
typedef vec(struct expr_arg) vec_arg_t;
/*
* 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 {
int 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);
int expr_eval(struct expr *e);
#define EXPR_TOP (1 << 0)
#define EXPR_TOPEN (1 << 1)
#define EXPR_TCLOSE (1 << 2)
#define EXPR_TNUMBER (1 << 3)
#define EXPR_TWORD (1 << 4)
#define EXPR_TDEFAULT (EXPR_TOPEN | EXPR_TNUMBER | EXPR_TWORD)
#define EXPR_UNARY (1 << 5)
#define EXPR_COMMA (1 << 6)
int expr_next_token(const char *s, size_t len, int *flags);
struct expr *expr_create(const char *s,
size_t len,
struct expr_var_list *vars,
struct expr_func *funcs);
void expr_destroy(struct expr *e, struct expr_var_list *vars);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* EXPRESSION_H_ */