URI:
       code.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       code.c (3281B)
       ---
            1 #include <ctype.h>
            2 #include <stdio.h>
            3 #include <stdlib.h>
            4 #include <string.h>
            5 
            6 #include <scc/scc.h>
            7 
            8 #include "cc2.h"
            9 
           10 Inst *pc, *prog;
           11 
           12 static void
           13 nextpc(void)
           14 {
           15         Inst *new;
           16 
           17         new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */
           18 
           19         if (!pc) {
           20                 prog = new;
           21         } else {
           22                 new->next = pc->next;
           23                 pc->next = new;
           24         }
           25 
           26         /* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */
           27         new->prev = pc;
           28         pc = new;
           29 }
           30 
           31 static void
           32 addr(Node *np, Addr *addr)
           33 {
           34         Symbol *sym;
           35 
           36         switch (np->op) {
           37         case OMREG:
           38                 addr->kind = SREG;
           39                 addr->u.reg = np->u.reg;
           40                 break;
           41         case OCONST:
           42                 addr->kind = SCONST;
           43                 /* TODO: Add support for more type of constants */
           44                 addr->u.i = np->u.i;
           45                 break;
           46         case OINDEX:
           47                 addr->kind = SINDEX;
           48                 addr->u.off = np->u.off;
           49                 break;
           50         case OREG:
           51         case OTMP:
           52         case OLABEL:
           53         case OAUTO:
           54         case OMEM:
           55                 sym = np->u.sym;
           56                 addr->kind = sym->kind;
           57                 addr->u.sym = sym;
           58                 break;
           59         default:
           60                 abort();
           61         }
           62 }
           63 
           64 void
           65 pprint(char *s)
           66 {
           67         int c;
           68         char *t;
           69 
           70         putchar('"');
           71         while ((c = *s++) != '\0') {
           72                 switch (c) {
           73                 case '\n':
           74                         t = "\\n";
           75                         goto print_str;
           76                 case '\v':
           77                         t = "\\v";
           78                         goto print_str;
           79                 case '\b':
           80                         t = "\\b";
           81                         goto print_str;
           82                 case '\t':
           83                         t = "\\t";
           84                         goto print_str;
           85                 case '\f':
           86                         t = "\\f";
           87                         goto print_str;
           88                 case '\r':
           89                         t = "\\r";
           90                         goto print_str;
           91                 case '"':
           92                         t = "\\\"";
           93                         goto print_str;
           94                 case '\\':
           95                         putchar('\\');
           96                 default:
           97                         if (!isprint(c))
           98                                 printf("\\x%x", c);
           99                         else
          100                                 putchar(c);
          101                         break;
          102                 print_str:
          103                         fputs(t, stdout);
          104                         break;
          105                 }
          106         }
          107         putchar('"');
          108 }
          109 
          110 Symbol *
          111 newlabel(void)
          112 {
          113         Symbol *sym = getsym(TMPSYM);
          114 
          115         sym->kind = SLABEL;
          116         return sym;
          117 }
          118 
          119 Node *
          120 labelstmt(Node *np, Symbol *sym)
          121 {
          122         if(!sym)
          123                 sym = newlabel();
          124         if (!np)
          125                 np = node(ONOP);
          126         np->label = sym;
          127         sym->u.stmt = np;
          128 
          129         return np;
          130 }
          131 
          132 Node *
          133 label2node(Node *np, Symbol *sym)
          134 {
          135         if(!sym)
          136                 sym = newlabel();
          137         if (!np)
          138                 np = node(OLABEL);
          139         np->op = OLABEL;
          140         np->u.sym = sym;
          141 
          142         return np;
          143 }
          144 
          145 Node *
          146 tmpnode(Type *tp, Symbol *sym)
          147 {
          148         unsigned short flags;
          149         Node *np;
          150 
          151         np = node(OTMP);
          152         if (!sym) {
          153                 sym = getsym(TMPSYM);
          154                 sym->type = np->type = *tp;
          155                 sym->kind = STMP;
          156         }
          157 
          158         flags = tp->flags & ~(PARF|INITF);
          159         sym->type.flags = np->type.flags = flags;
          160         np->type = *tp;
          161         np->left = np->right = NULL;
          162         np->u.sym = sym;
          163         np->op = OTMP;
          164 
          165         return np;
          166 }
          167 
          168 Node *
          169 idxnode(Node *np, long off)
          170 {
          171         if (!np)
          172                 np = node(OINDEX);
          173         np->op = OINDEX;
          174         np->left = np->right = NULL;
          175         np->type = ptrtype;
          176         np->u.off = off;
          177         return np;
          178 }
          179 
          180 Node *
          181 constnode(Node *np, unsigned long long n, Type *tp)
          182 {
          183         if (!np)
          184                 np = node(OCONST);
          185         np->op = OCONST;
          186         np->left = np->right = NULL;
          187         np->type = *tp;
          188         np->u.i = n;
          189         return np;
          190 }
          191 
          192 void
          193 setlabel(Symbol *sym)
          194 {
          195         if (!sym)
          196                 return;
          197         code(ASLABEL, NULL, NULL, NULL);
          198         pc->label = sym;
          199         sym->u.inst = pc;
          200 }
          201 
          202 void
          203 code(int op, Node *to, Node *from1, Node *from2)
          204 {
          205         nextpc();
          206         if (from1)
          207                 addr(from1, &pc->from1);
          208         if (from2)
          209                 addr(from2, &pc->from2);
          210         if (to)
          211                 addr(to, &pc->to);
          212         pc->op = op;
          213 }
          214 
          215 void
          216 delcode(void)
          217 {
          218         Inst *prev = pc->prev, *next = pc->next;
          219 
          220         free(pc);
          221         if (!prev) {
          222                 prog = pc = next;
          223         } else {
          224                 pc = prev;
          225                 prev->next = next;
          226                 if (next)
          227                         next->prev = prev;
          228         }
          229 }