<commit_before>
#include <stdint.h>
#include <stdio.h>

#include "cc1.h"

char *opcodes[] = {
	[OADD] = "+",
	[OSUB] = "-",
	[OMUL] = "*",
	[OARY] = "'",
	[OINC] = ";+",
	[ODEC] =  ";=",
	[OSIZE] = "#",
	[OPTR] = "@",
	[OMOD] = "*",
	[ODIV] = "/",
	[OSHL] = "l",
	[OSHR]  = "r",
	[OLT] = "<",
	[OGT] = ">",
	[OGE] = "]",
	[OLE] =  "[",
	[OEQ] = "=",
	[ONE] = "!",
	[OBAND] = "&",
	[OBXOR]  = "^",
	[OBOR] = "|",
	[OASSIGN] = ":",
	[OA_MUL] = ":*",
	[OA_DIV] = ":/",
	[OA_MOD] = ":%",
	[OA_ADD] = ":+",
	[OA_SUB] = ":-",
	[OA_SHL] = ":l",
	[OA_SHR] = ":r",
	[OA_AND] = ":&",
	[OA_XOR] = ":^",
	[OA_OR] = ":|",
	[OADDR] = "a",
	[ONEG] = "_",
	[OCPL] = "~",
	[OAND] = "m",
	[OOR] = "s",
	[OCOMMA] = ","
};

Node *
node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds)
{
	Node *np = xmalloc(sizeof(*np) + nchilds * sizeof(np));

	np->code = code;
	np->type = tp;
	np->utype = UNQUAL(tp);
	np->typeop = np->utype->op;
	np->u = u;
	np->b.symbol = np->b.lvalue = 0;

	return np;
}

static void
emitsym2(Symbol *sym)
{
	char c;

	if (sym->s.isglobal)
		c = 'G';
	else if (sym->s.isstatic)
		c = 'T';
	else if (sym->s.isregister)
		c = 'Q';
	else
		c = 'A';
	printf("%c%d", c, sym->id);
}

static void
emitconst(Node *np)
{
	register char *bp, c;
	Symbol *sym = np->u.sym;

	if (np->type == inttype) {
		printf("#%x", sym->u.i);
	} else {
		putchar('"');
		for (bp = sym->u.s; c = *bp; ++bp)
			printf("%02x", (unsigned) c);
	}
}

void
emitsym(Node *np)
{
	putchar('\t');
	(np->b.constant) ? emitconst(np) : emitsym2(np->u.sym);
}

static void
emittype(Type *tp)
{
	putchar(tp->letter);
}

void
emitdcl(Symbol *sym)
{
	emitsym2(sym);
	putchar('\t');
	emittype(sym->type);
	putchar('\n');
}

void
emitcast(Node *np)
{
	Node *child = np->childs[0];

	(*child->code)(child);
	printf("\t%c%c", np->u.type->letter, np->type->letter);
}

void
emitunary(Node *np)
{
	Node *child;
	char op, letter;

	letter = np->type->letter;
	child = np->childs[0];
	(*child->code)(child);
	printf("\t%s%c", opcodes[np->u.op], letter);
}

void
emitbin(Node *np)
{
	Node *child1, *child2;

	child1 = np->childs[0];
	child2 = np->childs[1];
	(*child1->code)(child1);
	(*child2->code)(child2);
	printf("\t%s%c", opcodes[np->u.op], np->type->letter);
}

void
emitternary(Node *np)
{
	Node *cond, *ifyes, *ifno;

	cond = np->childs[0];
	ifyes = np->childs[1];
	ifno = np->childs[2];
	(*cond->code)(cond);
	(*ifyes->code)(ifyes);
	(*ifno->code)(ifno);
	printf("\t?%c", np->type->letter);
}

void
emitsizeof(Node *np)
{
	printf("\t#%c", np->u.type->letter);
}

void
emitexp(Node *np)
{
	if (np)
		(*np->code)(np);
	putchar('\n');
}

void
emitprint(Node *np)
{
	(*np->code)(np);
	printf("\tk%c\n", np->type->letter);
}

void
emitfun(Symbol *sym)
{
	printf("%c%d\tn%s\n",
	       sym->s.isglobal ? 'X' : 'Y', sym->id, sym->name);
}

void
emitsframe(Symbol *sym)
{
	puts("{");
}

void
emiteframe(Symbol *sym)
{
	puts("}");
}

void
emitret(Type *tp)
{
	fputs("\ty", stdout);
	emittype(tp);
}

void
emitlabel(Symbol *sym)
{
	printf("L%d\n", sym->id);
}

void
emitbloop(void)
{
	puts("\td");
}

void
emiteloop(void)
{
	puts("\tb");
}

void
emitjump(Symbol *sym, Node *np)
{
	printf("\tj\tL%d", sym->id);
	if (!np)
		putchar('\n');
	else
		emitexp(np);
}

void
emitswitch(short nr, Node *np)
{
	printf("\teI\t#%0x", nr);
	emitexp(np);
}

void
emitcase(Symbol *sym, Node *np)
{
	fputs("\tw", stdout);
	(*np->code)(np);
	putchar('\t');
	emitlabel(sym);
}

void
emitdefault(Symbol *sym)<commit_msg>Change order of emiting in emitcase<commit_after>
#include <stdint.h>
#include <stdio.h>

#include "cc1.h"

