scc

simple C compiler
git clone git@git.2f30.org/scc.git
Log | Files | Refs | README | LICENSE

main.c (1764B)


      1 static char sccsid[] = "@(#) ./as/main.c";
      2 
      3 #include <ctype.h>
      4 #include <setjmp.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #include "../inc/scc.h"
     10 #include "as.h"
     11 
     12 static int
     13 cmp(const void *f1, const void *f2)
     14 {
     15 	const Ins *ins = f2;
     16 	const char *s = f1;
     17 	int d;
     18 
     19 	if ((d = *s - *ins->str) != 0)
     20 		return d;
     21 
     22 	return strcmp(s, ins->str);
     23 }
     24 
     25 static void
     26 as(char *text, char *xargs)
     27 {
     28 	int c;
     29 	char *p;
     30 	Ins *ins;
     31 	Op *op, *lim;
     32 	Node **args;
     33 
     34 	for (p = text; c = *p; ++p)
     35 		*p = toupper(c);
     36 
     37 	ins = bsearch(text, instab, nr_ins, sizeof(Ins), cmp);
     38 	if (!ins) {
     39 		error("invalid instruction");
     40 		return;
     41 	}
     42 
     43 	args = getargs(xargs);
     44 	lim = &optab[ins->end];
     45 	for (op = &optab[ins->begin]; op < lim; ++op) {
     46 		if (match(op, args))
     47 			break;
     48 	}
     49 	if (op == lim) {
     50 		error("invalid operands");
     51 		return;
     52 	}
     53 	(*op->format)(op, args);
     54 }
     55 
     56 static int
     57 dopass(char *fname)
     58 {
     59 	struct line line;
     60 	FILE *fp;
     61 	extern int nerrors;
     62 	extern jmp_buf recover;
     63 
     64 	if ((fp = fopen(fname, "r")) == NULL)
     65 		die("as: error opening '%s'", fname);
     66 	isections();
     67 
     68 	setjmp(recover);
     69 	while (nextline(fp, &line)) {
     70 		linesym = NULL;
     71 
     72 		if (line.label)
     73 			linesym = deflabel(line.label);
     74 
     75 		if (line.op)
     76 			as(line.op, line.args);
     77 		else if (line.args)
     78 			error("arguments without an opcode");
     79 	}
     80 
     81 	if (fclose(fp))
     82 		die("as: error reading from input file '%s'", fname);
     83 	if (pass == 2)
     84 		writeout("a.out");
     85 	/*
     86 	 * kill tmp symbols because they are not needed anymore
     87 	 */
     88 	killtmp();
     89 
     90 	return nerrors == 0;
     91 }
     92 
     93 static void
     94 usage(void)
     95 {
     96 	fputs("usage: as filename\n", stderr);
     97 	exit(1);
     98 }
     99 
    100 int
    101 main(int argc, char *argv[])
    102 {
    103 	if (argc != 2)
    104 		usage();
    105 
    106 	iarch();
    107 	filename = argv[1];
    108 	for (pass = 1; pass <= 2; pass++) {
    109 		if (!dopass(filename))
    110 			return 1;
    111 	}
    112 
    113 	return 0;
    114 }