Little fix after the last commit (mostly a git fail)
[eigenmath-fx.git] / print.cpp
blobd526e2e33a5ee06c952a76d78e239b59b5e39b90
1 // tty style printing
3 #include "stdafx.h"
4 #include "defs.h"
5 #include "console.h"
7 #include "tex/TeX.h"
9 #define TEX 1
10 #define MAX_TEX_WIDTH 110
11 #define MAX_TEX_HEIGHT 50
13 //char* get_tex_flag_address();
15 int tex_flag = 1;
17 int out_index, out_length;
18 char *out_str;
19 static int char_count, last_char;
21 char *power_str = "^";
23 extern "C"{
24 int* get_tex_flag_address()
26 return &tex_flag;
30 void
31 print(U *p)
33 print_expr(p);
36 void
37 printline(U *p)
39 int old_tex_flag = tex_flag;
40 #ifdef TEX
41 int width, height, baseline;
42 char* edit_line = (char*)Console_GetEditLine();
43 //tex_flag = 1;
44 #endif
45 print_expr(p);
46 #ifdef TEX
47 TeX_sizeComplex(edit_line, &width, &height, &baseline);
48 /*if(width > MAX_TEX_WIDTH || height > MAX_TEX_HEIGHT) {
49 tex_flag = 0;
50 Console_Clear_EditLine();
51 print_expr(p);
52 }*/
54 tex_flag = old_tex_flag;
55 #endif
58 void
59 print_subexpr(U *p)
61 print_char('(');
62 print_expr(p);
63 print_char(')');
66 void
67 print_expr(U *p)
69 if (isadd(p)) {
70 p = cdr(p);
71 if (sign_of_term(car(p)) == '-')
72 print_str("-");
73 print_term(car(p));
74 p = cdr(p);
75 while (iscons(p)) {
76 if (sign_of_term(car(p)) == '+')
77 if (test_flag == 0)
78 print_str(" + ");
79 else
80 print_str("+");
81 else
82 if (test_flag == 0)
83 print_str(" - ");
84 else
85 print_str("-");
86 print_term(car(p));
87 p = cdr(p);
89 } else {
90 if (sign_of_term(p) == '-')
91 print_str("-");
92 print_term(p);
96 int
97 sign_of_term(U *p)
99 if (car(p) == symbol(MULTIPLY) && isnum(cadr(p)) && lessp(cadr(p), zero))
100 return '-';
101 else if (isnum(p) && lessp(p, zero))
102 return '-';
103 else
104 return '+';
107 #define A p3
108 #define B p4
110 void
111 print_a_over_b(U *p)
113 int flag, n, d;
114 U *p1, *p2;
116 save();
118 // count numerators and denominators
120 n = 0;
121 d = 0;
123 p1 = cdr(p);
124 p2 = car(p1);
126 if (isrational(p2)) {
127 push(p2);
128 mp_numerator();
129 absval();
130 A = pop();
131 push(p2);
132 mp_denominator();
133 B = pop();
134 if (!isplusone(A))
135 n++;
136 if (!isplusone(B))
137 d++;
138 p1 = cdr(p1);
139 } else {
140 A = one;
141 B = one;
144 while (iscons(p1)) {
145 p2 = car(p1);
146 if (is_denominator(p2))
147 d++;
148 else
149 n++;
150 p1 = cdr(p1);
153 //#ifdef TEX
154 if(tex_flag) print_str("\\frac{");
155 //#endif
157 if (n == 0)
158 print_char('1');
159 else {
160 flag = 0;
161 p1 = cdr(p);
162 if (isrational(car(p1)))
163 p1 = cdr(p1);
164 if (!isplusone(A)) {
165 print_factor(A);
166 flag = 1;
168 while (iscons(p1)) {
169 p2 = car(p1);
170 if (is_denominator(p2))
172 else {
173 if (flag)
174 print_multiply_sign();
175 print_factor(p2);
176 flag = 1;
178 p1 = cdr(p1);
182 //#ifdef TEX
183 if(tex_flag) print_str("}{");
184 else {
185 //#else
186 if (test_flag == 0)
187 print_str(" / ");
188 else
189 print_str("/");
191 if (d > 1)
192 print_char('(');
194 //#endif
196 flag = 0;
197 p1 = cdr(p);
199 if (isrational(car(p1)))
200 p1 = cdr(p1);
202 if (!isplusone(B)) {
203 print_factor(B);
204 flag = 1;
207 while (iscons(p1)) {
208 p2 = car(p1);
209 if (is_denominator(p2)) {
210 if (flag)
211 print_multiply_sign();
212 print_denom(p2, d);
213 flag = 1;
215 p1 = cdr(p1);
218 //#ifdef TEX
220 //#else
221 if(!tex_flag && d > 1) //if (d > 1)
222 print_char(')');
224 if(tex_flag) print_str("}");
225 //#endif
227 restore();
230 void
231 print_term(U *p)
233 U* p_sqrt = NULL;
234 int sqrt_factor_number = 0, non_sqrt_factor_number = 0, i = 0;
236 if (car(p) == symbol(MULTIPLY) && any_denominators(p)) {
237 print_a_over_b(p);
238 return;
241 if (car(p) == symbol(MULTIPLY)) {
242 p = cdr(p);
244 // coeff -1?
246 if (isminusone(car(p))) {
247 // print_char('-');
248 p = cdr(p);
251 #if 0
252 #ifdef TEX
253 p_sqrt = p; //temp buffer
254 sqrt_factor_number = 0;
255 non_sqrt_factor_number = 0;
257 //Get the number of factor which are square root of something
258 while(iscons(p_sqrt) || isnum(p_sqrt)){
259 if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) sqrt_factor_number++;
260 else non_sqrt_factor_number++;
261 p_sqrt = cdr(p_sqrt);
264 p_sqrt = p;
266 if(sqrt_factor_number > 1) {
267 //First, print the factor wich are not square root of something
268 if(non_sqrt_factor_number) {
269 //Print the first wich is not square root of something
270 while (iscons(p_sqrt) || isnum(p_sqrt)) {
271 if(!(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2))) {
272 print_factor(cdar(p_sqrt));
273 break;
275 else p_sqrt = cdr(p_sqrt);
278 p_sqrt = cdr(p_sqrt);
279 i++;
280 //Print the other ones
281 while ((iscons(p_sqrt) || isnum(p_sqrt)) && i < non_sqrt_factor_number) {
282 if(!(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2))){
283 print_multiply_sign();
284 print_factor(cdar(p_sqrt));
285 p_sqrt = cdr(p_sqrt);
286 i++;
291 p_sqrt = p;
292 i = 0;
294 print_str("\\sqrt{");
296 while (iscons(p_sqrt) || isnum(p_sqrt)) {
297 if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) {
298 print_expr(cadar(p_sqrt));
299 i++;
300 break;
302 p_sqrt = cdr(p_sqrt);
305 p_sqrt = cdr(p_sqrt);
307 while ((iscons(p_sqrt) || isnum(p_sqrt)) && i < sqrt_factor_number) {
308 if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) {
309 print_multiply_sign();
310 print_expr(cadar(p_sqrt));
311 i++;
312 p_sqrt = cdr(p_sqrt);
316 print_str("}");
318 return;
320 #endif // TeX
321 #endif // 0
323 print_factor(car(p));
324 p = cdr(p);
325 while (iscons(p)) {
326 print_multiply_sign();
327 print_factor(car(p));
328 p = cdr(p);
330 } else
331 print_factor(p);
334 // prints stuff after the divide symbol "/"
336 // d is the number of denominators
338 #define BASE p1
339 #define EXPO p2
341 void
342 print_denom(U *p, int d)
344 save();
346 BASE = cadr(p);
347 EXPO = caddr(p);
349 // i.e. 1 / (2^(1/3))
351 if (d == 1 && !isminusone(EXPO))
352 print_char('(');
354 #ifdef TEX
355 if (tex_flag && equalq(EXPO, -1, 2)) {
356 print_str("\\sqrt{");
357 print_expr(BASE);
358 print_str("}");
359 restore();
360 return;
362 #endif
364 if (isfraction(BASE) || car(BASE) == symbol(ADD) || car(BASE) == symbol(MULTIPLY) || car(BASE) == symbol(POWER) || lessp(BASE, zero)) {
365 print_char('(');
366 print_expr(BASE);
367 print_char(')');
368 } else
369 print_expr(BASE);
371 if (isminusone(EXPO)) {
372 restore();
373 return;
376 if (test_flag == 0)
377 print_str(power_str);
378 else
379 print_char('^');
381 push(EXPO);
382 negate();
383 EXPO = pop();
385 if (isfraction(EXPO) || car(EXPO) == symbol(ADD) || car(EXPO) == symbol(MULTIPLY) || car(EXPO) == symbol(POWER)) {
386 print_char('(');
387 print_expr(EXPO);
388 print_char(')');
389 } else
390 print_expr(EXPO);
392 if (d == 1)
393 print_char(')');
395 restore();
398 void
399 print_factor(U *p)
401 if (isnum(p)) {
402 print_number(p);
403 return;
406 if (isstr(p)) {
407 //print_str("\"");
408 print_str(p->u.str);
409 //print_str("\"");
410 return;
413 if (istensor(p)) {
414 print_tensor(p);
415 return;
418 if (isadd(p) || car(p) == symbol(MULTIPLY)) {
419 print_str("(");
420 print_expr(p);
421 print_str(")");
422 return;
425 if (car(p) == symbol(POWER)) {
427 if (cadr(p) == symbol(E)) {
428 #ifdef ARM9
429 print_str("\235(");
430 #else
431 print_str("e^(");
432 #endif
433 print_expr(caddr(p));
434 print_str(")");
435 return;
438 if (isminusone(caddr(p))) {
439 if (test_flag == 0)
440 if(tex_flag) print_str("\\frac{1}{");
441 else print_str("1 / ");
442 else {
443 print_str("1/");
445 if (iscons(cadr(p))) {
446 print_str("(");
447 print_expr(cadr(p));
448 print_str(")");
449 } else
450 print_expr(cadr(p));
452 if(tex_flag) print_str("}");
453 return;
456 #ifdef TEX
457 if (tex_flag && equalq(caddr(p), 1, 2)) {
458 print_str("\\sqrt{");
459 print_expr(cadr(p));
460 print_str("}");
461 return;
464 if (tex_flag && equalq(caddr(p), -1, 2)) {
465 print_str("\\frac{1}{\\sqrt{");
466 print_expr(cadr(p));
467 //if(caddr)
468 print_str("}}");
469 return;
471 #endif
473 if (isadd(cadr(p)) || caadr(p) == symbol(MULTIPLY) || caadr(p) == symbol(POWER) || isnegativenumber(cadr(p))) {
474 print_str("(");
475 print_expr(cadr(p));
476 print_str(")");
477 } else if (isnum(cadr(p)) && (lessp(cadr(p), zero) || isfraction(cadr(p)))) {
478 print_str("(");
479 print_factor(cadr(p));
480 print_str(")");
481 } else
482 print_factor(cadr(p));
483 if (test_flag == 0)
484 //print_str(" ^ ");
485 print_str(power_str);
486 else
487 print_str("^");
489 int a,b,c;
491 a = iscons(caddr(p));
492 b = isfraction(caddr(p));
493 c = (isnum(caddr(p)) && lessp(caddr(p), zero));
495 if ( a|| b || c) {
496 print_str("(");
497 print_expr(caddr(p));
498 print_str(")");
499 } else
500 print_factor(caddr(p));
502 return;
505 // if (car(p) == _list) {
506 // print_str("{");
507 // p = cdr(p);
508 // if (iscons(p)) {
509 // print_expr(car(p));
510 // p = cdr(p);
511 // }
512 // while (iscons(p)) {
513 // print_str(",");
514 // print_expr(car(p));
515 // p = cdr(p);
516 // }
517 // print_str("}");
518 // return;
519 // }
521 if (car(p) == symbol(INDEX) && issymbol(cadr(p))) {
522 print_index_function(p);
523 return;
526 if (car(p) == symbol(FACTORIAL)) {
527 print_factorial_function(p);
528 return;
531 if (iscons(p)) {
532 //if (car(p) == symbol(FORMAL) && cadr(p)->k == SYM) {
533 // print_str(((struct symbol *) cadr(p))->name);
534 // return;
536 print_factor(car(p));
537 p = cdr(p);
538 print_str("(");
539 if (iscons(p)) {
540 print_expr(car(p));
541 p = cdr(p);
542 while (iscons(p)) {
543 if (test_flag == 0)
544 print_str(",");
545 else
546 print_str(",");
547 print_expr(car(p));
548 p = cdr(p);
551 print_str(")");
552 return;
555 if (p == symbol(DERIVATIVE))
556 print_char('d');
557 else if (p == symbol(E))
558 #ifdef ARM9
559 print_str("\235(1)");
560 #else
561 print_str("e");
562 #endif
563 else if (p == symbol(PI))
564 #ifdef ARM9
565 print_str("\233");
566 #else
567 Console_Output((const unsigned char *)"pi");
568 #endif
569 else
570 print_str(get_printname(p));
573 void
574 print_index_function(U *p)
576 p = cdr(p);
577 if (caar(p) == symbol(ADD) || caar(p) == symbol(MULTIPLY) || caar(p) == symbol(POWER) || caar(p) == symbol(FACTORIAL))
578 print_subexpr(car(p));
579 else
580 print_expr(car(p));
581 print_char('[');
582 p = cdr(p);
583 if (iscons(p)) {
584 print_expr(car(p));
585 p = cdr(p);
586 while(iscons(p)) {
587 print_char(',');
588 print_expr(car(p));
589 p = cdr(p);
592 print_char(']');
595 void
596 print_factorial_function(U *p)
598 p = cadr(p);
599 if (car(p) == symbol(ADD) || car(p) == symbol(MULTIPLY) || car(p) == symbol(POWER) || car(p) == symbol(FACTORIAL))
600 print_subexpr(p);
601 else
602 print_expr(p);
603 print_char('!');
606 void
607 print_tensor(U *p)
609 int k = 0;
610 print_tensor_inner(p, 0, &k);
613 void
614 print_tensor_inner(U *p, int j, int *k)
616 int i;
617 print_str("(");
618 for (i = 0; i < p->u.tensor->dim[j]; i++) {
619 if (j + 1 == p->u.tensor->ndim) {
620 print_expr(p->u.tensor->elem[*k]);
621 *k = *k + 1;
622 } else
623 print_tensor_inner(p, j + 1, k);
624 if (i + 1 < p->u.tensor->dim[j]) {
625 if (test_flag == 0)
626 print_str(",");
627 else
628 print_str(",");
631 print_str(")");
634 void
635 print_str(char *s)
637 while (*s)
638 print_char(*s++);
641 void
642 print_char(int c)
644 last_char = c;
645 char_count++;
646 // if (display_flag == 1)
647 // displaychar(c);
648 // else
649 printchar(c);
652 void
653 print_function_definition(U *p)
655 print_str(get_printname(p));
656 print_arg_list(cadr(get_binding(p)));
657 print_str("=");
658 print_expr(caddr(get_binding(p)));
661 void
662 print_arg_list(U *p)
664 print_str("(");
665 if (iscons(p)) {
666 print_str(get_printname(car(p)));
667 p = cdr(p);
668 while (iscons(p)) {
669 print_str(",");
670 print_str(get_printname(car(p)));
671 p = cdr(p);
674 print_str(")");
677 void
678 print_lisp(U *p)
680 print1(p);
683 void
684 print1(U *p)
686 switch (p->k) {
687 case CONS:
688 print_str("(");
689 print1(car(p));
690 p = cdr(p);
691 while (iscons(p)) {
692 print_str(" ");
693 print1(car(p));
694 p = cdr(p);
696 if (p != symbol(NIL)) {
697 print_str(" . ");
698 print1(p);
700 print_str(")");
701 break;
702 case STR:
703 //print_str("\"");
704 print_str(p->u.str);
705 //print_str("\"");
706 break;
707 case NUM:
708 case DOUBLE:
709 print_number(p);
710 break;
711 case SYM:
712 print_str(get_printname(p));
713 break;
714 default:
715 print_str("<tensor>");
716 break;
720 void
721 print_multiply_sign(void)
723 if (test_flag == 0)
724 Console_Output("*");
725 else
726 Console_Output(" ");
730 is_denominator(U *p)
732 if (car(p) == symbol(POWER) && cadr(p) != symbol(E) && isnegativeterm(caddr(p)))
733 return 1;
734 else
735 return 0;
738 // don't consider the leading fraction
740 // we want 2/3*a*b*c instead of 2*a*b*c/3
743 any_denominators(U *p)
745 U *q;
746 p = cdr(p);
747 // if (isfraction(car(p)))
748 // return 1;
749 while (iscons(p)) {
750 q = car(p);
751 if (is_denominator(q))
752 return 1;
753 p = cdr(p);
755 return 0;