<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "util.h"
#include "parse.h"

static int getintlit(Node *n, vlong *v)
{
	Node *l;

	if (exprop(n) != Olit)
		return 0;
	l = n->expr.args[0];
	if (l->lit.littype != Lint)
		return 0;
	*v = l->lit.intval;
	return 1;
}

static int isintval(Node *n, vlong val)
{
	vlong v;

	if (!getintlit(n, &v))
		return 0;
	return v == val;
}

static Node *val(Srcloc loc, vlong val, Type *t)
{
	Node *l, *n;

	l = mkint(loc, val);
	n = mkexpr(loc, Olit, l, NULL);
	l->lit.type = t;
	n->expr.type = t;
	return n;
}

static int issmallconst(Node *dcl)
{
	Type *t;

	if (!dcl->decl.isconst)
		return 0;
	if (!dcl->decl.init)
		return 0;
	t = tybase(exprtype(dcl->decl.init));
	if (t->type <= Tyflt64)
		return 1;
	return 0;
}

static Node *foldcast(Node *n)
{
	Type *to, *from;
	Node *sub;

	sub = n->expr.args[0];
	to = exprtype(n);
	from = exprtype(sub);

	switch (tybase(to)->type) {
	case Tybool:
	case Tyint8: case Tyint16: case Tyint32: case Tyint64:
	case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
	case Tyint: case Tyuint: case Tychar: case Tybyte:
	case Typtr:
		switch (tybase(from)->type) {
		case Tybool:
		case Tyint8: case Tyint16: case Tyint32: case Tyint64:
		case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
		case Tyint: case Tyuint: case Tychar: case Tybyte:
		case Typtr:
			if (exprop(sub) == Olit || tybase(from)->type == tybase(to)->type) {
				sub->expr.type = to;
				return sub;
			} else {
				return n;
			}
		default:
			return n;
		}
	default:
		return n;
	}
	return n;
}

int idxcmp(const void *pa, const void *pb)
{
	Node *a, *b;
	vlong av, bv;

	a = *(Node **)pa;
	b = *(Node **)pb;

	assert(getintlit(a->expr.idx, &av));
	assert(getintlit(b->expr.idx, &bv));

	/* don't trust overflow with int64 */
	if (av < bv)
		return -1;
	else if (av == bv)
		return 0;
	else
		return 1;
}

Node *fold(Node *n, int foldvar)
{
	Node **args, *r;
	Type *t;
	vlong a, b;
	Ucon *uc;
	size_t i;

	if (!n)
		return NULL;
	if (n->type != Nexpr)
		return n;

	r = NULL;
	args = n->expr.args;
	if (n->expr.idx)
		n->expr.idx = fold(n->expr.idx, foldvar);
	for (i = 0; i < n->expr.nargs; i++)
		args[i] = fold(args[i], foldvar);
	switch (exprop(n)) {
	case Outag:
		if (exprop(args[0]) != Oucon)
			break;
		uc = finducon(tybase(exprtype(args[0])), args[0]->expr.args[0]);
		r = val(n->loc, uc->id, exprtype(n));
		break;
	case Ovar:
		if (foldvar && issmallconst(decls[n->expr.did]))
			r = fold(decls[n->expr.did]->decl.init, foldvar);
		break;<commit_msg>Fold Oudata.<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "util.h"
#include "parse.h"

static int getintlit(Node *n, vlong *v)
{
	Node *l;

	if (exprop(n) != Olit)
		return 0;
	l = n->expr.args[0];
	if (l->lit.littype != Lint)
		return 0;
	*v = l->lit.intval;
	return 1;
}

static int isintval(Node *n, vlong val)
{
	vlong v;

	if (!getintlit(n, &v))
		return 0;
	return v == val;
}

static Node *val(Srcloc loc, vlong val, Type *t)
{
	Node *l, *n;

	l = mkint(loc, val);
	n = mkexpr(loc, Olit, l, NULL);
	l->lit.type = t;
	n->expr.type = t;
	return n;
}

static int issmallconst(Node *dcl)
{
	Type *t;

	if (!dcl->decl.isconst)
		return 0;
	if (!dcl->decl.init)
		return 0;
	t = tybase(exprtype(dcl->decl.init));
	if (t->type <= Tyflt64)
		return 1;
	return 0;
}

static Node *foldcast(Node *n)
{
	Type *to, *from;
	Node *sub;

	sub = n->expr.args[0];
	to = exprtype(n);
	from = exprtype(sub);

	switch (tybase(to)->type) {
	case Tybool:
	case Tyint8: case Tyint16: case Tyint32: case Tyint64:
	case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
	case Tyint: case Tyuint: case Tychar: case Tybyte:
	case Typtr:
		switch (tybase(from)->type) {
		case Tybool:
		case Tyint8: case Tyint16: case Tyint32: case Tyint64:
		case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
		case Tyint: case Tyuint: case Tychar: case Tybyte:
		case Typtr:
			if (exprop(sub) == Olit || tybase(from)->type == tybase(to)->type) {
				sub->expr.type = to;
				return sub;
			} else {
				return n;
			}
		default:
			return n;
		}
	default:
		return n;
	}
	return n;
}

int idxcmp(const void *pa, const void *pb)
{
	Node *a, *b;
	vlong av, bv;

	a = *(Node **)pa;
	b = *(Node **)pb;

	assert(getintlit(a->expr.idx, &av));
	assert(getintlit(b->expr.idx, &bv));

	/* don't trust overflow with int64 */
	if (av < bv)
		return -1;
	else if (av == bv)
		return 0;
	else
		return 1;
}

Node *fold(Node *n, int foldvar)
{
	Node **args, *r;
	Type *t;
	vlong a, b;
	Ucon *uc;
	size_t i;

	if (!n)
		return NULL;
	if (n->type != Nexpr)
		return n;

	r = NULL;
	args = n->expr.args;
	if (n->expr.idx)
		n->expr.idx = fold(n->expr.idx, foldvar);
	for (i = 0; i < n->expr.nargs; i++)
		args[i] = fold(args[i], foldvar);
	switch (exprop(n)) {
	case Outag:
		if (exprop(args[0]) != Oucon)
			break;
		uc = finducon(tybase(exprtype(args[0])), args[0]->expr.args[0]);
		r = val(n->loc, uc->id, exprtype(n));
		break;
	case Oudata:
		if (exprop(args[0]) != Oucon || args[0]->expr.nargs != 2)
			break;
		r = args[0]->expr.args[1];
		break;
	case Ovar:
		if (foldvar && issmallconst(decls[n->expr.did]))
			r = fold(decls[n->expr.did]->decl.init, foldvar);
		break;
{'fraction_non_alphanumeric': 0.18449919079302285, 'fraction_numerical': 0.018881496133788887, 'mean_word_length': 3.4496, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 85, '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': '3337320', 'n_tokens_mistral': 2673, 'n_tokens_neox': 2485, 'n_words': 651}