print.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. // tty style printing
  2. #include "stdafx.h"
  3. #include "defs.h"
  4. #include "console.h"
  5. #include "tex/TeX.h"
  6. #define TEX 1
  7. #define MAX_TEX_WIDTH 110
  8. #define MAX_TEX_HEIGHT 50
  9. //char* get_tex_flag_address();
  10. int tex_flag = 1;
  11. int out_index, out_length;
  12. char *out_str;
  13. static int char_count, last_char;
  14. char *power_str = "^";
  15. extern "C"{
  16. int* get_tex_flag_address()
  17. {
  18. return &tex_flag;
  19. }
  20. }
  21. void
  22. print(U *p)
  23. {
  24. print_expr(p);
  25. }
  26. void
  27. printline(U *p)
  28. {
  29. int old_tex_flag = tex_flag;
  30. #ifdef TEX
  31. int width, height, baseline;
  32. char* edit_line = (char*)Console_GetEditLine();
  33. //tex_flag = 1;
  34. #endif
  35. print_expr(p);
  36. #ifdef TEX
  37. TeX_sizeComplex(edit_line, &width, &height, &baseline);
  38. /*if(width > MAX_TEX_WIDTH || height > MAX_TEX_HEIGHT) {
  39. tex_flag = 0;
  40. Console_Clear_EditLine();
  41. print_expr(p);
  42. }*/
  43. tex_flag = old_tex_flag;
  44. #endif
  45. }
  46. void
  47. print_subexpr(U *p)
  48. {
  49. print_char('(');
  50. print_expr(p);
  51. print_char(')');
  52. }
  53. void
  54. print_expr(U *p)
  55. {
  56. if (isadd(p)) {
  57. p = cdr(p);
  58. if (sign_of_term(car(p)) == '-')
  59. print_str("-");
  60. print_term(car(p));
  61. p = cdr(p);
  62. while (iscons(p)) {
  63. if (sign_of_term(car(p)) == '+')
  64. if (test_flag == 0)
  65. print_str(" + ");
  66. else
  67. print_str("+");
  68. else
  69. if (test_flag == 0)
  70. print_str(" - ");
  71. else
  72. print_str("-");
  73. print_term(car(p));
  74. p = cdr(p);
  75. }
  76. } else {
  77. if (sign_of_term(p) == '-')
  78. print_str("-");
  79. print_term(p);
  80. }
  81. }
  82. int
  83. sign_of_term(U *p)
  84. {
  85. if (car(p) == symbol(MULTIPLY) && isnum(cadr(p)) && lessp(cadr(p), zero))
  86. return '-';
  87. else if (isnum(p) && lessp(p, zero))
  88. return '-';
  89. else
  90. return '+';
  91. }
  92. #define A p3
  93. #define B p4
  94. void
  95. print_a_over_b(U *p)
  96. {
  97. int flag, n, d;
  98. U *p1, *p2;
  99. save();
  100. // count numerators and denominators
  101. n = 0;
  102. d = 0;
  103. p1 = cdr(p);
  104. p2 = car(p1);
  105. if (isrational(p2)) {
  106. push(p2);
  107. mp_numerator();
  108. absval();
  109. A = pop();
  110. push(p2);
  111. mp_denominator();
  112. B = pop();
  113. if (!isplusone(A))
  114. n++;
  115. if (!isplusone(B))
  116. d++;
  117. p1 = cdr(p1);
  118. } else {
  119. A = one;
  120. B = one;
  121. }
  122. while (iscons(p1)) {
  123. p2 = car(p1);
  124. if (is_denominator(p2))
  125. d++;
  126. else
  127. n++;
  128. p1 = cdr(p1);
  129. }
  130. //#ifdef TEX
  131. if(tex_flag) print_str("\\frac{");
  132. //#endif
  133. if (n == 0)
  134. print_char('1');
  135. else {
  136. flag = 0;
  137. p1 = cdr(p);
  138. if (isrational(car(p1)))
  139. p1 = cdr(p1);
  140. if (!isplusone(A)) {
  141. print_factor(A);
  142. flag = 1;
  143. }
  144. while (iscons(p1)) {
  145. p2 = car(p1);
  146. if (is_denominator(p2))
  147. ;
  148. else {
  149. if (flag)
  150. print_multiply_sign();
  151. print_factor(p2);
  152. flag = 1;
  153. }
  154. p1 = cdr(p1);
  155. }
  156. }
  157. //#ifdef TEX
  158. if(tex_flag) print_str("}{");
  159. else {
  160. //#else
  161. if (test_flag == 0)
  162. print_str(" / ");
  163. else
  164. print_str("/");
  165. if (d > 1)
  166. print_char('(');
  167. }
  168. //#endif
  169. flag = 0;
  170. p1 = cdr(p);
  171. if (isrational(car(p1)))
  172. p1 = cdr(p1);
  173. if (!isplusone(B)) {
  174. print_factor(B);
  175. flag = 1;
  176. }
  177. while (iscons(p1)) {
  178. p2 = car(p1);
  179. if (is_denominator(p2)) {
  180. if (flag)
  181. print_multiply_sign();
  182. print_denom(p2, d);
  183. flag = 1;
  184. }
  185. p1 = cdr(p1);
  186. }
  187. //#ifdef TEX
  188. //#else
  189. if(!tex_flag && d > 1) //if (d > 1)
  190. print_char(')');
  191. if(tex_flag) print_str("}");
  192. //#endif
  193. restore();
  194. }
  195. void
  196. print_term(U *p)
  197. {
  198. U* p_sqrt = NULL;
  199. int sqrt_factor_number = 0, non_sqrt_factor_number = 0, i = 0;
  200. if (car(p) == symbol(MULTIPLY) && any_denominators(p)) {
  201. print_a_over_b(p);
  202. return;
  203. }
  204. if (car(p) == symbol(MULTIPLY)) {
  205. p = cdr(p);
  206. // coeff -1?
  207. if (isminusone(car(p))) {
  208. // print_char('-');
  209. p = cdr(p);
  210. }
  211. #if 0
  212. #ifdef TEX
  213. p_sqrt = p; //temp buffer
  214. sqrt_factor_number = 0;
  215. non_sqrt_factor_number = 0;
  216. //Get the number of factor which are square root of something
  217. while(iscons(p_sqrt) || isnum(p_sqrt)){
  218. if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) sqrt_factor_number++;
  219. else non_sqrt_factor_number++;
  220. p_sqrt = cdr(p_sqrt);
  221. }
  222. p_sqrt = p;
  223. if(sqrt_factor_number > 1) {
  224. //First, print the factor wich are not square root of something
  225. if(non_sqrt_factor_number) {
  226. //Print the first wich is not square root of something
  227. while (iscons(p_sqrt) || isnum(p_sqrt)) {
  228. if(!(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2))) {
  229. print_factor(cdar(p_sqrt));
  230. break;
  231. }
  232. else p_sqrt = cdr(p_sqrt);
  233. }
  234. p_sqrt = cdr(p_sqrt);
  235. i++;
  236. //Print the other ones
  237. while ((iscons(p_sqrt) || isnum(p_sqrt)) && i < non_sqrt_factor_number) {
  238. if(!(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2))){
  239. print_multiply_sign();
  240. print_factor(cdar(p_sqrt));
  241. p_sqrt = cdr(p_sqrt);
  242. i++;
  243. }
  244. }
  245. }
  246. p_sqrt = p;
  247. i = 0;
  248. print_str("\\sqrt{");
  249. while (iscons(p_sqrt) || isnum(p_sqrt)) {
  250. if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) {
  251. print_expr(cadar(p_sqrt));
  252. i++;
  253. break;
  254. }
  255. p_sqrt = cdr(p_sqrt);
  256. }
  257. p_sqrt = cdr(p_sqrt);
  258. while ((iscons(p_sqrt) || isnum(p_sqrt)) && i < sqrt_factor_number) {
  259. if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) {
  260. print_multiply_sign();
  261. print_expr(cadar(p_sqrt));
  262. i++;
  263. p_sqrt = cdr(p_sqrt);
  264. }
  265. }
  266. print_str("}");
  267. return;
  268. }
  269. #endif // TeX
  270. #endif // 0
  271. print_factor(car(p));
  272. p = cdr(p);
  273. while (iscons(p)) {
  274. print_multiply_sign();
  275. print_factor(car(p));
  276. p = cdr(p);
  277. }
  278. } else
  279. print_factor(p);
  280. }
  281. // prints stuff after the divide symbol "/"
  282. // d is the number of denominators
  283. #define BASE p1
  284. #define EXPO p2
  285. void
  286. print_denom(U *p, int d)
  287. {
  288. save();
  289. BASE = cadr(p);
  290. EXPO = caddr(p);
  291. // i.e. 1 / (2^(1/3))
  292. if (d == 1 && !isminusone(EXPO))
  293. print_char('(');
  294. #ifdef TEX
  295. if (tex_flag && equalq(EXPO, -1, 2)) {
  296. print_str("\\sqrt{");
  297. print_expr(BASE);
  298. print_str("}");
  299. restore();
  300. return;
  301. }
  302. #endif
  303. if (isfraction(BASE) || car(BASE) == symbol(ADD) || car(BASE) == symbol(MULTIPLY) || car(BASE) == symbol(POWER) || lessp(BASE, zero)) {
  304. print_char('(');
  305. print_expr(BASE);
  306. print_char(')');
  307. } else
  308. print_expr(BASE);
  309. if (isminusone(EXPO)) {
  310. restore();
  311. return;
  312. }
  313. if (test_flag == 0)
  314. print_str(power_str);
  315. else
  316. print_char('^');
  317. push(EXPO);
  318. negate();
  319. EXPO = pop();
  320. if (isfraction(EXPO) || car(EXPO) == symbol(ADD) || car(EXPO) == symbol(MULTIPLY) || car(EXPO) == symbol(POWER)) {
  321. print_char('(');
  322. print_expr(EXPO);
  323. print_char(')');
  324. } else
  325. print_expr(EXPO);
  326. if (d == 1)
  327. print_char(')');
  328. restore();
  329. }
  330. void
  331. print_factor(U *p)
  332. {
  333. if (isnum(p)) {
  334. print_number(p);
  335. return;
  336. }
  337. if (isstr(p)) {
  338. //print_str("\"");
  339. print_str(p->u.str);
  340. //print_str("\"");
  341. return;
  342. }
  343. if (istensor(p)) {
  344. print_tensor(p);
  345. return;
  346. }
  347. if (isadd(p) || car(p) == symbol(MULTIPLY)) {
  348. print_str("(");
  349. print_expr(p);
  350. print_str(")");
  351. return;
  352. }
  353. if (car(p) == symbol(POWER)) {
  354. if (cadr(p) == symbol(E)) {
  355. #ifdef ARM9
  356. print_str("\235(");
  357. #else
  358. print_str("e^(");
  359. #endif
  360. print_expr(caddr(p));
  361. print_str(")");
  362. return;
  363. }
  364. if (isminusone(caddr(p))) {
  365. if (test_flag == 0)
  366. if(tex_flag) print_str("\\frac{1}{");
  367. else print_str("1 / ");
  368. else {
  369. print_str("1/");
  370. }
  371. if (iscons(cadr(p))) {
  372. print_str("(");
  373. print_expr(cadr(p));
  374. print_str(")");
  375. } else
  376. print_expr(cadr(p));
  377. if(tex_flag) print_str("}");
  378. return;
  379. }
  380. #ifdef TEX
  381. if (tex_flag && equalq(caddr(p), 1, 2)) {
  382. print_str("\\sqrt{");
  383. print_expr(cadr(p));
  384. print_str("}");
  385. return;
  386. }
  387. if (tex_flag && equalq(caddr(p), -1, 2)) {
  388. print_str("\\frac{1}{\\sqrt{");
  389. print_expr(cadr(p));
  390. //if(caddr)
  391. print_str("}}");
  392. return;
  393. }
  394. #endif
  395. if (isadd(cadr(p)) || caadr(p) == symbol(MULTIPLY) || caadr(p) == symbol(POWER) || isnegativenumber(cadr(p))) {
  396. print_str("(");
  397. print_expr(cadr(p));
  398. print_str(")");
  399. } else if (isnum(cadr(p)) && (lessp(cadr(p), zero) || isfraction(cadr(p)))) {
  400. print_str("(");
  401. print_factor(cadr(p));
  402. print_str(")");
  403. } else
  404. print_factor(cadr(p));
  405. if (test_flag == 0)
  406. //print_str(" ^ ");
  407. print_str(power_str);
  408. else
  409. print_str("^");
  410. {
  411. int a,b,c;
  412. a = iscons(caddr(p));
  413. b = isfraction(caddr(p));
  414. c = (isnum(caddr(p)) && lessp(caddr(p), zero));
  415. if ( a|| b || c) {
  416. print_str("(");
  417. print_expr(caddr(p));
  418. print_str(")");
  419. } else
  420. print_factor(caddr(p));
  421. }
  422. return;
  423. }
  424. // if (car(p) == _list) {
  425. // print_str("{");
  426. // p = cdr(p);
  427. // if (iscons(p)) {
  428. // print_expr(car(p));
  429. // p = cdr(p);
  430. // }
  431. // while (iscons(p)) {
  432. // print_str(",");
  433. // print_expr(car(p));
  434. // p = cdr(p);
  435. // }
  436. // print_str("}");
  437. // return;
  438. // }
  439. if (car(p) == symbol(INDEX) && issymbol(cadr(p))) {
  440. print_index_function(p);
  441. return;
  442. }
  443. if (car(p) == symbol(FACTORIAL)) {
  444. print_factorial_function(p);
  445. return;
  446. }
  447. if (iscons(p)) {
  448. //if (car(p) == symbol(FORMAL) && cadr(p)->k == SYM) {
  449. // print_str(((struct symbol *) cadr(p))->name);
  450. // return;
  451. //}
  452. print_factor(car(p));
  453. p = cdr(p);
  454. print_str("(");
  455. if (iscons(p)) {
  456. print_expr(car(p));
  457. p = cdr(p);
  458. while (iscons(p)) {
  459. if (test_flag == 0)
  460. print_str(",");
  461. else
  462. print_str(",");
  463. print_expr(car(p));
  464. p = cdr(p);
  465. }
  466. }
  467. print_str(")");
  468. return;
  469. }
  470. if (p == symbol(DERIVATIVE))
  471. print_char('d');
  472. else if (p == symbol(E))
  473. #ifdef ARM9
  474. print_str("\235(1)");
  475. #else
  476. print_str("e");
  477. #endif
  478. else if (p == symbol(PI))
  479. #ifdef ARM9
  480. print_str("\233");
  481. #else
  482. Console_Output((const unsigned char *)"pi");
  483. #endif
  484. else
  485. print_str(get_printname(p));
  486. }
  487. void
  488. print_index_function(U *p)
  489. {
  490. p = cdr(p);
  491. if (caar(p) == symbol(ADD) || caar(p) == symbol(MULTIPLY) || caar(p) == symbol(POWER) || caar(p) == symbol(FACTORIAL))
  492. print_subexpr(car(p));
  493. else
  494. print_expr(car(p));
  495. print_char('[');
  496. p = cdr(p);
  497. if (iscons(p)) {
  498. print_expr(car(p));
  499. p = cdr(p);
  500. while(iscons(p)) {
  501. print_char(',');
  502. print_expr(car(p));
  503. p = cdr(p);
  504. }
  505. }
  506. print_char(']');
  507. }
  508. void
  509. print_factorial_function(U *p)
  510. {
  511. p = cadr(p);
  512. if (car(p) == symbol(ADD) || car(p) == symbol(MULTIPLY) || car(p) == symbol(POWER) || car(p) == symbol(FACTORIAL))
  513. print_subexpr(p);
  514. else
  515. print_expr(p);
  516. print_char('!');
  517. }
  518. void
  519. print_tensor(U *p)
  520. {
  521. int k = 0;
  522. print_tensor_inner(p, 0, &k);
  523. }
  524. void
  525. print_tensor_inner(U *p, int j, int *k)
  526. {
  527. int i;
  528. print_str("(");
  529. for (i = 0; i < p->u.tensor->dim[j]; i++) {
  530. if (j + 1 == p->u.tensor->ndim) {
  531. print_expr(p->u.tensor->elem[*k]);
  532. *k = *k + 1;
  533. } else
  534. print_tensor_inner(p, j + 1, k);
  535. if (i + 1 < p->u.tensor->dim[j]) {
  536. if (test_flag == 0)
  537. print_str(",");
  538. else
  539. print_str(",");
  540. }
  541. }
  542. print_str(")");
  543. }
  544. void
  545. print_str(char *s)
  546. {
  547. while (*s)
  548. print_char(*s++);
  549. }
  550. void
  551. print_char(int c)
  552. {
  553. last_char = c;
  554. char_count++;
  555. // if (display_flag == 1)
  556. // displaychar(c);
  557. // else
  558. printchar(c);
  559. }
  560. void
  561. print_function_definition(U *p)
  562. {
  563. print_str(get_printname(p));
  564. print_arg_list(cadr(get_binding(p)));
  565. print_str("=");
  566. print_expr(caddr(get_binding(p)));
  567. }
  568. void
  569. print_arg_list(U *p)
  570. {
  571. print_str("(");
  572. if (iscons(p)) {
  573. print_str(get_printname(car(p)));
  574. p = cdr(p);
  575. while (iscons(p)) {
  576. print_str(",");
  577. print_str(get_printname(car(p)));
  578. p = cdr(p);
  579. }
  580. }
  581. print_str(")");
  582. }
  583. void
  584. print_lisp(U *p)
  585. {
  586. print1(p);
  587. }
  588. void
  589. print1(U *p)
  590. {
  591. switch (p->k) {
  592. case CONS:
  593. print_str("(");
  594. print1(car(p));
  595. p = cdr(p);
  596. while (iscons(p)) {
  597. print_str(" ");
  598. print1(car(p));
  599. p = cdr(p);
  600. }
  601. if (p != symbol(NIL)) {
  602. print_str(" . ");
  603. print1(p);
  604. }
  605. print_str(")");
  606. break;
  607. case STR:
  608. //print_str("\"");
  609. print_str(p->u.str);
  610. //print_str("\"");
  611. break;
  612. case NUM:
  613. case DOUBLE:
  614. print_number(p);
  615. break;
  616. case SYM:
  617. print_str(get_printname(p));
  618. break;
  619. default:
  620. print_str("<tensor>");
  621. break;
  622. }
  623. }
  624. void
  625. print_multiply_sign(void)
  626. {
  627. if (test_flag == 0)
  628. Console_Output("*");
  629. else
  630. Console_Output(" ");
  631. }
  632. int
  633. is_denominator(U *p)
  634. {
  635. if (car(p) == symbol(POWER) && cadr(p) != symbol(E) && isnegativeterm(caddr(p)))
  636. return 1;
  637. else
  638. return 0;
  639. }
  640. // don't consider the leading fraction
  641. // we want 2/3*a*b*c instead of 2*a*b*c/3
  642. int
  643. any_denominators(U *p)
  644. {
  645. U *q;
  646. p = cdr(p);
  647. // if (isfraction(car(p)))
  648. // return 1;
  649. while (iscons(p)) {
  650. q = car(p);
  651. if (is_denominator(q))
  652. return 1;
  653. p = cdr(p);
  654. }
  655. return 0;
  656. }