Merge branch 'topcom'
[barvinok.git] / evalue_read.c
blob04afc764c166f83fef61d19e087cc402ae2b78a5
1 #include <barvinok/util.h>
2 #include "evalue_read.h"
4 #define ALLOC(type) (type*)malloc(sizeof(type))
5 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
7 enum token_type { TOKEN_UNKNOWN = 256, TOKEN_VALUE, TOKEN_IDENT, TOKEN_GE,
8 TOKEN_NE, TOKEN_UNION, TOKEN_VARS };
10 struct token {
11 enum token_type type;
13 int line;
14 int col;
16 union {
17 Value v;
18 char *s;
19 } u;
22 static struct token *token_new(int line, int col)
24 struct token *tok = ALLOC(struct token);
25 tok->line = line;
26 tok->col = col;
27 return tok;
30 void token_free(struct token *tok)
32 if (tok->type == TOKEN_VALUE)
33 value_clear(tok->u.v);
34 else if (tok->type == TOKEN_IDENT)
35 free(tok->u.s);
36 free(tok);
39 struct stream {
40 FILE *file;
41 const char *str;
42 int line;
43 int col;
44 int eof;
46 char *buffer;
47 size_t size;
48 size_t len;
49 int c;
51 struct token *tokens[5];
52 int n_token;
55 static struct stream* stream_new()
57 int i;
58 struct stream *s = ALLOC(struct stream);
59 s->size = 256;
60 s->file = NULL;
61 s->str = NULL;
62 s->buffer = (char*)malloc(s->size);
63 s->len = 0;
64 s->line = 1;
65 s->col = 0;
66 s->eof = 0;
67 s->c = -1;
68 for (i = 0; i < 5; ++i)
69 s->tokens[i] = NULL;
70 s->n_token = 0;
71 return s;
74 static struct stream* stream_new_file(FILE *file)
76 struct stream *s = stream_new();
77 s->file = file;
78 return s;
81 static struct stream* stream_new_str(const char *str)
83 struct stream *s = stream_new();
84 s->str = str;
85 return s;
88 static int stream_getc(struct stream *s)
90 int c;
91 if (s->eof)
92 return -1;
93 if (s->file)
94 c = fgetc(s->file);
95 else {
96 c = *s->str++;
97 if (c == '\0')
98 c = -1;
100 if (c == -1)
101 s->eof = 1;
102 if (!s->eof) {
103 if (s->c == '\n') {
104 s->line++;
105 s->col = 0;
106 } else
107 s->col++;
109 s->c = c;
110 return c;
113 static void stream_ungetc(struct stream *s, int c)
115 if (s->file)
116 ungetc(c, s->file);
117 else
118 --s->str;
119 s->c = -1;
122 static void stream_push_char(struct stream *s, int c)
124 if (s->len >= s->size) {
125 s->size = (3*s->size)/2;
126 s->buffer = (char*)realloc(s->buffer, s->size);
128 s->buffer[s->len++] = c;
131 static struct token *stream_push_token(struct stream *s, struct token *tok)
133 assert(s->n_token < 5);
134 s->tokens[s->n_token++] = tok;
137 static struct token *stream_next_token(struct stream *s)
139 int c;
140 struct token *tok;
141 int line, col;
143 if (s->n_token)
144 return s->tokens[--s->n_token];
146 s->len = 0;
148 /* skip spaces */
149 while ((c = stream_getc(s)) != -1 && isspace(c))
150 /* nothing */
153 line = s->line;
154 col = s->col;
156 if (c == -1)
157 return NULL;
158 if (c == '(' ||
159 c == ')' ||
160 c == '+' ||
161 c == '/' ||
162 c == '*' ||
163 c == '^' ||
164 c == '=' ||
165 c == ',' ||
166 c == '_' ||
167 c == '[' ||
168 c == ']' ||
169 c == '{' ||
170 c == '}') {
171 tok = token_new(line, col);
172 tok->type = (enum token_type)c;
173 return tok;
175 if (c == '-' || isdigit(c)) {
176 tok = token_new(line, col);
177 tok->type = TOKEN_VALUE;
178 value_init(tok->u.v);
179 stream_push_char(s, c);
180 while ((c = stream_getc(s)) != -1 && isdigit(c))
181 stream_push_char(s, c);
182 if (c != -1)
183 stream_ungetc(s, c);
184 if (s->len == 1 && s->buffer[0] == '-')
185 value_set_si(tok->u.v, -1);
186 else {
187 stream_push_char(s, '\0');
188 mpz_set_str(tok->u.v, s->buffer, 0);
190 return tok;
192 if (c == '#' || isalpha(c)) {
193 tok = token_new(line, col);
194 stream_push_char(s, c);
195 while ((c = stream_getc(s)) != -1 && isalnum(c))
196 stream_push_char(s, c);
197 if (c != -1)
198 stream_ungetc(s, c);
199 stream_push_char(s, '\0');
200 if (!strcmp(s->buffer, "#variables")) {
201 tok->type = TOKEN_VARS;
202 } else if (s->buffer[0] == '#') {
203 tok->type = TOKEN_UNKNOWN;
204 } else if (!strcmp(s->buffer, "UNION")) {
205 tok->type = TOKEN_UNION;
206 } else {
207 tok->type = TOKEN_IDENT;
208 tok->u.s = strdup(s->buffer);
210 return tok;
212 if (c == '>') {
213 if ((c = stream_getc(s)) == '=') {
214 tok = token_new(line, col);
215 tok->type = TOKEN_GE;
216 return tok;
218 if (c != -1)
219 stream_ungetc(s, c);
221 if (c == '!') {
222 if ((c = stream_getc(s)) == '=') {
223 tok = token_new(line, col);
224 tok->type = TOKEN_NE;
225 return tok;
227 if (c != -1)
228 stream_ungetc(s, c);
231 tok = token_new(line, col);
232 tok->type = TOKEN_UNKNOWN;
233 return tok;
236 void stream_error(struct stream *s, struct token *tok, char *msg)
238 int line = tok ? tok->line : s->line;
239 int col = tok ? tok->col : s->col;
240 fprintf(stderr, "syntax error (%d, %d): %s\n", line, col, msg);
241 if (tok) {
242 if (tok->type < 256)
243 fprintf(stderr, "got '%c'\n", tok->type);
244 else
245 fprintf(stderr, "got token type %d\n", tok->type);
249 static void stream_free(struct stream *s)
251 free(s->buffer);
252 if (s->n_token != 0) {
253 struct token *tok = stream_next_token(s);
254 stream_error(s, tok, "unexpected token");
256 free(s);
259 struct parameter {
260 char *name;
261 int pos;
262 struct parameter *next;
265 struct parameter *parameter_new(const char *name, int pos, struct parameter *next)
267 struct parameter *p = ALLOC(struct parameter);
268 p->name = strdup(name);
269 p->pos = pos;
270 p->next = next;
271 return p;
274 static int parameter_pos(struct parameter **p, const char *s, int len)
276 int pos = *p ? (*p)->pos+1 : 0;
277 struct parameter *q;
279 if (len == -1)
280 len = strlen(s);
281 for (q = *p; q; q = q->next) {
282 if (strncmp(q->name, s, len) == 0)
283 break;
285 if (q)
286 pos = q->pos;
287 else
288 *p = parameter_new(s, pos, *p);
289 return pos;
292 static int optional_power(struct stream *s)
294 int pow;
295 struct token *tok;
296 tok = stream_next_token(s);
297 if (!tok)
298 return 1;
299 if (tok->type != '^') {
300 stream_push_token(s, tok);
301 return 1;
303 token_free(tok);
304 tok = stream_next_token(s);
305 if (!tok || tok->type != TOKEN_VALUE) {
306 stream_error(s, tok, "expecting exponent");
307 if (tok)
308 stream_push_token(s, tok);
309 return 1;
311 pow = VALUE_TO_INT(tok->u.v);
312 token_free(tok);
313 return pow;
316 static evalue *evalue_read_factor(struct stream *s, struct parameter **p);
317 static evalue *evalue_read_term(struct stream *s, struct parameter **p);
319 static evalue *create_fract_like(struct stream *s, evalue *arg, enode_type type,
320 struct parameter **p)
322 evalue *e;
323 int pow;
324 pow = optional_power(s);
326 e = ALLOC(evalue);
327 value_init(e->d);
328 e->x.p = new_enode(type, pow+2, -1);
329 value_clear(e->x.p->arr[0].d);
330 e->x.p->arr[0] = *arg;
331 free(arg);
332 evalue_set_si(&e->x.p->arr[1+pow], 1, 1);
333 while (--pow >= 0)
334 evalue_set_si(&e->x.p->arr[1+pow], 0, 1);
336 return e;
339 static evalue *create_relation(evalue *arg, int ne)
341 evalue *e;
343 e = ALLOC(evalue);
344 value_init(e->d);
345 e->x.p = new_enode(relation, 2+ne, 0);
346 value_clear(e->x.p->arr[0].d);
347 e->x.p->arr[0] = *arg;
348 free(arg);
349 if (ne)
350 evalue_set_si(&e->x.p->arr[1], 0, 1);
351 evalue_set_si(&e->x.p->arr[1+ne], 1, 1);
353 return e;
356 static evalue *read_fract(struct stream *s, struct token *tok, struct parameter **p)
358 evalue *arg;
360 tok = stream_next_token(s);
361 assert(tok);
362 assert(tok->type == '{');
364 token_free(tok);
365 arg = evalue_read_term(s, p);
366 tok = stream_next_token(s);
367 if (!tok || tok->type != '}') {
368 stream_error(s, tok, "expecting \"}\"");
369 if (tok)
370 stream_push_token(s, tok);
371 } else
372 token_free(tok);
374 return create_fract_like(s, arg, fractional, p);
377 static evalue *read_periodic(struct stream *s, struct parameter **p)
379 evalue **list;
380 int len;
381 int n;
382 evalue *e = NULL;
384 struct token *tok;
385 tok = stream_next_token(s);
386 assert(tok && tok->type == '[');
387 token_free(tok);
389 len = 100;
390 list = (evalue **)malloc(len * sizeof(evalue *));
391 n = 0;
393 for (;;) {
394 evalue *e = evalue_read_term(s, p);
395 if (!e) {
396 stream_error(s, NULL, "missing argument or list element");
397 goto out;
399 if (n >= len) {
400 len = (3*len)/2;
401 list = (evalue **)realloc(list, len * sizeof(evalue *));
403 list[n++] = e;
405 tok = stream_next_token(s);
406 if (!tok) {
407 stream_error(s, NULL, "unexpected EOF");
408 goto out;
410 if (tok->type != ',')
411 break;
412 token_free(tok);
415 if (n == 1 && (tok->type == '=' || tok->type == TOKEN_NE)) {
416 int ne = tok->type == TOKEN_NE;
417 token_free(tok);
418 tok = stream_next_token(s);
419 if (!tok || tok->type != TOKEN_VALUE) {
420 stream_error(s, tok, "expecting \"0\"");
421 if (tok)
422 stream_push_token(s, tok);
423 goto out;
425 token_free(tok);
426 tok = stream_next_token(s);
427 if (!tok || tok->type != ']') {
428 stream_error(s, tok, "expecting \"]\"");
429 if (tok)
430 stream_push_token(s, tok);
431 goto out;
433 token_free(tok);
434 e = create_relation(list[0], ne);
435 n = 0;
436 goto out;
439 if (tok->type != ']') {
440 stream_error(s, tok, "expecting \"]\"");
441 stream_push_token(s, tok);
442 goto out;
445 token_free(tok);
447 tok = stream_next_token(s);
448 if (tok && tok->type == '_') {
449 int pos;
450 token_free(tok);
451 tok = stream_next_token(s);
452 if (!tok || tok->type != TOKEN_IDENT) {
453 stream_error(s, tok, "expecting identifier");
454 if (tok)
455 stream_push_token(s, tok);
456 goto out;
458 e = ALLOC(evalue);
459 value_init(e->d);
460 pos = parameter_pos(p, tok->u.s, -1);
461 token_free(tok);
462 e->x.p = new_enode(periodic, n, pos+1);
463 while (--n >= 0) {
464 value_clear(e->x.p->arr[n].d);
465 e->x.p->arr[n] = *list[n];
466 free(list[n]);
468 } else if (n == 1) {
469 if (tok)
470 stream_push_token(s, tok);
471 e = create_fract_like(s, list[0], flooring, p);
472 n = 0;
473 } else {
474 stream_error(s, tok, "unexpected token");
475 if (tok)
476 stream_push_token(s, tok);
479 out:
480 while (--n >= 0) {
481 free_evalue_refs(list[n]);
482 free(list[n]);
484 free(list);
485 return e;
488 /* frees product on error */
489 static evalue *read_factor_and_multiply(struct stream *s, struct parameter **p,
490 evalue *product)
492 evalue *e2;
493 e2 = evalue_read_factor(s, p);
494 if (!e2) {
495 stream_error(s, NULL, "unexpected EOF");
496 free_evalue_refs(product);
497 free(product);
498 return NULL;
500 emul(e2, product);
501 free_evalue_refs(e2);
502 free(e2);
503 return product;
506 static evalue *evalue_read_factor(struct stream *s, struct parameter **p)
508 struct token *tok;
509 evalue *e = NULL;
511 tok = stream_next_token(s);
512 if (!tok)
513 return NULL;
515 if (tok->type == '(') {
516 token_free(tok);
517 e = evalue_read_term(s, p);
518 tok = stream_next_token(s);
519 if (!tok || tok->type != ')') {
520 stream_error(s, tok, "expecting \")\"");
521 if (tok)
522 stream_push_token(s, tok);
523 } else
524 token_free(tok);
525 } else if (tok->type == TOKEN_VALUE) {
526 e = ALLOC(evalue);
527 value_init(e->d);
528 value_set_si(e->d, 1);
529 value_init(e->x.n);
530 value_assign(e->x.n, tok->u.v);
531 token_free(tok);
532 tok = stream_next_token(s);
533 if (tok && tok->type == '/') {
534 token_free(tok);
535 tok = stream_next_token(s);
536 if (!tok || tok->type != TOKEN_VALUE) {
537 stream_error(s, tok, "expecting denominator");
538 if (tok)
539 stream_push_token(s, tok);
540 return NULL;
542 value_assign(e->d, tok->u.v);
543 token_free(tok);
544 } else if (tok && tok->type == TOKEN_IDENT) {
545 stream_push_token(s, tok);
546 e = read_factor_and_multiply(s, p, e);
547 } else if (tok)
548 stream_push_token(s, tok);
549 } else if (tok->type == TOKEN_IDENT) {
550 int pos = parameter_pos(p, tok->u.s, -1);
551 int pow = optional_power(s);
552 token_free(tok);
553 e = ALLOC(evalue);
554 value_init(e->d);
555 e->x.p = new_enode(polynomial, pow+1, pos+1);
556 evalue_set_si(&e->x.p->arr[pow], 1, 1);
557 while (--pow >= 0)
558 evalue_set_si(&e->x.p->arr[pow], 0, 1);
559 } else if (tok->type == '[') {
560 stream_push_token(s, tok);
561 e = read_periodic(s, p);
562 } else if (tok->type == '{') {
563 stream_push_token(s, tok);
564 e = read_fract(s, tok, p);
567 tok = stream_next_token(s);
568 if (tok && tok->type == '*') {
569 token_free(tok);
570 e = read_factor_and_multiply(s, p, e);
571 } else if (tok)
572 stream_push_token(s, tok);
574 return e;
577 static evalue *evalue_read_term(struct stream *s, struct parameter **p)
579 struct token *tok;
580 evalue *e = NULL;
582 e = evalue_read_factor(s, p);
583 if (!e)
584 return NULL;
586 tok = stream_next_token(s);
587 if (!tok)
588 return e;
590 if (tok->type == '+' || tok->type == TOKEN_VALUE) {
591 evalue *e2;
592 if (tok->type == '+')
593 token_free(tok);
594 else
595 stream_push_token(s, tok);
596 e2 = evalue_read_term(s, p);
597 if (!e2) {
598 stream_error(s, NULL, "unexpected EOF");
599 return NULL;
601 eadd(e2, e);
602 free_evalue_refs(e2);
603 free(e2);
604 } else
605 stream_push_token(s, tok);
607 return e;
610 struct constraint {
611 int type;
612 Vector *v;
613 struct constraint *next;
614 struct constraint *union_next;
617 static struct constraint *constraint_new()
619 struct constraint *c = ALLOC(struct constraint);
620 c->type = -1;
621 c->v = Vector_Alloc(16);
622 c->next = NULL;
623 c->union_next = NULL;
624 return c;
627 static void constraint_free(struct constraint *c)
629 while (c) {
630 struct constraint *next = c->next ? c->next : c->union_next;
631 Vector_Free(c->v);
632 free(c);
633 c = next;
637 static void constraint_extend(struct constraint *c, int pos)
639 Vector *v;
640 if (pos < c->v->Size)
641 return;
643 v = Vector_Alloc((3*c->v->Size)/2);
644 Vector_Copy(c->v->p, v->p, c->v->Size);
645 Vector_Free(c->v);
646 c->v = v;
649 static int evalue_read_constraint(struct stream *s, struct parameter **p,
650 struct constraint **constraints,
651 struct constraint *union_next)
653 struct token *tok;
654 struct constraint *c = NULL;
656 while ((tok = stream_next_token(s))) {
657 struct token *tok2;
658 int pos;
659 if (tok->type == '+')
660 token_free(tok);
661 else if (tok->type == TOKEN_IDENT) {
662 if (!c)
663 c = constraint_new();
664 pos = parameter_pos(p, tok->u.s, -1);
665 constraint_extend(c, 1+pos);
666 value_set_si(c->v->p[1+pos], 1);
667 token_free(tok);
668 } else if (tok->type == TOKEN_VALUE) {
669 if (!c)
670 c = constraint_new();
671 tok2 = stream_next_token(s);
672 if (tok2 && tok2->type == TOKEN_IDENT) {
673 pos = parameter_pos(p, tok2->u.s, -1);
674 constraint_extend(c, 1+pos);
675 value_assign(c->v->p[1+pos], tok->u.v);
676 token_free(tok);
677 token_free(tok2);
678 } else {
679 if (tok2)
680 stream_push_token(s, tok2);
681 value_assign(c->v->p[0], tok->u.v);
682 token_free(tok);
684 } else if (tok->type == TOKEN_GE || tok->type == '=') {
685 int type = tok->type == TOKEN_GE;
686 token_free(tok);
687 tok = stream_next_token(s);
688 if (!tok || tok->type != TOKEN_VALUE || value_notzero_p(tok->u.v)) {
689 stream_error(s, tok, "expecting \"0\"");
690 if (tok)
691 stream_push_token(s, tok);
692 *constraints = NULL;
693 } else {
694 c->type = type;
695 c->next = *constraints;
696 c->union_next = union_next;
697 *constraints = c;
698 token_free(tok);
700 break;
701 } else {
702 if (!c)
703 stream_push_token(s, tok);
704 else {
705 stream_error(s, tok, "unexpected token");
706 *constraints = NULL;
708 return 0;
711 return tok != NULL;
714 static struct constraint *evalue_read_domain(struct stream *s, struct parameter **p,
715 unsigned MaxRays)
717 struct constraint *constraints = NULL;
718 struct constraint *union_next = NULL;
719 struct token *tok;
720 int line;
722 tok = stream_next_token(s);
723 if (!tok)
724 return NULL;
725 stream_push_token(s, tok);
727 line = tok->line;
728 while (evalue_read_constraint(s, p, &constraints, union_next)) {
729 tok = stream_next_token(s);
730 if (tok) {
731 if (tok->type == TOKEN_UNION) {
732 token_free(tok);
733 tok = stream_next_token(s);
734 if (!tok) {
735 stream_error(s, NULL, "unexpected EOF");
736 return constraints;
738 stream_push_token(s, tok);
739 union_next = constraints;
740 constraints = NULL;
741 } else {
742 union_next = NULL;
743 stream_push_token(s, tok);
744 /* empty line separates domain from evalue */
745 if (tok->line > line+1)
746 break;
748 line = tok->line;
751 return constraints;
754 struct section {
755 struct constraint *constraints;
756 evalue *e;
757 struct section *next;
760 static char **extract_parameters(struct parameter *p, unsigned *nparam)
762 int i;
763 char **params;
765 *nparam = p ? p->pos+1 : 0;
766 params = ALLOCN(char *, *nparam);
767 for (i = 0; i < *nparam; ++i) {
768 struct parameter *next = p->next;
769 params[p->pos] = p->name;
770 free(p);
771 p = next;
773 return params;
776 static Polyhedron *constraints2domain(struct constraint *constraints,
777 unsigned nparam, unsigned MaxRays)
779 Polyhedron *D;
780 Matrix *M;
781 int n;
782 struct constraint *c;
783 struct constraint *union_next = NULL;
785 for (n = 0, c = constraints; c; ++n, c = c->next)
787 M = Matrix_Alloc(n, 1+nparam+1);
788 while (--n >= 0) {
789 struct constraint *next = constraints->next;
790 union_next = constraints->union_next;
791 Vector_Copy(constraints->v->p+1, M->p[n]+1, nparam);
792 if (constraints->type)
793 value_set_si(M->p[n][0], 1);
794 value_assign(M->p[n][1+nparam], constraints->v->p[0]);
795 constraints->next = NULL;
796 constraints->union_next = NULL;
797 constraint_free(constraints);
798 constraints = next;
800 D = Constraints2Polyhedron(M, MaxRays);
801 Matrix_Free(M);
803 if (union_next)
804 D = DomainConcat(D, constraints2domain(union_next, nparam, MaxRays));
805 return D;
808 static evalue *evalue_read_partition(struct stream *s, struct parameter *p,
809 char ***ppp,
810 unsigned *nparam, unsigned MaxRays)
812 struct section *part = NULL;
813 struct constraint *constraints;
814 evalue *e = NULL;
815 int m = 0;
817 while ((constraints = evalue_read_domain(s, &p, MaxRays))) {
818 struct section *sect;
819 evalue *e = evalue_read_term(s, &p);
820 if (!e) {
821 stream_error(s, NULL, "missing evalue");
822 break;
824 sect = ALLOC(struct section);
825 sect->constraints = constraints;
826 sect->e = e;
827 sect->next = part;
828 part = sect;
829 ++m;
832 if (part) {
833 Polyhedron *D;
834 int j;
836 *ppp = extract_parameters(p, nparam);
837 e = ALLOC(evalue);
838 value_init(e->d);
839 e->x.p = new_enode(partition, 2*m, *nparam);
841 for (j = 0; j < m; ++j) {
842 int n;
843 struct section *next = part->next;
844 constraints = part->constraints;
845 D = constraints2domain(part->constraints, *nparam, MaxRays);
846 EVALUE_SET_DOMAIN(e->x.p->arr[2*j], D);
847 value_clear(e->x.p->arr[2*j+1].d);
848 e->x.p->arr[2*j+1] = *part->e;
849 free(part->e);
850 free(part);
851 part = next;
854 return e;
857 static evalue *evalue_read(struct stream *s, const char *var_list, char ***ppp,
858 unsigned *nvar, unsigned *nparam, unsigned MaxRays)
860 struct token *tok;
861 evalue *e;
862 struct parameter *p = NULL;
863 char *next;
864 int nv;
866 if (var_list) {
867 while ((next = strchr(var_list, ','))) {
868 if (next > var_list)
869 parameter_pos(&p, var_list, next-var_list);
870 var_list = next+1;
872 if (strlen(var_list) > 0)
873 parameter_pos(&p, var_list, -1);
874 nv = p ? p->pos+1 : 0;
875 } else
876 nv = -1;
878 if (!(tok = stream_next_token(s)))
879 return NULL;
881 if (tok->type == TOKEN_VARS) {
882 token_free(tok);
883 for (;;) {
884 tok = stream_next_token(s);
885 if (!tok || tok->type != TOKEN_IDENT) {
886 stream_error(s, tok, "expecting identifier");
887 break;
889 if (nv == -1)
890 parameter_pos(&p, tok->u.s, -1);
891 token_free(tok);
892 tok = stream_next_token(s);
893 if (!tok || tok->type != ',')
894 break;
895 token_free(tok);
897 if (!tok)
898 return NULL;
899 if (nv = -1)
900 nv = p ? p->pos+1 : 0;
903 if (tok->type == '(') {
904 stream_push_token(s, tok);
905 e = evalue_read_term(s, &p);
906 *ppp = extract_parameters(p, nparam);
907 } else if (tok->type == TOKEN_VALUE) {
908 struct token *tok2 = stream_next_token(s);
909 if (tok2)
910 stream_push_token(s, tok2);
911 stream_push_token(s, tok);
912 if (tok2 && (tok2->type == TOKEN_IDENT || tok2->type == TOKEN_GE))
913 e = evalue_read_partition(s, p, ppp, nparam, MaxRays);
914 else {
915 e = evalue_read_term(s, &p);
916 *ppp = extract_parameters(p, nparam);
918 } else if (tok->type == TOKEN_IDENT) {
919 stream_push_token(s, tok);
920 e = evalue_read_partition(s, p, ppp, nparam, MaxRays);
921 } else {
922 stream_error(s, tok, "unexpected token");
923 *nparam = nv == -1 ? 0 : nv;
924 e = NULL;
926 if (nv == -1)
927 *nvar = *nparam;
928 else
929 *nvar = nv;
930 *nparam -= *nvar;
931 return e;
934 evalue *evalue_read_from_file(FILE *in, const char *var_list, char ***ppp,
935 unsigned *nvar, unsigned *nparam, unsigned MaxRays)
937 evalue *e;
938 struct stream *s = stream_new_file(in);
939 e = evalue_read(s, var_list, ppp, nvar, nparam, MaxRays);
940 stream_free(s);
941 return e;
944 evalue *evalue_read_from_str(const char *str, const char *var_list, char ***ppp,
945 unsigned *nvar, unsigned *nparam, unsigned MaxRays)
947 evalue *e;
948 struct stream *s = stream_new_str(str);
949 e = evalue_read(s, var_list, ppp, nvar, nparam, MaxRays);
950 stream_free(s);
951 return e;