<commit_before>#include <assert.h>
#include <stddef.h>
#include <string.h>

#include "sizes.h"
#include "cc.h"
#include "tokens.h"
#include "syntax.h"
#include "symbol.h"

char parser_out_home;

static struct symbol *cursym;
static void declarator(struct ctype *tp);

static void
newiden(struct ctype *tp)
{
	register unsigned char yyns, ns;

	ns = tp->c_typedef ? NS_TYPEDEF : NS_IDEN;
	yyns = yyval.sym->ns;

	if (yyns == NS_ANY) {     /* First appearence of the symbol */
		yyval.sym->ns = ns;
		cursym = yyval.sym;
		return;
	} else if (ns == yyns) {  /* Duplicated symbol */
		if (yyval.sym->ctx == curctx)
			error("redeclaration of '%s'", yytext);
	}
	cursym = lookup(yytext, ns);
}

static void
dirdcl(register struct ctype *tp)
{
	if (accept('(')) {
		declarator(tp);
		expect(')');
	} else if (yytoken == IDEN) {
		newiden(tp);
		next();
	} else {
		error("expected '(' or identifier before of '%s'", yytext);
	}

	for (;;) {
		if (accept('(')) {
			next();
			pushtype(FTN);
			if (accept(')'))
				; /* TODO: k&r function */
			else
				/* TODO: prototyped function */;
			continue;
		} else if (accept('[')) {
			unsigned len;

			if (accept(']')) {
				len = 0;
			} else {
				expect(CONSTANT);
				len = yyval.sym->val;
				expect(']');
			}
			pushtype(len);
			pushtype(ARY);
			continue;
		} else {
			return;
		}
	}
}

struct ctype *
spec(void)
{
	register struct ctype *tp = NULL;

	for (;; next()) {
		switch (yytoken) {
		case TYPEDEF:  case EXTERN: case STATIC: case AUTO:
		case REGISTER: case CONST:  case VOLATILE:
			tp = storage(tp, yytoken);
			break;
		case UNSIGNED: case SIGNED:
		case FLOAT:    case DOUBLE: case BOOL:
		case VOID:     case CHAR:   case SHORT:
		case INT:      case ENUM:   case LONG:
		case STRUCT:   case UNION:
			tp = btype(tp, yytoken);
			break;
			/* TODO: ENUM, STRUCT, UNION */
		case IDEN:
			if (!tp || !tp->type) {
				struct symbol *sym;
				unsigned char tok = ahead();

				sym = (yyval.sym->ns == NS_TYPEDEF) ?
					yyval.sym : find(yytext, NS_TYPEDEF);
				if (sym && tok != ';' && tok != ',') {
					if (!tp)
						tp = newctype();
					tp->type = TYPEDEF;<commit_msg>Add namespace function<commit_after>#include <assert.h>
#include <stddef.h>
#include <string.h>

#include "sizes.h"
#include "cc.h"
#include "tokens.h"
#include "syntax.h"
#include "symbol.h"

char parser_out_home;

static struct symbol *cursym;
static void declarator(struct ctype *tp);

static struct symbol *
namespace(register unsigned char ns, unsigned char alloc)
{
	register struct symbol *sym = yyval.sym;
	unsigned char yyns = sym->ns;

	if (!alloc) {
		if (yyns == NS_ANY)
			return NULL;
		else if (yyns == ns)
			return sym;
		else
			return find(yytext, ns);
	} else {
		if (yyns == NS_ANY) {
			sym->ns = ns;
			return sym;
		} else if (yyns == ns && sym->ctx == curctx) {
			error("redeclaration of '%s'", yytext);
		}
		return lookup(yytext, ns);
	}
}

static void
dirdcl(register struct ctype *tp)
{
	if (accept('(')) {
		declarator(tp);
		expect(')');
	} else if (yytoken == IDEN) {
		cursym = namespace(tp->c_typedef ? NS_TYPEDEF : NS_IDEN, 1);
		next();
	} else {
		error("expected '(' or identifier before of '%s'", yytext);
	}

	for (;;) {
		if (accept('(')) {
			next();
			pushtype(FTN);
			if (accept(')'))
				; /* TODO: k&r function */
			else
				/* TODO: prototyped function */;
			continue;
		} else if (accept('[')) {
			unsigned len;

			if (accept(']')) {
				len = 0;
			} else {
				expect(CONSTANT);
				len = yyval.sym->val;
				expect(']');
			}
			pushtype(len);
			pushtype(ARY);
			continue;
		} else {
			return;
		}
	}
}

struct ctype *
spec(void)
{
	register struct ctype *tp = NULL;

	for (;; next()) {
		switch (yytoken) {
		case TYPEDEF:  case EXTERN: case STATIC: case AUTO:
		case REGISTER: case CONST:  case VOLATILE:
			tp = storage(tp, yytoken);
			break;
		case UNSIGNED: case SIGNED:
		case FLOAT:    case DOUBLE: case BOOL:
		case VOID:     case CHAR:   case SHORT:
		case INT:      case ENUM:   case LONG:
		case STRUCT:   case UNION:
			tp = btype(tp, yytoken);
			break;
			/* TODO: ENUM, STRUCT, UNION */
		case IDEN:
			if (!tp || !tp->type) {
				struct symbol *sym;
				unsigned char tok = ahead();

				sym = namespace(NS_TYPEDEF, 0);
				if (sym && tok != ';' && tok != ',') {
					if (!tp)
						tp = newctype();
					tp->type = TYPEDEF;
{'fraction_non_alphanumeric': 0.16708919105784742, 'fraction_numerical': 0.0009218713989398478, 'mean_word_length': 2.916967509025271, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 24, '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': '6279114', 'n_tokens_mistral': 1934, 'n_tokens_neox': 1706, 'n_words': 458}