URI:
       tprint.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tprint.c (7127B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include <ctype.h>
            5 #include <mach.h>
            6 #define Extern extern
            7 #include "acid.h"
            8 
            9 static char *binop[NUMO];
           10 
           11 static void
           12 initbinop(void)
           13 {
           14         binop[OMUL]=        "*";
           15         binop[ODIV]=        "/";
           16         binop[OMOD]=        "%";
           17         binop[OADD]=        "+";
           18         binop[OSUB]=        "-";
           19         binop[ORSH]=        ">>";
           20         binop[OLSH]=        "<<";
           21         binop[OLT]=        "<";
           22         binop[OGT]=        ">";
           23         binop[OLEQ]=        "<=";
           24         binop[OGEQ]=        ">=";
           25         binop[OEQ]=        "==";
           26         binop[ONEQ]=        "!=";
           27         binop[OLAND]=        "&";
           28         binop[OXOR]=        "^";
           29         binop[OLOR]=        "|";
           30         binop[OCAND]=        "&&";
           31         binop[OCOR]=        "||";
           32         binop[OASGN]=        " = ";
           33 }
           34 
           35 static char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
           36 char *typenames[] = {
           37         "integer",
           38         "float",
           39         "string",
           40         "list",
           41         "code"
           42 };
           43 
           44 void
           45 initprint(void)
           46 {
           47         initbinop();
           48 }
           49 
           50 int
           51 cmp(const void *va, const void *vb)
           52 {
           53         char **a = (char**)va;
           54         char **b = (char**)vb;
           55 
           56         return strcmp(*a, *b);
           57 }
           58 
           59 void
           60 fundefs(void)
           61 {
           62         Lsym *l;
           63         char **vec;
           64         int i, j, n, max, col, f, g, s;
           65 
           66         max = 0;
           67         f = 0;
           68         g = 100;
           69         vec = malloc(sizeof(char*)*g);
           70         if(vec == 0)
           71                 fatal("out of memory");
           72 
           73         for(i = 0; i < Hashsize; i++) {
           74                 for(l = hash[i]; l; l = l->hash) {
           75                         if(l->proc == 0 && l->builtin == 0)
           76                                 continue;
           77                         n = strlen(l->name);
           78                         if(n > max)
           79                                 max = n;
           80                         if(f >= g) {
           81                                 g *= 2;
           82                                 vec = realloc(vec, sizeof(char*)*g);
           83                                 if(vec == 0)
           84                                         fatal("out of memory");
           85                         }
           86                         vec[f++] = l->name;
           87                 }
           88         }
           89         qsort(vec, f, sizeof(char*), cmp);
           90         max++;
           91         col = 60/max;
           92         s = (f+col-1)/col;
           93 
           94         for(i = 0; i < s; i++) {
           95                 for(j = i; j < f; j += s)
           96                         Bprint(bout, "%-*s", max, vec[j]);
           97                 Bprint(bout, "\n");
           98         }
           99 }
          100 
          101 void
          102 whatis(Lsym *l)
          103 {
          104         int t;
          105         int def;
          106         Type *ti;
          107 
          108         if(l == 0) {
          109                 fundefs();
          110                 return;
          111         }
          112 
          113         def = 0;
          114         if(l->v->set) {
          115                 t = l->v->type;
          116                 Bprint(bout, "%s variable", typenames[t]);
          117                 if(t == TINT || t == TFLOAT)
          118                         Bprint(bout, " format %c", l->v->store.fmt);
          119                 if(l->v->store.comt)
          120                         Bprint(bout, " complex %s",
          121                                                 l->v->store.comt->base->name);
          122                 Bputc(bout, '\n');
          123                 def = 1;
          124         }
          125         if(l->lt) {
          126                 Bprint(bout, "complex %s {\n", l->name);
          127                 for(ti = l->lt; ti; ti = ti->next) {
          128                         if(ti->type) {
          129                                 if(ti->fmt == 'a') {
          130                                         Bprint(bout, "\t%s %d %s;\n",
          131                                         ti->type->name, ti->offset,
          132                                         ti->tag->name);
          133                                 }
          134                                 else {
          135                                         Bprint(bout, "\t'%c' %s %d %s;\n",
          136                                         ti->fmt, ti->type->name, ti->offset,
          137                                         ti->tag->name);
          138                                 }
          139                         }
          140                         else
          141                                 Bprint(bout, "\t'%c' %d %s;\n",
          142                                 ti->fmt, ti->offset, ti->tag->name);
          143                 }
          144                 Bprint(bout, "};\n");
          145                 def = 1;
          146         }
          147         if(l->proc) {
          148                 Bprint(bout, "defn %s(", l->name);
          149                 pexpr(l->proc->left);
          150                 Bprint(bout, ") {\n");
          151                 pcode(l->proc->right, 1);
          152                 Bprint(bout, "}\n");
          153                 def = 1;
          154         }
          155         if(l->builtin) {
          156                 Bprint(bout, "builtin function\n");
          157                 def = 1;
          158         }
          159         if(def == 0)
          160                 Bprint(bout, "%s is undefined\n", l->name);
          161 }
          162 
          163 void
          164 slist(Node *n, int d)
          165 {
          166         if(n == 0)
          167                 return;
          168         if(n->op == OLIST)
          169                 Bprint(bout, "%.*s{\n", d-1, tabs);
          170         pcode(n, d);
          171         if(n->op == OLIST)
          172                 Bprint(bout, "%.*s}\n", d-1, tabs);
          173 }
          174 
          175 void
          176 pcode(Node *n, int d)
          177 {
          178         Node *r, *l;
          179 
          180         if(n == 0)
          181                 return;
          182 
          183         r = n->right;
          184         l = n->left;
          185 
          186         switch(n->op) {
          187         default:
          188                 Bprint(bout, "%.*s", d, tabs);
          189                 pexpr(n);
          190                 Bprint(bout, ";\n");
          191                 break;
          192         case OLIST:
          193                 pcode(n->left, d);
          194                 pcode(n->right, d);
          195                 break;
          196         case OLOCAL:
          197                 Bprint(bout, "%.*slocal", d, tabs);
          198                 while(l) {
          199                         Bprint(bout, " %s", l->sym->name);
          200                         l = l->left;
          201                         if(l == 0)
          202                                 Bprint(bout, ";\n");
          203                         else
          204                                 Bprint(bout, ",");
          205                 }
          206                 break;
          207         case OCOMPLEX:
          208                 Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);
          209                 break;
          210         case OIF:
          211                 Bprint(bout, "%.*sif ", d, tabs);
          212                 pexpr(l);
          213                 d++;
          214                 Bprint(bout, " then\n");
          215                 if(r && r->op == OELSE) {
          216                         slist(r->left, d);
          217                         Bprint(bout, "%.*selse\n", d-1, tabs);
          218                         slist(r->right, d);
          219                 }
          220                 else
          221                         slist(r, d);
          222                 break;
          223         case OWHILE:
          224                 Bprint(bout, "%.*swhile ", d, tabs);
          225                 pexpr(l);
          226                 d++;
          227                 Bprint(bout, " do\n");
          228                 slist(r, d);
          229                 break;
          230         case ORET:
          231                 Bprint(bout, "%.*sreturn ", d, tabs);
          232                 pexpr(l);
          233                 Bprint(bout, ";\n");
          234                 break;
          235         case ODO:
          236                 Bprint(bout, "%.*sloop ", d, tabs);
          237                 pexpr(l->left);
          238                 Bprint(bout, ", ");
          239                 pexpr(l->right);
          240                 Bprint(bout, " do\n");
          241                 slist(r, d+1);
          242         }
          243 }
          244 
          245 void
          246 pexpr(Node *n)
          247 {
          248         Node *r, *l;
          249 
          250         if(n == 0)
          251                 return;
          252 
          253         r = n->right;
          254         l = n->left;
          255 
          256         switch(n->op) {
          257         case ONAME:
          258                 Bprint(bout, "%s", n->sym->name);
          259                 break;
          260         case OCONST:
          261                 switch(n->type) {
          262                 case TINT:
          263                         Bprint(bout, "%d", (int)n->store.u.ival);
          264                         break;
          265                 case TFLOAT:
          266                         Bprint(bout, "%g", n->store.u.fval);
          267                         break;
          268                 case TSTRING:
          269                         pstr(n->store.u.string);
          270                         break;
          271                 case TLIST:
          272                         break;
          273                 }
          274                 break;
          275         case OMUL:
          276         case ODIV:
          277         case OMOD:
          278         case OADD:
          279         case OSUB:
          280         case ORSH:
          281         case OLSH:
          282         case OLT:
          283         case OGT:
          284         case OLEQ:
          285         case OGEQ:
          286         case OEQ:
          287         case ONEQ:
          288         case OLAND:
          289         case OXOR:
          290         case OLOR:
          291         case OCAND:
          292         case OCOR:
          293                 Bputc(bout, '(');
          294                 pexpr(l);
          295                 Bprint(bout, binop[(uchar)n->op]);
          296                 pexpr(r);
          297                 Bputc(bout, ')');
          298                 break;
          299         case OASGN:
          300                 pexpr(l);
          301                 Bprint(bout, binop[(uchar)n->op]);
          302                 pexpr(r);
          303                 break;
          304         case OINDM:
          305                 Bprint(bout, "*");
          306                 pexpr(l);
          307                 break;
          308         case OEDEC:
          309                 Bprint(bout, "--");
          310                 pexpr(l);
          311                 break;
          312         case OEINC:
          313                 Bprint(bout, "++");
          314                 pexpr(l);
          315                 break;
          316         case OPINC:
          317                 pexpr(l);
          318                 Bprint(bout, "++");
          319                 break;
          320         case OPDEC:
          321                 pexpr(l);
          322                 Bprint(bout, "--");
          323                 break;
          324         case ONOT:
          325                 Bprint(bout, "!");
          326                 pexpr(l);
          327                 break;
          328         case OLIST:
          329                 pexpr(l);
          330                 if(r) {
          331                         Bprint(bout, ",");
          332                         pexpr(r);
          333                 }
          334                 break;
          335         case OCALL:
          336                 pexpr(l);
          337                 Bprint(bout, "(");
          338                 pexpr(r);
          339                 Bprint(bout, ")");
          340                 break;
          341         case OCTRUCT:
          342                 Bprint(bout, "{");
          343                 pexpr(l);
          344                 Bprint(bout, "}");
          345                 break;
          346         case OHEAD:
          347                 Bprint(bout, "head ");
          348                 pexpr(l);
          349                 break;
          350         case OTAIL:
          351                 Bprint(bout, "tail ");
          352                 pexpr(l);
          353                 break;
          354         case OAPPEND:
          355                 Bprint(bout, "append ");
          356                 pexpr(l);
          357                 Bprint(bout, ",");
          358                 pexpr(r);
          359                 break;
          360         case ODELETE:
          361                 Bprint(bout, "delete ");
          362                 pexpr(l);
          363                 Bprint(bout, ",");
          364                 pexpr(r);
          365                 break;
          366         case ORET:
          367                 Bprint(bout, "return ");
          368                 pexpr(l);
          369                 break;
          370         case OINDEX:
          371                 pexpr(l);
          372                 Bprint(bout, "[");
          373                 pexpr(r);
          374                 Bprint(bout, "]");
          375                 break;
          376         case OINDC:
          377                 Bprint(bout, "@");
          378                 pexpr(l);
          379                 break;
          380         case ODOT:
          381                 pexpr(l);
          382                 Bprint(bout, ".%s", n->sym->name);
          383                 break;
          384         case OFRAME:
          385                 Bprint(bout, "%s:%s", n->sym->name, l->sym->name);
          386                 break;
          387         case OCAST:
          388                 Bprint(bout, "(%s)", n->sym->name);
          389                 pexpr(l);
          390                 break;
          391         case OFMT:
          392                 pexpr(l);
          393                 Bprint(bout, "\\%c", (int)r->store.u.ival);
          394                 break;
          395         case OEVAL:
          396                 Bprint(bout, "eval ");
          397                 pexpr(l);
          398                 break;
          399         case OWHAT:
          400                 Bprint(bout, "whatis");
          401                 if(n->sym)
          402                         Bprint(bout, " %s", n->sym->name);
          403                 break;
          404         case OUPLUS:
          405                 Bprint(bout, "+");
          406                 pexpr(l);
          407                 break;
          408         }
          409 }
          410 
          411 void
          412 pstr(String *s)
          413 {
          414         int i, c;
          415 
          416         Bputc(bout, '"');
          417         for(i = 0; i < s->len; i++) {
          418                 c = s->string[i];
          419                 switch(c) {
          420                 case '\0':
          421                         c = '0';
          422                         break;
          423                 case '\n':
          424                         c = 'n';
          425                         break;
          426                 case '\r':
          427                         c = 'r';
          428                         break;
          429                 case '\t':
          430                         c = 't';
          431                         break;
          432                 case '\b':
          433                         c = 'b';
          434                         break;
          435                 case '\f':
          436                         c = 'f';
          437                         break;
          438                 case '\a':
          439                         c = 'a';
          440                         break;
          441                 case '\v':
          442                         c = 'v';
          443                         break;
          444                 case '\\':
          445                         c = '\\';
          446                         break;
          447                 case '"':
          448                         c = '"';
          449                         break;
          450                 default:
          451                         Bputc(bout, c);
          452                         continue;
          453                 }
          454                 Bputc(bout, '\\');
          455                 Bputc(bout, c);
          456         }
          457         Bputc(bout, '"');
          458 }