scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  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
 10Inst *pc, *prog;
 11
 12static void
 13nextpc(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
 31static void
 32addr(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
 64void
 65pprint(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
110Symbol *
111newlabel(void)
112{
113	Symbol *sym = getsym(TMPSYM);
114
115	sym->kind = SLABEL;
116	return sym;
117}
118
119Node *
120labelstmt(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
132Node *
133label2node(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
145Node *
146tmpnode(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
168Node *
169idxnode(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
180Node *
181constnode(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
192void
193setlabel(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
202void
203code(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
215void
216delcode(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}