code.c - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       code.c (3407B)
       ---
            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 '\a':
           86                         t = "\\a";
           87                         goto print_str;
           88                 case '\f':
           89                         t = "\\f";
           90                         goto print_str;
           91                 case '\r':
           92                         t = "\\r";
           93                         goto print_str;
           94                 case '"':
           95                         t = "\\\"";
           96                         goto print_str;
           97                 case '\'':
           98                         t = "\\'";
           99                         goto print_str;
          100                 case '\?':
          101                         t = "\\\?";
          102                         goto print_str;
          103                 case '\\':
          104                         putchar('\\');
          105                 default:
          106                         if (!isprint(c))
          107                                 printf("\\x%x", c);
          108                         else
          109                                 putchar(c);
          110                         break;
          111                 print_str:
          112                         fputs(t, stdout);
          113                         break;
          114                 }
          115         }
          116         putchar('"');
          117 }
          118 
          119 Symbol *
          120 newlabel(void)
          121 {
          122         Symbol *sym = getsym(TMPSYM);
          123 
          124         sym->kind = SLABEL;
          125         return sym;
          126 }
          127 
          128 Node *
          129 labelstmt(Node *np, Symbol *sym)
          130 {
          131         if(!sym)
          132                 sym = newlabel();
          133         if (!np)
          134                 np = node(ONOP);
          135         np->label = sym;
          136         sym->u.stmt = np;
          137 
          138         return np;
          139 }
          140 
          141 Node *
          142 label2node(Node *np, Symbol *sym)
          143 {
          144         if(!sym)
          145                 sym = newlabel();
          146         if (!np)
          147                 np = node(OLABEL);
          148         np->op = OLABEL;
          149         np->u.sym = sym;
          150 
          151         return np;
          152 }
          153 
          154 Node *
          155 tmpnode(Type *tp, Symbol *sym)
          156 {
          157         unsigned short flags;
          158         Node *np;
          159 
          160         np = node(OTMP);
          161         if (!sym) {
          162                 sym = getsym(TMPSYM);
          163                 sym->type = np->type = *tp;
          164                 sym->kind = STMP;
          165         }
          166 
          167         flags = tp->flags & ~(PARF|INITF);
          168         sym->type.flags = np->type.flags = flags;
          169         np->type = *tp;
          170         np->left = np->right = NULL;
          171         np->u.sym = sym;
          172         np->op = OTMP;
          173 
          174         return np;
          175 }
          176 
          177 Node *
          178 idxnode(Node *np, long off)
          179 {
          180         if (!np)
          181                 np = node(OINDEX);
          182         np->op = OINDEX;
          183         np->left = np->right = NULL;
          184         np->type = ptrtype;
          185         np->u.off = off;
          186         return np;
          187 }
          188 
          189 Node *
          190 constnode(Node *np, TUINT n, Type *tp)
          191 {
          192         if (!np)
          193                 np = node(OCONST);
          194         np->op = OCONST;
          195         np->left = np->right = NULL;
          196         np->type = *tp;
          197         np->u.i = n;
          198         return np;
          199 }
          200 
          201 void
          202 setlabel(Symbol *sym)
          203 {
          204         if (!sym)
          205                 return;
          206         code(ASLABEL, NULL, NULL, NULL);
          207         pc->label = sym;
          208         sym->u.inst = pc;
          209 }
          210 
          211 void
          212 code(int op, Node *to, Node *from1, Node *from2)
          213 {
          214         nextpc();
          215         if (from1)
          216                 addr(from1, &pc->from1);
          217         if (from2)
          218                 addr(from2, &pc->from2);
          219         if (to)
          220                 addr(to, &pc->to);
          221         pc->op = op;
          222 }
          223 
          224 void
          225 delcode(void)
          226 {
          227         Inst *prev = pc->prev, *next = pc->next;
          228 
          229         free(pc);
          230         if (!prev) {
          231                 prog = pc = next;
          232         } else {
          233                 pc = prev;
          234                 prev->next = next;
          235                 if (next)
          236                         next->prev = prev;
          237         }
          238 }