summaryrefslogtreecommitdiff
path: root/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'print.c')
-rw-r--r--print.c152
1 files changed, 133 insertions, 19 deletions
diff --git a/print.c b/print.c
index 8c3dbbf..1ebdecb 100644
--- a/print.c
+++ b/print.c
@@ -4,6 +4,9 @@
#include "apl9.h"
+void strdims(Rune *, int *, int *);
+Rune *printborder(Rune *, int *, int, int);
+
Rune *
ppdatum(Datum d)
{
@@ -59,40 +62,95 @@ Rune *
pparray(Array *a)
{
Rune **elemstrs = malloc(sizeof(Rune *) * a->size);
+ int rowcount = 1;
+ if(a->rank > 0){
+ for(int i = 0; i < a->rank-1; i++)
+ rowcount *= a->shape[i];
+ }
+ Rune **rowstrs = mallocz(sizeof(Rune *) * rowcount, 1);
+ int boxing = a->type == AtypeArray;
+
+ char *align = a->type == AtypeArray ? "-" : "";
for(int i = 0; i < a->size; i++){
if(a->type == AtypeArray){
Rune *arrstr = pparray(a->arraydata[i]);
- elemstrs[i] = runesmprint("[%S]", arrstr);
+ elemstrs[i] = runesmprint("%S", arrstr);
free(arrstr);
}else if(a->type == AtypeInt)
elemstrs[i] = runesmprint("%lld", a->intdata[i]);
}
- /* Should do some width and height padding here */
- Rune *res = runesmprint("");
- Rune *tmp;
+ int lastdim = a->rank ? a->shape[a->rank-1] : 1;
+ int *widths = mallocz(sizeof(int) * lastdim, 1);
for(int i = 0; i < a->size; i++){
- tmp = res;
- res = runesmprint("%S%S", res, elemstrs[i]);
+ int w,h;
+ strdims(elemstrs[i], &w, &h);
+ if(w > widths[i%lastdim])
+ widths[i%lastdim] = w;
+ }
+
+ /* Should do height padding here as well */
+ for(int i = 0; i < a->size; i++){
+ if(i%lastdim == 0)
+ rowstrs[i/lastdim] = runesmprint("%S", boxing ? L"│" : L"");
+ Rune *tmp = rowstrs[i/lastdim];
+ char *fmt = smprint("%%%s%dS", align, widths[i%lastdim]);
+ Rune *elem = runesmprint(fmt, elemstrs[i]);
+ Rune *spacing;
+ if((i+1)%lastdim == 0)
+ spacing = boxing ? L"│" : L"";
+ else
+ spacing = boxing ? L"│" : L" ";
+ rowstrs[i/lastdim] = runesmprint("%S%S%S", tmp, elem, spacing);
free(tmp);
+ free(elem);
+ free(fmt);
free(elemstrs[i]);
+ }
+ free(elemstrs);
+
+ if(rowstrs[0] == nil)
+ rowstrs[0] = runestrdup(L"");
+
+ if(rowcount == 1 && !boxing)
+ return rowstrs[0];
+
+ Rune *res = runesmprint("");
+ Rune *tmp;
+ for(int i = 0; i < rowcount; i++){
+ if(i == 0 && boxing)
+ res = printborder(res, widths, lastdim, 0);
int j = 1;
- int spaceprinted = 0;
- for(int dim = 0; dim < a->rank && i+1 != a->size; dim++){
- j *= a->shape[a->rank-dim-1];
+ int blanks = 0;
+ for(int dim = 0; dim < a->rank - 1 && i+1 != a->size; dim++){
+ j *= a->shape[a->rank-dim-2];
+ if(i%j == 0)
+ blanks++;
+ }
+ if(i != 0 && blanks == 0 && boxing)
+ res = printborder(res, widths, lastdim, 1);
+ if(i != 0 && blanks > 0 && boxing)
+ res = printborder(res, widths, lastdim, 2);
+
+ for(int b = 0; i != 0 && b < blanks; b++){
tmp = res;
- if((i+1)%j == 0){
- spaceprinted = 1;
- res = runesmprint("%S\n", res);
- free(tmp);
- }else if(!spaceprinted){
- spaceprinted = 1;
- res = runesmprint("%S ", res);
- free(tmp);
- }
- }
+ res = runesmprint("%S\n", tmp);
+ free(tmp);
+ }
+
+ if(blanks > 0 && i != 0 && i < rowcount-1 && boxing)
+ res = printborder(res, widths, lastdim, 0);
+
+ tmp = res;
+ res = runesmprint("%S%S\n", tmp, rowstrs[i]);
+ free(tmp);
+
+ if(i == rowcount-1 && boxing)
+ res = printborder(res, widths, lastdim, 2);
+
}
+ res[runestrlen(res)-1] = 0; /* remove trailing newline */
return res;
}
@@ -113,4 +171,60 @@ ppoperator(Operator op)
free(left);
free(right);
return res;
+}
+
+void
+strdims(Rune *s, int *width, int *height)
+{
+ int currentwidth = 0;
+ *width = 0;
+ *height = 1;
+
+ int len = runestrlen(s);
+ int i;
+ for(i = 0; i < len; i++){
+ if(s[i] == '\n'){
+ (*height)++;
+ if(currentwidth > *width)
+ *width = currentwidth;
+ currentwidth = 0;
+ }else
+ currentwidth++;
+ }
+ if(currentwidth > *width)
+ *width = currentwidth;
+}
+
+Rune *
+printborder(Rune *input, int *widths, int lastdim, int type)
+{
+ Rune *borderchars = L"????";
+ switch(type){
+ case 0: borderchars = L"┌─┬┐"; break;
+ case 1: borderchars = L"├─┼┤"; break;
+ case 2: borderchars = L"└─┴┘"; break;
+ }
+
+ int width = 1;
+ for(int i = 0; i < lastdim; i++)
+ width += widths[i]+1;
+ Rune *border = malloc(sizeof(Rune) * width + 1);
+ border[width] = 0;
+
+ border[0] = borderchars[0];
+ border[width-1] = borderchars[3];
+ for(int i = 1; i < width-1; i++)
+ border[i] = borderchars[1];
+
+ int offset = 1;
+ for(int i = 0; i < lastdim-1; i++){
+ offset += widths[i];
+ border[offset] = borderchars[2];
+ offset++;
+ }
+
+ Rune *result = runesmprint("%S%S\n", input, border);
+ //free(border);
+ //free(input);
+ return result;
} \ No newline at end of file