-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpretty_print.c
149 lines (125 loc) · 3.78 KB
/
pretty_print.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <stdlib.h>
#include <stdio.h>
#include "cmplr.h"
#include "pretty_print.h"
#include "simplify_rne.h"
#include "simplify.h"
#include <math.h>
struct pp_buf * create_pp_buffer()
{
struct pp_buf * buf = calloc(1, sizeof(struct pp_buf));
return buf;
}
void pp_print_char(struct pp_buf * buf, char ch, int x, double y)
{
int line_ind;
struct pp_line * line = NULL;
for (line_ind = 0; line_ind < buf->n_lines; line_ind++) {
if (buf->lines[line_ind].y_pos == y) {
line = &buf->lines[line_ind];
}
}
if (line == NULL) {
if (buf->n_lines == MAXLINE) return;
line = &buf->lines[buf->n_lines];
line->y_pos = y;
buf->n_lines++;
}
line->text[x] = ch;
}
int line_pos_cmpr(const void * a, const void *b)
{
const struct pp_line * A = (struct pp_line *) a;
const struct pp_line * B = (struct pp_line *) b;
return A->y_pos < B->y_pos;
}
void pp_print_buffer(struct pp_buf * buf)
{
/* sort buffer lines */
qsort(buf->lines, buf->n_lines, sizeof(struct pp_line), line_pos_cmpr);
int i;
for (i = 0; i < buf->n_lines; i++) {
printf("%s\n", buf->lines[i].text);
}
}
void pp_print_expression(Node * ast, int * x, double * y, double * ULim, double * LLim,
struct pp_buf * buf)
{
switch(ast->type) {
case BIN_OP_TIMES:
pp_print_product(ast, x, y, ULim, LLim, buf);
break;
case BIN_OP_POWER:
pp_print_power(ast, x, y, ULim, LLim, buf);
break;
case FRAC:
pp_print_fraction(ast, x, y, ULim, LLim, buf);
break;
case INT:
pp_print_integer(ast, x, y, ULim, LLim, buf);
break;
case VAR:
pp_print_var(ast, x, y, ULim, LLim, buf);
break;
}
}
void pp_print_product(Node * ast, int * x, double * y, double * ULim, double * LLim,
struct pp_buf * buf)
{
int n = ast->n_args;
int i;
for (i = 0; i < n; i++) {
pp_print_expression(ast->args[i], x, y, ULim, LLim, buf);
*x++;
pp_print_char(buf, ' ', *x, *y);
}
}
void pp_print_power(Node * ast, int *x, double *y, double * ULim, double * LLim, struct pp_buf * buf)
{
pp_print_expression(ast->args[0], x, y, ULim, LLim, buf);
/* advance to next character */
*x++;
double y_exponent = (*ULim + *y)/2.0;
pp_print_expression(ast->args[1], x, &y_exponent, ULim, LLim, buf);
}
void pp_print_fraction(Node * ast, int * x, double *y, double * ULim, double * LLim, struct pp_buf * buf)
{
int ntop = num_digits(numerator_fun(ast));
int nbot = num_digits(denominator_fun(ast));
int linelen = (ntop < nbot) ? nbot : ntop;
int i;
int x2 = *x;
int xnum = *x;
int xdenom = *x;
double y2 = *y;
double ynum = y2 - 1;
double ydenom = y2 +1;
double LLim_num = *y;
double ULim_denom = *y;
for (i = 0; i < linelen; i++) {
pp_print_char(buf, '-', x2+i, y2);
}
pp_print_expression(ast->args[0], &xnum, &ynum, ULim, &LLim_num, buf);
pp_print_expression(ast->args[1], &xdenom, &ydenom, &ULim_denom, LLim, buf);
}
void pp_print_integer(Node * ast, int * x, double *y, double * ULim, double * LLim, struct pp_buf * buf)
{
char str[256];
sprintf(str, "%d", ast->value);
int slen = (int)((ceil(log10(ast->value))+1)*sizeof(char));
int i;
for (i = 0; i < slen; i++)
{
pp_print_char(buf, str[i], *x, *y);
*x++;
}
}
void pp_print_var(Node * ast, int * x, double * y, double * ULim, double * LLim, struct pp_buf * buf)
{
int ind = 0;
while (ast->name[ind] != '\0')
{
pp_print_char(buf, ast->name[ind], *x, *y);
*x += 1;
}
}