// tty style printing #include "stdafx.h" #include "defs.h" #include "console.h" #include "tex/TeX.h" #define TEX 1 #define MAX_TEX_WIDTH 110 #define MAX_TEX_HEIGHT 50 //char* get_tex_flag_address(); int tex_flag = 1; int out_index, out_length; char *out_str; static int char_count, last_char; char *power_str = "^"; extern "C"{ int* get_tex_flag_address() { return &tex_flag; } } void print(U *p) { print_expr(p); } void printline(U *p) { int old_tex_flag = tex_flag; #ifdef TEX int width, height, baseline; char* edit_line = (char*)Console_GetEditLine(); //tex_flag = 1; #endif print_expr(p); #ifdef TEX TeX_sizeComplex(edit_line, &width, &height, &baseline); /*if(width > MAX_TEX_WIDTH || height > MAX_TEX_HEIGHT) { tex_flag = 0; Console_Clear_EditLine(); print_expr(p); }*/ tex_flag = old_tex_flag; #endif } void print_subexpr(U *p) { print_char('('); print_expr(p); print_char(')'); } void print_expr(U *p) { if (isadd(p)) { p = cdr(p); if (sign_of_term(car(p)) == '-') print_str("-"); print_term(car(p)); p = cdr(p); while (iscons(p)) { if (sign_of_term(car(p)) == '+') if (test_flag == 0) print_str(" + "); else print_str("+"); else if (test_flag == 0) print_str(" - "); else print_str("-"); print_term(car(p)); p = cdr(p); } } else { if (sign_of_term(p) == '-') print_str("-"); print_term(p); } } int sign_of_term(U *p) { if (car(p) == symbol(MULTIPLY) && isnum(cadr(p)) && lessp(cadr(p), zero)) return '-'; else if (isnum(p) && lessp(p, zero)) return '-'; else return '+'; } #define A p3 #define B p4 void print_a_over_b(U *p) { int flag, n, d; U *p1, *p2; save(); // count numerators and denominators n = 0; d = 0; p1 = cdr(p); p2 = car(p1); if (isrational(p2)) { push(p2); mp_numerator(); absval(); A = pop(); push(p2); mp_denominator(); B = pop(); if (!isplusone(A)) n++; if (!isplusone(B)) d++; p1 = cdr(p1); } else { A = one; B = one; } while (iscons(p1)) { p2 = car(p1); if (is_denominator(p2)) d++; else n++; p1 = cdr(p1); } //#ifdef TEX if(tex_flag) print_str("\\frac{"); //#endif if (n == 0) print_char('1'); else { flag = 0; p1 = cdr(p); if (isrational(car(p1))) p1 = cdr(p1); if (!isplusone(A)) { print_factor(A); flag = 1; } while (iscons(p1)) { p2 = car(p1); if (is_denominator(p2)) ; else { if (flag) print_multiply_sign(); print_factor(p2); flag = 1; } p1 = cdr(p1); } } //#ifdef TEX if(tex_flag) print_str("}{"); else { //#else if (test_flag == 0) print_str(" / "); else print_str("/"); if (d > 1) print_char('('); } //#endif flag = 0; p1 = cdr(p); if (isrational(car(p1))) p1 = cdr(p1); if (!isplusone(B)) { print_factor(B); flag = 1; } while (iscons(p1)) { p2 = car(p1); if (is_denominator(p2)) { if (flag) print_multiply_sign(); print_denom(p2, d); flag = 1; } p1 = cdr(p1); } //#ifdef TEX //#else if(!tex_flag && d > 1) //if (d > 1) print_char(')'); if(tex_flag) print_str("}"); //#endif restore(); } void print_term(U *p) { U* p_sqrt = NULL; int sqrt_factor_number = 0, non_sqrt_factor_number = 0, i = 0; if (car(p) == symbol(MULTIPLY) && any_denominators(p)) { print_a_over_b(p); return; } if (car(p) == symbol(MULTIPLY)) { p = cdr(p); // coeff -1? if (isminusone(car(p))) { // print_char('-'); p = cdr(p); } #if 0 #ifdef TEX p_sqrt = p; //temp buffer sqrt_factor_number = 0; non_sqrt_factor_number = 0; //Get the number of factor which are square root of something while(iscons(p_sqrt) || isnum(p_sqrt)){ if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) sqrt_factor_number++; else non_sqrt_factor_number++; p_sqrt = cdr(p_sqrt); } p_sqrt = p; if(sqrt_factor_number > 1) { //First, print the factor wich are not square root of something if(non_sqrt_factor_number) { //Print the first wich is not square root of something while (iscons(p_sqrt) || isnum(p_sqrt)) { if(!(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2))) { print_factor(cdar(p_sqrt)); break; } else p_sqrt = cdr(p_sqrt); } p_sqrt = cdr(p_sqrt); i++; //Print the other ones while ((iscons(p_sqrt) || isnum(p_sqrt)) && i < non_sqrt_factor_number) { if(!(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2))){ print_multiply_sign(); print_factor(cdar(p_sqrt)); p_sqrt = cdr(p_sqrt); i++; } } } p_sqrt = p; i = 0; print_str("\\sqrt{"); while (iscons(p_sqrt) || isnum(p_sqrt)) { if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) { print_expr(cadar(p_sqrt)); i++; break; } p_sqrt = cdr(p_sqrt); } p_sqrt = cdr(p_sqrt); while ((iscons(p_sqrt) || isnum(p_sqrt)) && i < sqrt_factor_number) { if(caar(p_sqrt) == symbol(POWER) && equalq(caddar(p), 1, 2)) { print_multiply_sign(); print_expr(cadar(p_sqrt)); i++; p_sqrt = cdr(p_sqrt); } } print_str("}"); return; } #endif // TeX #endif // 0 print_factor(car(p)); p = cdr(p); while (iscons(p)) { print_multiply_sign(); print_factor(car(p)); p = cdr(p); } } else print_factor(p); } // prints stuff after the divide symbol "/" // d is the number of denominators #define BASE p1 #define EXPO p2 void print_denom(U *p, int d) { save(); BASE = cadr(p); EXPO = caddr(p); // i.e. 1 / (2^(1/3)) if (d == 1 && !isminusone(EXPO)) print_char('('); #ifdef TEX if (tex_flag && equalq(EXPO, -1, 2)) { print_str("\\sqrt{"); print_expr(BASE); print_str("}"); restore(); return; } #endif if (isfraction(BASE) || car(BASE) == symbol(ADD) || car(BASE) == symbol(MULTIPLY) || car(BASE) == symbol(POWER) || lessp(BASE, zero)) { print_char('('); print_expr(BASE); print_char(')'); } else print_expr(BASE); if (isminusone(EXPO)) { restore(); return; } if (test_flag == 0) print_str(power_str); else print_char('^'); push(EXPO); negate(); EXPO = pop(); if (isfraction(EXPO) || car(EXPO) == symbol(ADD) || car(EXPO) == symbol(MULTIPLY) || car(EXPO) == symbol(POWER)) { print_char('('); print_expr(EXPO); print_char(')'); } else print_expr(EXPO); if (d == 1) print_char(')'); restore(); } void print_factor(U *p) { if (isnum(p)) { print_number(p); return; } if (isstr(p)) { //print_str("\""); print_str(p->u.str); //print_str("\""); return; } if (istensor(p)) { print_tensor(p); return; } if (isadd(p) || car(p) == symbol(MULTIPLY)) { print_str("("); print_expr(p); print_str(")"); return; } if (car(p) == symbol(POWER)) { if (cadr(p) == symbol(E)) { #ifdef ARM9 print_str("\235("); #else print_str("e^("); #endif print_expr(caddr(p)); print_str(")"); return; } if (isminusone(caddr(p))) { if (test_flag == 0) if(tex_flag) print_str("\\frac{1}{"); else print_str("1 / "); else { print_str("1/"); } if (iscons(cadr(p))) { print_str("("); print_expr(cadr(p)); print_str(")"); } else print_expr(cadr(p)); if(tex_flag) print_str("}"); return; } #ifdef TEX if (tex_flag && equalq(caddr(p), 1, 2)) { print_str("\\sqrt{"); print_expr(cadr(p)); print_str("}"); return; } if (tex_flag && equalq(caddr(p), -1, 2)) { print_str("\\frac{1}{\\sqrt{"); print_expr(cadr(p)); //if(caddr) print_str("}}"); return; } #endif if (isadd(cadr(p)) || caadr(p) == symbol(MULTIPLY) || caadr(p) == symbol(POWER) || isnegativenumber(cadr(p))) { print_str("("); print_expr(cadr(p)); print_str(")"); } else if (isnum(cadr(p)) && (lessp(cadr(p), zero) || isfraction(cadr(p)))) { print_str("("); print_factor(cadr(p)); print_str(")"); } else print_factor(cadr(p)); if (test_flag == 0) //print_str(" ^ "); print_str(power_str); else print_str("^"); { int a,b,c; a = iscons(caddr(p)); b = isfraction(caddr(p)); c = (isnum(caddr(p)) && lessp(caddr(p), zero)); if ( a|| b || c) { print_str("("); print_expr(caddr(p)); print_str(")"); } else print_factor(caddr(p)); } return; } // if (car(p) == _list) { // print_str("{"); // p = cdr(p); // if (iscons(p)) { // print_expr(car(p)); // p = cdr(p); // } // while (iscons(p)) { // print_str(","); // print_expr(car(p)); // p = cdr(p); // } // print_str("}"); // return; // } if (car(p) == symbol(INDEX) && issymbol(cadr(p))) { print_index_function(p); return; } if (car(p) == symbol(FACTORIAL)) { print_factorial_function(p); return; } if (iscons(p)) { //if (car(p) == symbol(FORMAL) && cadr(p)->k == SYM) { // print_str(((struct symbol *) cadr(p))->name); // return; //} print_factor(car(p)); p = cdr(p); print_str("("); if (iscons(p)) { print_expr(car(p)); p = cdr(p); while (iscons(p)) { if (test_flag == 0) print_str(","); else print_str(","); print_expr(car(p)); p = cdr(p); } } print_str(")"); return; } if (p == symbol(DERIVATIVE)) print_char('d'); else if (p == symbol(E)) #ifdef ARM9 print_str("\235(1)"); #else print_str("e"); #endif else if (p == symbol(PI)) #ifdef ARM9 print_str("\233"); #else Console_Output((const unsigned char *)"pi"); #endif else print_str(get_printname(p)); } void print_index_function(U *p) { p = cdr(p); if (caar(p) == symbol(ADD) || caar(p) == symbol(MULTIPLY) || caar(p) == symbol(POWER) || caar(p) == symbol(FACTORIAL)) print_subexpr(car(p)); else print_expr(car(p)); print_char('['); p = cdr(p); if (iscons(p)) { print_expr(car(p)); p = cdr(p); while(iscons(p)) { print_char(','); print_expr(car(p)); p = cdr(p); } } print_char(']'); } void print_factorial_function(U *p) { p = cadr(p); if (car(p) == symbol(ADD) || car(p) == symbol(MULTIPLY) || car(p) == symbol(POWER) || car(p) == symbol(FACTORIAL)) print_subexpr(p); else print_expr(p); print_char('!'); } void print_tensor(U *p) { int k = 0; print_tensor_inner(p, 0, &k); } void print_tensor_inner(U *p, int j, int *k) { int i; print_str("("); for (i = 0; i < p->u.tensor->dim[j]; i++) { if (j + 1 == p->u.tensor->ndim) { print_expr(p->u.tensor->elem[*k]); *k = *k + 1; } else print_tensor_inner(p, j + 1, k); if (i + 1 < p->u.tensor->dim[j]) { if (test_flag == 0) print_str(","); else print_str(","); } } print_str(")"); } void print_str(char *s) { while (*s) print_char(*s++); } void print_char(int c) { last_char = c; char_count++; // if (display_flag == 1) // displaychar(c); // else printchar(c); } void print_function_definition(U *p) { print_str(get_printname(p)); print_arg_list(cadr(get_binding(p))); print_str("="); print_expr(caddr(get_binding(p))); } void print_arg_list(U *p) { print_str("("); if (iscons(p)) { print_str(get_printname(car(p))); p = cdr(p); while (iscons(p)) { print_str(","); print_str(get_printname(car(p))); p = cdr(p); } } print_str(")"); } void print_lisp(U *p) { print1(p); } void print1(U *p) { switch (p->k) { case CONS: print_str("("); print1(car(p)); p = cdr(p); while (iscons(p)) { print_str(" "); print1(car(p)); p = cdr(p); } if (p != symbol(NIL)) { print_str(" . "); print1(p); } print_str(")"); break; case STR: //print_str("\""); print_str(p->u.str); //print_str("\""); break; case NUM: case DOUBLE: print_number(p); break; case SYM: print_str(get_printname(p)); break; default: print_str(""); break; } } void print_multiply_sign(void) { if (test_flag == 0) Console_Output("*"); else Console_Output(" "); } int is_denominator(U *p) { if (car(p) == symbol(POWER) && cadr(p) != symbol(E) && isnegativeterm(caddr(p))) return 1; else return 0; } // don't consider the leading fraction // we want 2/3*a*b*c instead of 2*a*b*c/3 int any_denominators(U *p) { U *q; p = cdr(p); // if (isfraction(car(p))) // return 1; while (iscons(p)) { q = car(p); if (is_denominator(q)) return 1; p = cdr(p); } return 0; }