123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /*
- * expr.h - Expressions and values
- *
- * Written 2009, 2012, 2016 by Werner Almesberger
- * Copyright 2009, 2012, 2016 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_um,
- 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_um || 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_um(double um)
- {
- struct num res;
- res.type = nt_um;
- res.exponent = 1;
- res.n = um;
- 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_floor(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);
- int var_eq(const struct frame *frame, const char *name,
- const struct expr *expr);
- 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 */
|