<commit_before>#include "c.h"
#include <float.h>

/**
 * ͼĻ֮һжǷȼۡ
 * ֻһݸȼ۲ԾͿԼ򻯡
 * ַֻһݸıȽϾͺܼ򵥡
 */


static char rcsid[] = "$Id$";

// typeͱtypetable
static struct entry {
	struct _type type;
	struct entry *link;
} *typetable[128];

static Symbol pointersym;

static int maxlevel;

Type chartype;
Type doubletype;
Type floattype;
Type inttype;
Type longdouble;
Type longtype;
Type longlong;
Type shorttype;
Type signedchar;
Type unsignedchar;
Type unsignedlong;
Type unsignedlonglong;
Type unsignedshort;
Type unsignedtype;
Type funcptype;
Type charptype;
Type voidptype;
Type voidtype;
Type unsignedptr;
Type signedptr;
Type widechar;
/**
 * exitscopermtypes(lev)typetableɾЩu.sym->scopeڻlev
 */
void rmtypes(int lev) {
	if (maxlevel >= lev) {
		int i;
		maxlevel = 0;
		for (i = 0; i < NELEMS(typetable); i++) {
			struct entry *tn, **tq = &typetable[i];
			// TODO
		}
	}
}
/*
  eqtypeڲǷͬ
  жǷͼĹؼ
  ͼݣeqtype1֮0.
  ty1ty2ǲȫͣeqtypeصretֵ
  ÿݡ
  

 */
int eqtype(Type ty1, Type ty2, int ret) {
	/*
		typeֻ֤һʵͶͨeqtypeĵһԡ
		ͬͲݶΪ;вͬĲǲݵģeqtype0.
	*/
	if (ty1 == ty2)
		return 1;
	/*
		ͬ;ͬĲCHARSHORTUNSIGNEDINT
		ʾͬͣunsigned shortsigned shortҲݡ
		ͬöͣṹֻͣеͬͲǼݵġ
	*/
	if (ty1->op != ty2->op)
		return 0;
	/*
		1.ָָͣõͼݣָͼ;
		
		2.޶ͣƵ޶͵ķ޶ͣҲ;
		
		3.ͣһΪȫͣeqtyperetǵԼݡ
				   eqtypeݹʱretΪ1ڱ𴦵ʱretͨҲΪ1.
				   һЩָȽϣҪҪôǲȫͣҪôȫͣ
				   ʱeqtypeĵòret0.
				   еĵһʱĴСλõ.
		
		4.ͣ͵ķͺԭͶݣôͶݡ
				   
	*/
	switch (ty1->op) {
	case ENUM:case UNION:case STRUCT:
	case UNSIGNED:case INT:case FLOAT:
		return 0;
	case POINTER:
		return eqtype(ty1->type, ty2->type, 1);
	case CONST:case VOLATILE:case CONST+VOLATILE:
		return eqtype(ty1->type, ty2->type, 1);
	case ARRAY:
		if (eqtype(ty1->type, ty2->type, 1)) {
			if (ty1->size == ty2->size)
				return 1;
			if (ty1->size == 0 || ty2->size == 0)
				return ret;
		}
		return 0;
	case FUNCTION:
		if (eqtype(ty1->type, ty2->type, 1)) {
			Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto;
			if (p1 == p2)
				return 1;
			// ԭʱԼһЩ
			// ԭͱͬĿĲͣÿԭе͵ķ޶ʽ.
			// һԭͣ
			// ú͵ÿͱӦĬϲ(default argument promotion)
			// õͱķ޶ʽݡ
			// ͬʱԭ͵ĺԭ͵Ĳ䣬Ͳݡ
			if (p1&&p2) {
				for (; *p1&&*p2; p1++, p2++) {
					if (eqtype(unqual(*p1), unqual(*p2), 1) == 0)
						return 0;
				}
				if (*p1 == NULL&&*p2 == NULL)
					return 1;
			}
			else {
				if (variadic(p1 ? ty1 : ty2))
					return 0;
				if (p1 == NULL)
					p1 = p2;
				for (; *p1; p1++) {
					Type ty = unqual(*p1);
					if (promote(ty) != ty || ty == floattype)
						return 0;
				}
				return 1;
			}
			return 0;

		}
	}

	assert(0);
	return 0;
}
/*
	Ĭϲ
	1.Ϊ˫ȣ
	2.СöΪ޷
*/
Type promote(Type ty) {
	ty = unqual(ty);
	switch (ty->op) {
	case ENUM:
		return inttype;
	case INT:
		if (ty->size < inttype->size)
			return inttype;
		break;
	case UNSIGNED:
		if (ty->size < inttype->size)
			return inttype;
		if (ty->size < unsignedtype->size)
			return unsignedtype;
		break;
	case FLOAT:
		if (ty->size < doubletype->size)
			return doubletype;
	}
	return ty;
}
// TODO
Type compose(Type ty1, Type ty2) {
	if (ty1 == ty2)
		return ty1;
	assert(ty1->op == ty2->op);
	switch (ty1->op) {
	case POINTER:
		return ptr(compose(ty1->type, ty2->type));
	case CONST+VOLATILE:
		return qual(CONST, qual(VOLATILE, compose(ty1->type, ty2->type)));
	case CONST:case VOLATILE:
		return qual(ty1->op, compose(ty1->type, ty2->type));
	case ARRAY:
		Type ty = compose(ty1->type, ty2->type);
		if (ty1->size
			&& (ty1->type->size&&ty2->size == 0 || ty1->size == ty2->size))
			return array(ty, ty1->size / ty1->type->size, ty1->align);
		if (ty2->size
			&&ty2->type->size&&ty1->size == 0)
			return array(ty, ty2->size / ty2->type->size, ty2->align);
		return array(ty, 0, 0);
	}
	assert(0);
	return NULL;
}
Type btot(int op, int size) {
#define xx(ty) if(size==(ty)->size) return ty;
#undef xx
	return 0;
}
/**
 * typetypetableָͻߴһµ͡
 * typeΪͺͲȫʹ͡
 * ʱtypeʼָx
 * ͼӦĹϣУµ͡
 * ------------------------------------------------
 * typetypetableʱͲͲֵַΪϣֵ
 * ӦĹϣѰҾͬСֽͷűڵ͡
 */
