expr.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. #ifndef EXPR_H
  13. #define EXPR_H
  14. #include <math.h>
  15. #define UNDEF HUGE_VAL
  16. struct frame;
  17. struct expr;
  18. struct value;
  19. enum num_type {
  20. nt_none,
  21. nt_mm,
  22. nt_um,
  23. nt_mil,
  24. };
  25. struct num {
  26. enum num_type type;
  27. int exponent;
  28. double n;
  29. };
  30. typedef struct num (*op_type)(const struct expr *self,
  31. const struct frame *frame);
  32. struct expr {
  33. op_type op;
  34. union {
  35. struct num num;
  36. const char *var;
  37. char *str;
  38. struct {
  39. struct expr *a;
  40. struct expr *b;
  41. } op;
  42. } u;
  43. int lineno;
  44. };
  45. extern struct num undef;
  46. #define is_undef(num) ((num).type == nt_none)
  47. #define is_dimensionless(num) (!(num).exponent)
  48. static inline int is_distance(struct num num)
  49. {
  50. return (num.type == nt_mm || num.type == nt_um || num.type == nt_mil)
  51. && num.exponent == 1;
  52. }
  53. void fail_expr(const struct expr *expr);
  54. const char *str_unit(struct num n);
  55. static inline struct num make_num(double n)
  56. {
  57. struct num res;
  58. res.type = nt_mm;
  59. res.exponent = 0;
  60. res.n = n;
  61. return res;
  62. }
  63. static inline struct num make_mm(double mm)
  64. {
  65. struct num res;
  66. res.type = nt_mm;
  67. res.exponent = 1;
  68. res.n = mm;
  69. return res;
  70. }
  71. static inline struct num make_um(double um)
  72. {
  73. struct num res;
  74. res.type = nt_um;
  75. res.exponent = 1;
  76. res.n = um;
  77. return res;
  78. }
  79. static inline struct num make_mil(double mil)
  80. {
  81. struct num res;
  82. res.type = nt_mil;
  83. res.exponent = 1;
  84. res.n = mil;
  85. return res;
  86. }
  87. int to_unit(struct num *n);
  88. struct num op_num(const struct expr *self, const struct frame *frame);
  89. struct num op_var(const struct expr *self, const struct frame *frame);
  90. struct num op_string(const struct expr *self, const struct frame *frame);
  91. struct num op_sin(const struct expr *self, const struct frame *frame);
  92. struct num op_cos(const struct expr *self, const struct frame *frame);
  93. struct num op_sqrt(const struct expr *self, const struct frame *frame);
  94. struct num op_minus(const struct expr *self, const struct frame *frame);
  95. struct num op_floor(const struct expr *self, const struct frame *frame);
  96. struct num op_add(const struct expr *self, const struct frame *frame);
  97. struct num op_sub(const struct expr *self, const struct frame *frame);
  98. struct num op_mult(const struct expr *self, const struct frame *frame);
  99. struct num op_div(const struct expr *self, const struct frame *frame);
  100. struct expr *new_op(op_type op);
  101. struct expr *binary_op(op_type op, struct expr *a, struct expr *b);
  102. int var_eq(const struct frame *frame, const char *name,
  103. const struct expr *expr);
  104. struct num eval_var(const struct frame *frame, const char *name);
  105. /*
  106. * eval_str returns NULL if the result isn't a string. Evaluation may then
  107. * be attempted with eval_num, and the result can be converted accordingly.
  108. */
  109. const char *eval_str(const struct expr *expr, const struct frame *frame);
  110. struct num eval_num(const struct expr *expr, const struct frame *frame);
  111. /* if frame == NULL, we only check the syntax without expanding */
  112. char *expand(const char *name, const struct frame *frame);
  113. struct expr *new_num(struct num num);
  114. struct expr *parse_expr(const char *s);
  115. void free_expr(struct expr *expr);
  116. int parse_var(const char *s, const char **id, struct value **values,
  117. int max_values);
  118. int parse_values(const char *s, struct value **values);
  119. void free_values(struct value *values, int keep_expr);
  120. #endif /* !EXPR_H */