Root/expr.h

1/*
2 * expr.h - Expressions and values
3 *
4 * Written 2009, 2012, 2016 by Werner Almesberger
5 * Copyright 2009, 2012, 2016 by Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#ifndef EXPR_H
15#define EXPR_H
16
17#include <math.h>
18
19
20#define UNDEF HUGE_VAL
21
22
23struct frame;
24struct expr;
25struct value;
26
27enum num_type {
28    nt_none,
29    nt_mm,
30    nt_um,
31    nt_mil,
32};
33
34struct num {
35    enum num_type type;
36    int exponent;
37    double n;
38};
39
40typedef struct num (*op_type)(const struct expr *self,
41    const struct frame *frame);
42
43struct expr {
44    op_type op;
45    union {
46        struct num num;
47        const char *var;
48        char *str;
49        struct {
50            struct expr *a;
51            struct expr *b;
52        } op;
53    } u;
54    int lineno;
55};
56
57
58extern struct num undef;
59
60
61#define is_undef(num) ((num).type == nt_none)
62#define is_dimensionless(num) (!(num).exponent)
63
64
65static inline int is_distance(struct num num)
66{
67    return (num.type == nt_mm || num.type == nt_um || num.type == nt_mil)
68        && num.exponent == 1;
69}
70
71
72void fail_expr(const struct expr *expr);
73
74const char *str_unit(struct num n);
75
76
77static inline struct num make_num(double n)
78{
79    struct num res;
80
81    res.type = nt_mm;
82    res.exponent = 0;
83    res.n = n;
84    return res;
85}
86
87
88static inline struct num make_mm(double mm)
89{
90    struct num res;
91
92    res.type = nt_mm;
93    res.exponent = 1;
94    res.n = mm;
95    return res;
96}
97
98
99static inline struct num make_um(double um)
100{
101    struct num res;
102
103    res.type = nt_um;
104    res.exponent = 1;
105    res.n = um;
106    return res;
107}
108
109
110static inline struct num make_mil(double mil)
111{
112    struct num res;
113
114    res.type = nt_mil;
115    res.exponent = 1;
116    res.n = mil;
117    return res;
118}
119
120
121int to_unit(struct num *n);
122
123struct num op_num(const struct expr *self, const struct frame *frame);
124struct num op_var(const struct expr *self, const struct frame *frame);
125struct num op_string(const struct expr *self, const struct frame *frame);
126
127struct num op_sin(const struct expr *self, const struct frame *frame);
128struct num op_cos(const struct expr *self, const struct frame *frame);
129struct num op_sqrt(const struct expr *self, const struct frame *frame);
130
131struct num op_minus(const struct expr *self, const struct frame *frame);
132struct num op_floor(const struct expr *self, const struct frame *frame);
133
134struct num op_add(const struct expr *self, const struct frame *frame);
135struct num op_sub(const struct expr *self, const struct frame *frame);
136struct num op_mult(const struct expr *self, const struct frame *frame);
137struct num op_div(const struct expr *self, const struct frame *frame);
138
139struct expr *new_op(op_type op);
140struct expr *binary_op(op_type op, struct expr *a, struct expr *b);
141
142int var_eq(const struct frame *frame, const char *name,
143    const struct expr *expr);
144
145struct num eval_var(const struct frame *frame, const char *name);
146
147/*
148 * eval_str returns NULL if the result isn't a string. Evaluation may then
149 * be attempted with eval_num, and the result can be converted accordingly.
150 */
151const char *eval_str(const struct expr *expr, const struct frame *frame);
152
153struct num eval_num(const struct expr *expr, const struct frame *frame);
154
155/* if frame == NULL, we only check the syntax without expanding */
156char *expand(const char *name, const struct frame *frame);
157
158struct expr *new_num(struct num num);
159struct expr *parse_expr(const char *s);
160void free_expr(struct expr *expr);
161
162int parse_var(const char *s, const char **id, struct value **values,
163    int max_values);
164int parse_values(const char *s, struct value **values);
165void free_values(struct value *values, int keep_expr);
166
167#endif /* !EXPR_H */
168

Archive Download this file

Branches:
master



interactive