main.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
       ---
       main.c (2060B)
       ---
            1 #include <errno.h>
            2 #include <ctype.h>
            3 #include <setjmp.h>
            4 #include <stdio.h>
            5 #include <stdlib.h>
            6 #include <string.h>
            7 
            8 #include <scc/arg.h>
            9 #include <scc/mach.h>
           10 #include <scc/scc.h>
           11 
           12 #include "as.h"
           13 
           14 char *argv0;
           15 char *outfile = "a.out", *infile;
           16 int endpass;
           17 
           18 static void
           19 cleanup(void)
           20 {
           21         if (outfile)
           22                 remove(outfile);
           23 }
           24 
           25 static Ins *
           26 decode(char *s)
           27 {
           28         int c;
           29         char *p;
           30         unsigned h, id;
           31         Ins *ins;
           32 
           33         for (p = s; c = *p; ++p)
           34                 *p = toupper(c);
           35 
           36         h = (unsigned short) genhash(s);
           37         h = (h*K >> S) & M;
           38         id = hashmap[h];
           39         if (id == 0)
           40                 return NULL;
           41 
           42         ins = &instab[id-1];
           43         if (strcmp(ins->str, s) != 0)
           44                 return NULL;
           45 
           46         return ins;
           47 }
           48 
           49 static void
           50 translate(char *text, char *xargs)
           51 {
           52         Ins *ins;
           53         Op *op, *lim;
           54         Node **args;
           55 
           56         ins = decode(text);
           57         if (!ins) {
           58                 error("invalid instruction '%s'", text);
           59                 return;
           60         }
           61 
           62         args = getargs(xargs);
           63         lim = &optab[ins->end];
           64         for (op = &optab[ins->begin]; op < lim; ++op) {
           65                 if (match(op, args))
           66                         break;
           67         }
           68         if (op == lim) {
           69                 error("invalid operands for '%s'", text);
           70                 return;
           71         }
           72         (*op->format)(op, args);
           73 }
           74 
           75 static int
           76 dopass(char *fname)
           77 {
           78         struct line line;
           79         extern int nerrors;
           80         extern jmp_buf recover;
           81 
           82         addinput(fname);
           83         cleansecs();
           84 
           85         endpass = 0;
           86         setjmp(recover);
           87         while (!endpass && nextline(&line)) {
           88                 linesym = NULL;
           89 
           90                 if (line.label)
           91                         linesym = deflabel(line.label);
           92 
           93                 if (line.op)
           94                         translate(line.op, line.args);
           95                 else if (line.args)
           96                         error("arguments without an opcode");
           97 
           98                 if (linesym)
           99                         linesym->flags |= FDEF;
          100         }
          101 
          102         return nerrors == 0;
          103 }
          104 
          105 static void
          106 asm(char *argv[])
          107 {
          108         char **p;
          109 
          110         for (pass = 1; pass <= 2; pass++) {
          111                 for (p = argv; infile = *p; ++p) {
          112                         if (!dopass(infile))
          113                                 exit(EXIT_FAILURE);
          114                 }
          115                 if (pass == 1)
          116                         killtmp();
          117         }
          118 }
          119 
          120 static void
          121 usage(void)
          122 {
          123         fputs("usage: as [-o outfile] filename ...\n", stderr);
          124         exit(1);
          125 }
          126 
          127 int
          128 main(int argc, char *argv[])
          129 {
          130         ARGBEGIN {
          131         case 'o':
          132                 outfile = EARGF(usage());
          133                 break;
          134         default:
          135                 usage();
          136         } ARGEND
          137 
          138         if (argc == 0)
          139                 usage();
          140 
          141         atexit(cleanup);
          142         iarch();
          143         ibinfmt();
          144         asm(argv);
          145         writeout(outfile);
          146 
          147         return 0;
          148 }