File: expr.h

package info (click to toggle)
fped 0.0%2Br5986-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 900 kB
  • sloc: ansic: 12,009; yacc: 1,088; sh: 688; lex: 197; makefile: 132
file content (150 lines) | stat: -rw-r--r-- 3,352 bytes parent folder | download
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
145
146
147
148
149
150
/*
 * expr.h - Expressions and values
 *
 * Written 2009 by Werner Almesberger
 * Copyright 2009 by Werner Almesberger
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */


#ifndef EXPR_H
#define EXPR_H

#include <math.h>


#define UNDEF HUGE_VAL


struct frame;
struct expr;
struct value;

enum num_type {
	nt_none,
	nt_mm,
	nt_mil,
};

struct num {
	enum num_type type;
	int exponent;
	double n;
};

typedef struct num (*op_type)(const struct expr *self,
    const struct frame *frame);

struct expr {
	op_type op;
	union {
		struct num num;
		const char *var;
		char *str;
		struct {
			struct expr *a;
			struct expr *b;
		} op;
	} u;
	int lineno;
};


extern struct num undef;


#define	is_undef(num)		((num).type == nt_none)
#define	is_dimensionless(num)	(!(num).exponent)


static inline int is_distance(struct num num)
{
	return (num.type == nt_mm || num.type == nt_mil) && num.exponent == 1;
}


void fail_expr(const struct expr *expr);

const char *str_unit(struct num n);


static inline struct num make_num(double n)
{
	struct num res;

	res.type = nt_mm;
	res.exponent = 0;
	res.n = n;
	return res;
}


static inline struct num make_mm(double mm)
{
	struct num res;

	res.type = nt_mm;
	res.exponent = 1;
	res.n = mm;
	return res;
}


static inline struct num make_mil(double mil)
{
	struct num res;

	res.type = nt_mil;
	res.exponent = 1;
	res.n = mil;
	return res;
}


int to_unit(struct num *n);

struct num op_num(const struct expr *self, const struct frame *frame);
struct num op_var(const struct expr *self, const struct frame *frame);
struct num op_string(const struct expr *self, const struct frame *frame);

struct num op_sin(const struct expr *self, const struct frame *frame);
struct num op_cos(const struct expr *self, const struct frame *frame);
struct num op_sqrt(const struct expr *self, const struct frame *frame);

struct num op_minus(const struct expr *self, const struct frame *frame);

struct num op_add(const struct expr *self, const struct frame *frame);
struct num op_sub(const struct expr *self, const struct frame *frame);
struct num op_mult(const struct expr *self, const struct frame *frame);
struct num op_div(const struct expr *self, const struct frame *frame);

struct expr *new_op(op_type op);
struct expr *binary_op(op_type op, struct expr *a, struct expr *b);

struct num eval_var(const struct frame *frame, const char *name);

/*
 * eval_str returns NULL if the result isn't a string. Evaluation may then
 * be attempted with eval_num, and the result can be converted accordingly.
 */
const char *eval_str(const struct expr *expr, const struct frame *frame);

struct num eval_num(const struct expr *expr, const struct frame *frame);

/* if frame == NULL, we only check the syntax without expanding */
char *expand(const char *name, const struct frame *frame);

struct expr *new_num(struct num num);
struct expr *parse_expr(const char *s);
void free_expr(struct expr *expr);

int parse_var(const char *s, const char **id, struct value **values,
    int max_values);
int parse_values(const char *s, struct value **values);
void free_values(struct value *values, int keep_expr);

#endif /* !EXPR_H */