expr.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /*
  2. * expr.c - Expressions and values
  3. *
  4. * Written 2009, 2010, 2012, 2016 by Werner Almesberger
  5. * Copyright 2009, 2010, 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. #include <stdlib.h>
  13. #include <string.h>
  14. #include <math.h>
  15. #include "util.h"
  16. #include "error.h"
  17. #include "obj.h"
  18. #include "unparse.h"
  19. #include "fpd.h"
  20. #include "expr.h"
  21. struct num undef = { .type = nt_none };
  22. /* ----- error reporting --------------------------------------------------- */
  23. void fail_expr(const struct expr *expr)
  24. {
  25. char *s;
  26. s = unparse(expr);
  27. fail("in \"%s\" at line %d", s, expr->lineno);
  28. free(s);
  29. }
  30. /* ----- unit conversion --------------------------------------------------- */
  31. /*
  32. * If an expression contains a typo, we may get large exponents. Thus, we just
  33. * "sprintf" in order to be able to handle any integer. Since the number of
  34. * different exponents in a session will still be small, we use "unique" to
  35. * give us a constant string, so that we don't have to worry about memory
  36. * allocation.
  37. */
  38. const char *str_unit(struct num n)
  39. {
  40. const char *unit;
  41. char buf[20]; /* @@@ plenty */
  42. if (n.exponent == 0)
  43. return "";
  44. switch (n.type) {
  45. case nt_mm:
  46. unit = "mm";
  47. break;
  48. case nt_um:
  49. unit = "um";
  50. break;
  51. case nt_mil:
  52. unit = "mil";
  53. break;
  54. default:
  55. abort();
  56. }
  57. if (n.exponent == 1)
  58. return unit;
  59. sprintf(buf, "%s^%d", unit, n.exponent);
  60. return unique(buf);
  61. }
  62. int to_unit(struct num *n)
  63. {
  64. if (!is_distance(*n)) {
  65. fail("%s^%d is not a distance",
  66. n->type == nt_mm ? "mm" : n->type == nt_um ? "um" :
  67. n->type == nt_mil ? "mil" : "?", n->exponent);
  68. return 0;
  69. }
  70. switch (n->type) {
  71. case nt_mil:
  72. n->n = mil_to_units(n->n);
  73. break;
  74. case nt_mm:
  75. n->n = mm_to_units(n->n);
  76. break;
  77. case nt_um:
  78. n->n = um_to_units(n->n);
  79. break;
  80. default:
  81. abort();
  82. }
  83. return 1;
  84. }
  85. /* ----- number to string conversion (hackish) ----------------------------- */
  86. static char *num_to_string(struct num n)
  87. {
  88. static char buf[100]; /* enough :-) */
  89. snprintf(buf, sizeof(buf), "%lg%s", n.n, str_unit(n));
  90. return buf;
  91. }
  92. /* ----- primary expressions ----------------------------------------------- */
  93. struct num op_string(const struct expr *self, const struct frame *frame)
  94. {
  95. fail("cannot evaluate string");
  96. return undef;
  97. }
  98. struct num op_num(const struct expr *self, const struct frame *frame)
  99. {
  100. return self->u.num;
  101. }
  102. /*
  103. * We have two modes of operation: during instantiation and editing, after
  104. * instantiation. During instantiation, we follow curr_row and curr_parent.
  105. * These pointers are NULL when instantiation finishes, and we use this as a
  106. * signal that we're now in editing mode. In editing mode, the "active" values
  107. * are used instead of the "current" ones.
  108. */
  109. struct num eval_var(const struct frame *frame, const char *name)
  110. {
  111. const struct table *table;
  112. const struct loop *loop;
  113. const struct value *value;
  114. struct var *var;
  115. struct num res;
  116. for (table = frame->tables; table; table = table->next) {
  117. value = table->curr_row ? table->curr_row->values :
  118. table->active_row->values;
  119. for (var = table->vars; var; var = var->next) {
  120. if (!var->key && var->name == name) {
  121. if (var->visited) {
  122. fail("recursive evaluation through "
  123. "\"%s\"", name);
  124. return undef;
  125. }
  126. var->visited = 1;
  127. res = eval_num(value->expr, frame);
  128. var->visited = 0;
  129. return res;
  130. }
  131. value = value->next;
  132. }
  133. }
  134. for (loop = frame->loops; loop; loop = loop->next)
  135. if (loop->var.name == name) {
  136. if (loop->curr_value == UNDEF)
  137. return make_num(loop->n+loop->active);
  138. if (!loop->initialized) {
  139. fail("uninitialized loop \"%s\"", name);
  140. return undef;
  141. }
  142. return make_num(loop->curr_value);
  143. }
  144. if (frame->curr_parent)
  145. return eval_var(frame->curr_parent, name);
  146. if (frame->active_ref)
  147. return eval_var(frame->active_ref->frame, name);
  148. return undef;
  149. }
  150. static const char *eval_string_var(const struct frame *frame, const char *name)
  151. {
  152. const struct table *table;
  153. const struct loop *loop;
  154. const struct value *value;
  155. struct var *var;
  156. const char *res;
  157. for (table = frame->tables; table; table = table->next) {
  158. value = table->curr_row ? table->curr_row->values :
  159. table->active_row->values;
  160. for (var = table->vars; var; var = var->next) {
  161. if (!var->key && var->name == name) {
  162. if (var->visited)
  163. return NULL;
  164. var->visited = 1;
  165. res = eval_str(value->expr, frame);
  166. var->visited = 0;
  167. return res;
  168. }
  169. value = value->next;
  170. }
  171. }
  172. for (loop = frame->loops; loop; loop = loop->next)
  173. if (loop->var.name == name)
  174. return NULL;
  175. if (frame->curr_parent)
  176. return eval_string_var(frame->curr_parent, name);
  177. if (frame->active_ref)
  178. return eval_string_var(frame->active_ref->frame, name);
  179. return NULL;
  180. }
  181. struct num op_var(const struct expr *self, const struct frame *frame)
  182. {
  183. struct num res;
  184. res = eval_var(frame, self->u.var);
  185. if (is_undef(res))
  186. fail("undefined variable \"%s\"", self->u.var);
  187. return res;
  188. }
  189. /* ----- Variable equivalence ---------------------------------------------- */
  190. static int num_eq(struct num a, struct num b)
  191. {
  192. if (a.exponent != b.exponent)
  193. return 0;
  194. if (a.exponent && a.type != b.type) {
  195. if (a.type == nt_mil)
  196. return mil_to_mm(a.n, a.exponent) == b.n;
  197. else
  198. return a.n == mil_to_mm(b.n, b.exponent);
  199. }
  200. return a.n == b.n;
  201. }
  202. int var_eq(const struct frame *frame, const char *name,
  203. const struct expr *expr)
  204. {
  205. const char *vs, *es;
  206. struct num vn, en;
  207. vs = eval_string_var(frame, name);
  208. if (!vs) {
  209. vn = eval_var(frame, name);
  210. if (is_undef(vn)) {
  211. fail("undefined variable \"%s\"", name);
  212. return -1;
  213. }
  214. }
  215. es = eval_str(expr, frame);
  216. if (!es) {
  217. en = eval_num(expr, frame);
  218. if (is_undef(en))
  219. return -1;
  220. }
  221. if (vs || es) {
  222. if (!vs)
  223. vs = num_to_string(vn);
  224. if (!es)
  225. es = num_to_string(en);
  226. return !strcmp(vs, es);
  227. } else {
  228. return num_eq(vn, en);
  229. }
  230. }
  231. /* ----- arithmetic -------------------------------------------------------- */
  232. static void converge_to_mm(struct num *a)
  233. {
  234. switch (a->type) {
  235. case nt_mil:
  236. a->type = nt_mm;
  237. a->n = mil_to_mm(a->n, a->exponent);
  238. break;
  239. case nt_um:
  240. a->type = nt_mm;
  241. a->n = um_to_mm(a->n, a->exponent);
  242. break;
  243. case nt_mm:
  244. break;
  245. default:
  246. abort();
  247. }
  248. }
  249. static struct num compatible_sum(struct num *a, struct num *b)
  250. {
  251. struct num res;
  252. if (a->type != b->type) {
  253. converge_to_mm(a);
  254. converge_to_mm(b);
  255. }
  256. if (a->exponent != b->exponent) {
  257. fail("incompatible exponents (%d, %d)",
  258. a->exponent, b->exponent);
  259. return undef;
  260. }
  261. res.type = a->type;
  262. res.exponent = a->exponent;
  263. res.n = 0; /* keep gcc happy */
  264. return res;
  265. }
  266. static struct num compatible_mult(struct num *a, struct num *b,
  267. int exponent)
  268. {
  269. struct num res;
  270. if (a->type != b->type) {
  271. converge_to_mm(a);
  272. converge_to_mm(b);
  273. }
  274. res.type = a->type;
  275. res.exponent = exponent;
  276. res.n = 0; /* keep gcc happy */
  277. return res;
  278. }
  279. static struct num sin_cos(const struct expr *self,
  280. const struct frame *frame, double (*fn)(double arg))
  281. {
  282. struct num res;
  283. res = eval_num(self->u.op.a, frame);
  284. if (is_undef(res))
  285. return undef;
  286. if (!is_dimensionless(res)) {
  287. fail("angle must be dimensionless");
  288. return undef;
  289. }
  290. res.n = fn(res.n/180.0*M_PI);
  291. return res;
  292. }
  293. struct num op_sin(const struct expr *self, const struct frame *frame)
  294. {
  295. return sin_cos(self, frame, sin);
  296. }
  297. struct num op_cos(const struct expr *self, const struct frame *frame)
  298. {
  299. return sin_cos(self, frame, cos);
  300. }
  301. struct num op_sqrt(const struct expr *self, const struct frame *frame)
  302. {
  303. struct num res;
  304. res = eval_num(self->u.op.a, frame);
  305. if (is_undef(res))
  306. return undef;
  307. if (res.exponent & 1) {
  308. fail("exponent of sqrt argument must be a multiple of two");
  309. return undef;
  310. }
  311. if (res.n < 0) {
  312. fail("argument of sqrt must be positive");
  313. return undef;
  314. }
  315. res.n = sqrt(res.n);
  316. res.exponent >>= 1;
  317. return res;
  318. }
  319. struct num op_minus(const struct expr *self, const struct frame *frame)
  320. {
  321. struct num res;
  322. res = eval_num(self->u.op.a, frame);
  323. if (!is_undef(res))
  324. res.n = -res.n;
  325. return res;
  326. }
  327. struct num op_floor(const struct expr *self, const struct frame *frame)
  328. {
  329. struct num res;
  330. res = eval_num(self->u.op.a, frame);
  331. if (!is_undef(res))
  332. res.n = floor(res.n);
  333. return res;
  334. }
  335. #define BINARY \
  336. struct num a, b, res; \
  337. \
  338. a = eval_num(self->u.op.a, frame); \
  339. if (is_undef(a)) \
  340. return undef; \
  341. b = eval_num(self->u.op.b, frame); \
  342. if (is_undef(b)) \
  343. return undef;
  344. struct num op_add(const struct expr *self, const struct frame *frame)
  345. {
  346. BINARY;
  347. res = compatible_sum(&a, &b);
  348. if (is_undef(res))
  349. return undef;
  350. res.n = a.n+b.n;
  351. return res;
  352. }
  353. struct num op_sub(const struct expr *self, const struct frame *frame)
  354. {
  355. BINARY;
  356. res = compatible_sum(&a, &b);
  357. if (is_undef(res))
  358. return undef;
  359. res.n = a.n-b.n;
  360. return res;
  361. }
  362. struct num op_mult(const struct expr *self, const struct frame *frame)
  363. {
  364. BINARY;
  365. res = compatible_mult(&a, &b, a.exponent+b.exponent);
  366. res.n = a.n*b.n;
  367. return res;
  368. }
  369. struct num op_div(const struct expr *self, const struct frame *frame)
  370. {
  371. BINARY;
  372. if (!b.n) {
  373. fail("division by zero");
  374. return undef;
  375. }
  376. res = compatible_mult(&a, &b, a.exponent-b.exponent);
  377. res.n = a.n/b.n;
  378. return res;
  379. }
  380. /* ----- expression construction ------------------------------------------- */
  381. struct expr *new_op(op_type op)
  382. {
  383. struct expr *expr;
  384. expr = alloc_type(struct expr);
  385. expr->op = op;
  386. expr->lineno = lineno;
  387. return expr;
  388. }
  389. struct expr *binary_op(op_type op, struct expr *a, struct expr *b)
  390. {
  391. struct expr *expr;
  392. expr = new_op(op);
  393. expr->u.op.a = a;
  394. expr->u.op.b = b;
  395. return expr;
  396. }
  397. const char *eval_str(const struct expr *expr, const struct frame *frame)
  398. {
  399. if (expr->op == op_string)
  400. return expr->u.str;
  401. if (expr->op == op_var)
  402. return eval_string_var(frame, expr->u.var);
  403. return NULL;
  404. }
  405. struct num eval_num(const struct expr *expr, const struct frame *frame)
  406. {
  407. return expr->op(expr, frame);
  408. }
  409. /* ----- string expansion -------------------------------------------------- */
  410. char *expand(const char *name, const struct frame *frame)
  411. {
  412. int len = strlen(name);
  413. char *buf = alloc_size(len+1);
  414. const char *s, *s0;
  415. char *var;
  416. const char *var_unique, *value_string;
  417. struct num value;
  418. int i, value_len;
  419. i = 0;
  420. for (s = name; *s; s++) {
  421. if (*s != '$') {
  422. buf[i++] = *s;
  423. continue;
  424. }
  425. s0 = ++s;
  426. if (*s != '{') {
  427. while (is_id_char(*s, s == s0))
  428. s++;
  429. if (s == s0) {
  430. if (*s) {
  431. goto invalid;
  432. } else {
  433. fail("incomplete variable name");
  434. goto fail;
  435. }
  436. }
  437. var = strnalloc(s0, s-s0);
  438. len -= s-s0+1;
  439. s--;
  440. } else {
  441. s++;
  442. while (*s != '}') {
  443. if (!*s) {
  444. fail("unfinished \"${...}\"");
  445. goto fail;
  446. }
  447. if (!is_id_char(*s, s == s0+1))
  448. goto invalid;
  449. s++;
  450. }
  451. var = strnalloc(s0+1, s-s0-1);
  452. len -= s-s0+2;
  453. }
  454. if (!frame)
  455. continue;
  456. var_unique = unique(var);
  457. free(var);
  458. value_string = eval_string_var(frame, var_unique);
  459. if (!value_string) {
  460. value = eval_var(frame, var_unique);
  461. if (is_undef(value)) {
  462. fail("undefined variable \"%s\"", var_unique);
  463. goto fail;
  464. }
  465. value_string = num_to_string(value);
  466. }
  467. value_len = strlen(value_string);
  468. len += value_len;
  469. buf = realloc(buf, len+1);
  470. if (!buf)
  471. abort();
  472. strcpy(buf+i, value_string);
  473. i += value_len;
  474. }
  475. buf[i] = 0;
  476. return buf;
  477. invalid:
  478. fail("invalid character in variable name");
  479. fail:
  480. free(buf);
  481. return NULL;
  482. }
  483. /* ----- make a number -----------------------------------------------------*/
  484. struct expr *new_num(struct num num)
  485. {
  486. struct expr *expr;
  487. expr = new_op(op_num);
  488. expr->u.num = num;
  489. return expr;
  490. }
  491. /* ----- expression-only parser -------------------------------------------- */
  492. struct expr *parse_expr(const char *s)
  493. {
  494. scan_expr(s);
  495. return yyparse() ? NULL : expr_result;
  496. }
  497. static void vacate_op(struct expr *expr)
  498. {
  499. if (expr->op == op_num || expr->op == op_var)
  500. return;
  501. if (expr->op == op_string) {
  502. free(expr->u.str);
  503. return;
  504. }
  505. if (expr->op == op_minus || expr->op == op_floor ||
  506. expr->op == op_sin || expr->op == op_cos || expr->op == op_sqrt) {
  507. free_expr(expr->u.op.a);
  508. return;
  509. }
  510. if (expr->op == op_add || expr->op == op_sub ||
  511. expr->op == op_mult || expr->op == op_div) {
  512. free_expr(expr->u.op.a);
  513. free_expr(expr->u.op.b);
  514. return;
  515. }
  516. abort();
  517. }
  518. void free_expr(struct expr *expr)
  519. {
  520. vacate_op(expr);
  521. free(expr);
  522. }
  523. /* ----- [var =] value, ... shortcuts -------------------------------------- */
  524. int parse_var(const char *s, const char **id, struct value **values,
  525. int max_values)
  526. {
  527. const struct value *value;
  528. int n;
  529. scan_var(s);
  530. if (yyparse())
  531. return -1;
  532. if (id)
  533. *id = var_id;
  534. *values = var_value_list;
  535. n = 0;
  536. for (value = var_value_list; value; value = value->next)
  537. n++;
  538. if (max_values == -1 || n <= max_values)
  539. return n;
  540. free_values(var_value_list, 0);
  541. return -1;
  542. }
  543. int parse_values(const char *s, struct value **values)
  544. {
  545. const struct value *value;
  546. int n;
  547. scan_values(s);
  548. if (yyparse())
  549. return -1;
  550. *values = var_value_list;
  551. n = 0;
  552. for (value = var_value_list; value; value = value->next)
  553. n++;
  554. return n;
  555. }
  556. void free_values(struct value *values, int keep_expr)
  557. {
  558. struct value *next;
  559. while (values) {
  560. next = values->next;
  561. if (!keep_expr)
  562. free_expr(values->expr);
  563. free(values);
  564. values = next;
  565. }
  566. }