static Type type(int op, Type ty, int size, int align, void *sym) {
	unsigned h = (op ^ ((unsigned long)ty >> 3))&(NELEMS(typetable) - 1);
	struct entry *tn;
	if (op != FUNCTION && (op != ARRAY || size > 0))
		for (tn = typetable[h]; tn; tn = tn->link)
			if (tn->type.op == op&&tn->type.type == ty
				&&tn->type.size == size&&tn->type.align == align
				&&tn->type.u.sym == sym)
				return &tn->type;
	tn = (struct entry*) memset(allocate(sizeof*(tn), PERM), 0, sizeof*(tn));
	tn->type.op = op;<commit_msg>ADD add type module<commit_after>#include "c.h"
#include <float.h>

/**
 * ͼĻ֮һжǷȼۡ
 * ֻһݸȼ۲ԾͿԼ򻯡
 * ַֻһݸıȽϾͺܼ򵥡
 */


static char rcsid[] = "$Id$";

// typeͱtypetable
static struct entry {
	struct _type type;
	struct entry *link;
} *typetable[128];

static Symbol pointersym;

static int maxlevel;

Type chartype;
Type doubletype;
Type floattype;
Type inttype;
Type longdouble;
Type longtype;
Type longlong;
Type shorttype;
Type signedchar;
Type unsignedchar;
Type unsignedlong;
Type unsignedlonglong;
Type unsignedshort;
Type unsignedtype;
Type funcptype;
Type charptype;
Type voidptype;
Type voidtype;
Type unsignedptr;
Type signedptr;
Type widechar;
/**
 * exitscopermtypes(lev)typetableɾЩu.sym->scopeڻlev
 */
void rmtypes(int lev) {
	if (maxlevel >= lev) {
		int i;
		maxlevel = 0;
		for (i = 0; i < NELEMS(typetable); i++) {
			struct entry *tn, **tq = &typetable[i];
			// TODO
		}
	}
}
/*
  eqtypeڲǷͬ
  жǷͼĹؼ
  ͼݣeqtype1֮0.
  ty1ty2ǲȫͣeqtypeصretֵ
  ÿݡ
  

 */
int eqtype(Type ty1, Type ty2, int ret) {
	/*
		typeֻ֤һʵͶͨeqtypeĵһԡ
		ͬͲݶΪ;вͬĲǲݵģeqtype0.
	*/
	if (ty1 == ty2)
		return 1;
	/*
		ͬ;ͬĲCHARSHORTUNSIGNEDINT
		ʾͬͣunsigned shortsigned shortҲݡ
		ͬöͣṹֻͣеͬͲǼݵġ
	*/
	if (ty1->op != ty2->op)
		return 0;
	/*
		1.ָָͣõͼݣָͼ;
		
		2.޶ͣƵ޶͵ķ޶ͣҲ;
		
		3.ͣһΪȫͣeqtyperetǵԼݡ
				   eqtypeݹʱretΪ1ڱ𴦵ʱretͨҲΪ1.
				   һЩָȽϣҪҪôǲȫͣҪôȫͣ
				   ʱeqtypeĵòret0.
				   еĵһʱĴСλõ.
		
		4.ͣ͵ķͺԭͶݣôͶݡ
				   
	*/
	switch (ty1->op) {
	case ENUM:case UNION:case STRUCT:
	case UNSIGNED:case INT:case FLOAT:
		return 0;
	case POINTER:
		return eqtype(ty1->type, ty2->type, 1);
	case CONST:case VOLATILE:case CONST+VOLATILE:
		return eqtype(ty1->type, ty2->type, 1);
	case ARRAY:
		if (eqtype(ty1->type, ty2->type, 1)) {
			if (ty1->size == ty2->size)
				return 1;
			if (ty1->size == 0 || ty2->size == 0)
				return ret;
		}
		return 0;
	case FUNCTION:
		if (eqtype(ty1->type, ty2->type, 1)) {
			Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto;
			if (p1 == p2)
				return 1;
			// ԭʱԼһЩ
			// ԭͱͬĿĲͣÿԭе͵ķ޶ʽ.
			// һԭͣ
			// ú͵ÿͱӦĬϲ(default argument promotion)
			// õͱķ޶ʽݡ
			// ͬʱԭ͵ĺԭ͵Ĳ䣬Ͳݡ
			if (p1&&p2) {
				for (; *p1&&*p2; p1++, p2++) {
					if (eqtype(unqual(*p1), unqual(*p2), 1) == 0)
						return 0;
				}
				if (*p1 == NULL&&*p2 == NULL)
					return 1;
			}
			else {
				if (variadic(p1 ? ty1 : ty2))
					return 0;
				if (p1 == NULL)
					p1 = p2;
				for (; *p1; p1++) {
					Type ty = unqual(*p1);
					if (promote(ty) != ty || ty == floattype)
						return 0;
				}
				return 1;
			}
			return 0;

		}
	}

	assert(0);
	return 0;
}
/*
	Ĭϲ
	1.Ϊ˫ȣ
	2.СöΪ޷
*/
Type promote(Type ty) {
	ty = unqual(ty);
	switch (ty->op) {
	case ENUM:
		return inttype;
	case INT:
		if (ty->size < inttype->size)
			return inttype;
		break;
	case UNSIGNED:
		if (ty->size < inttype->size)
			return inttype;
		if (ty->size < unsignedtype->size)
			return unsignedtype;
		break;
	case FLOAT:
		if (ty->size < doubletype->size)
			return doubletype;
	}
	return ty;
}
// TODO
Type compose(Type ty1, Type ty2) {
	if (ty1 == ty2)
		return ty1;
	assert(ty1->op == ty2->op);
	switch (ty1->op) {
	case POINTER:
		return ptr(compose(ty1->type, ty2->type));
	case CONST+VOLATILE:
		return qual(CONST, qual(VOLATILE, compose(ty1->type, ty2->type)));
	case CONST:case VOLATILE:
		return qual(ty1->op, compose(ty1->type, ty2->type));
	case ARRAY:
		Type ty = compose(ty1->type, ty2->type);
		if (ty1->size
			&& (ty1->type->size&&ty2->size == 0 || ty1->size == ty2->size))
			return array(ty, ty1->size / ty1->type->size, ty1->align);
		if (ty2->size
			&&ty2->type->size&&ty1->size == 0)
			return array(ty, ty2->size / ty2->type->size, ty2->align);
		return array(ty, 0, 0);
	case FUNCTION:
		Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto;
		List tlist = NULL;
		if (p1 == NULL&p2 == NULL)
			return func(ty, NULL, 1);
	}
	

	assert(0);
	return NULL;
}
Type btot(int op, int size) {
#define xx(ty) if(size==(ty)->size) return ty;
#undef xx
	return 0;
}
/**
 * typetypetableָͻߴһµ͡
 * typeΪͺͲȫʹ͡
 * ʱtypeʼָx
 * ͼӦĹϣУµ͡
 * ------------------------------------------------
 * typetypetableʱͲͲֵַΪϣֵ
 * ӦĹϣѰҾͬСֽͷűڵ͡
 */
static Type type(int op, Type ty, int size, int align, void *sym) {
	unsigned h = (op ^ ((unsigned long)ty >> 3))&(NELEMS(typetable) - 1);
	struct entry *tn;
	if (op != FUNCTION && (op != ARRAY || size > 0))
		for (tn = typetable[h]; tn; tn = tn->link)
			if (tn->type.op == op&&tn->type.type == ty
				&&tn->type.size == size&&tn->type.align == align
				&&tn->type.u.sym == sym)
				return &tn->type;
	tn = (struct entry*) memset(allocate(sizeof*(tn), PERM), 0, sizeof*(tn));
	tn->type.op = op;
{'fraction_non_alphanumeric': 0.19142317520275526, 'fraction_numerical': 0.028996778135762694, 'mean_word_length': 2.896969696969697, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 147, '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': '6452803', 'n_tokens_mistral': 4931, 'n_tokens_neox': 4467, 'n_words': 894}