char *opcodes[] = {
	[OADD] = "+",
	[OSUB] = "-",
	[OMUL] = "*",
	[OARY] = "'",
	[OINC] = ";+",
	[ODEC] =  ";=",
	[OSIZE] = "#",
	[OPTR] = "@",
	[OMOD] = "*",
	[ODIV] = "/",
	[OSHL] = "l",
	[OSHR]  = "r",
	[OLT] = "<",
	[OGT] = ">",
	[OGE] = "]",
	[OLE] =  "[",
	[OEQ] = "=",
	[ONE] = "!",
	[OBAND] = "&",
	[OBXOR]  = "^",
	[OBOR] = "|",
	[OASSIGN] = ":",
	[OA_MUL] = ":*",
	[OA_DIV] = ":/",
	[OA_MOD] = ":%",
	[OA_ADD] = ":+",
	[OA_SUB] = ":-",
	[OA_SHL] = ":l",
	[OA_SHR] = ":r",
	[OA_AND] = ":&",
	[OA_XOR] = ":^",
	[OA_OR] = ":|",
	[OADDR] = "a",
	[ONEG] = "_",
	[OCPL] = "~",
	[OAND] = "m",
	[OOR] = "s",
	[OCOMMA] = ","
};

Node *
node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds)
{
	Node *np = xmalloc(sizeof(*np) + nchilds * sizeof(np));

	np->code = code;
	np->type = tp;
	np->utype = UNQUAL(tp);
	np->typeop = np->utype->op;
	np->u = u;
	np->b.symbol = np->b.lvalue = 0;

	return np;
}

static void
emitsym2(Symbol *sym)
{
	char c;

	if (sym->s.isglobal)
		c = 'G';
	else if (sym->s.isstatic)
		c = 'T';
	else if (sym->s.isregister)
		c = 'Q';
	else
		c = 'A';
	printf("%c%d", c, sym->id);
}

static void
emitconst(Node *np)
{
	register char *bp, c;
	Symbol *sym = np->u.sym;

	if (np->type == inttype) {
		printf("#%x", sym->u.i);
	} else {
		putchar('"');
		for (bp = sym->u.s; c = *bp; ++bp)
			printf("%02x", (unsigned) c);
	}
}

void
emitsym(Node *np)
{
	putchar('\t');
	(np->b.constant) ? emitconst(np) : emitsym2(np->u.sym);
}

static void
emittype(Type *tp)
{
	putchar(tp->letter);
}

void
emitdcl(Symbol *sym)
{
	emitsym2(sym);
	putchar('\t');
	emittype(sym->type);
	putchar('\n');
}

void
emitcast(Node *np)
{
	Node *child = np->childs[0];

	(*child->code)(child);
	printf("\t%c%c", np->u.type->letter, np->type->letter);
}

void
emitunary(Node *np)
{
	Node *child;
	char op, letter;

	letter = np->type->letter;
	child = np->childs[0];
	(*child->code)(child);
	printf("\t%s%c", opcodes[np->u.op], letter);
}

void
emitbin(Node *np)
{
	Node *child1, *child2;

	child1 = np->childs[0];
	child2 = np->childs[1];
	(*child1->code)(child1);
	(*child2->code)(child2);
	printf("\t%s%c", opcodes[np->u.op], np->type->letter);
}

void
emitternary(Node *np)
{
	Node *cond, *ifyes, *ifno;

	cond = np->childs[0];
	ifyes = np->childs[1];
	ifno = np->childs[2];
	(*cond->code)(cond);
	(*ifyes->code)(ifyes);
	(*ifno->code)(ifno);
	printf("\t?%c", np->type->letter);
}

void
emitsizeof(Node *np)
{
	printf("\t#%c", np->u.type->letter);
}

void
emitexp(Node *np)
{
	if (np)
		(*np->code)(np);
	putchar('\n');
}

void
emitprint(Node *np)
{
	(*np->code)(np);
	printf("\tk%c\n", np->type->letter);
}

void
emitfun(Symbol *sym)
{
	printf("%c%d\tn%s\n",
	       sym->s.isglobal ? 'X' : 'Y', sym->id, sym->name);
}

void
emitsframe(Symbol *sym)
{
	puts("{");
}

void
emiteframe(Symbol *sym)
{
	puts("}");
}

void
emitret(Type *tp)
{
	fputs("\ty", stdout);
	emittype(tp);
}

void
emitlabel(Symbol *sym)
{
	printf("L%d\n", sym->id);
}

void
emitbloop(void)
{
	puts("\td");
}

void
emiteloop(void)
{
	puts("\tb");
}

void
emitjump(Symbol *sym, Node *np)
{
	printf("\tj\tL%d", sym->id);
	if (!np)
		putchar('\n');
	else
		emitexp(np);
}

void
emitswitch(short nr, Node *np)
{
	printf("\teI\t#%0x", nr);
	emitexp(np);
}

void
emitcase(Symbol *sym, Node *np)
{
	fputs("\tw\t", stdout);
	printf("L%d", sym->id);
	emitexp(np);
}

void
emitdefault(Symbol *sym)
{'fraction_non_alphanumeric': 0.282339383462979, 'fraction_numerical': 0.006914433880726016, 'mean_word_length': 3.7007447528774544, 'pattern_counts': {'":': 22, '<': 9, '<?xml version=': 0, '>': 127, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7157264', 'n_tokens_mistral': 3535, 'n_tokens_neox': 3462, 'n_words': 604}