~oriansj/M3-Preprocess

85f3f0ffc68dd6cdd5d674a360e3d9f8122ae91d — Jeremiah Orians 2 years ago e0accc2
A partial heuristic for detecting labels that can break
5 files changed, 134 insertions(+), 10 deletions(-)

M c_stage1.c
M cc_globals.c
M cc_globals.h
M cc_reader.c
M cpp.c
M c_stage1.c => c_stage1.c +98 -2
@@ 43,6 43,7 @@ int pattern_compress(struct token_list* i, struct pattern* p)
	if(NULL == p->next) return TRUE;
	struct token_list* hold = i->next;
	i->next = i->next->next;
	free(hold->s);
	free(hold);
	return TRUE;
}


@@ 50,6 51,7 @@ int pattern_compress(struct token_list* i, struct pattern* p)
void combine_common()
{
	struct token_list* i = global_token;
	struct token_list* hold;

	struct pattern* decrement = new_pattern("-", new_pattern("-", NULL));
	struct pattern* increment = new_pattern("+", new_pattern("+", NULL));


@@ 77,7 79,51 @@ void combine_common()
	{
		if(NULL == i->next) break;

		if(pattern_compress(i, leftassign)) i->s = "<<=";
		if(match(i->s, "#include"))
		{
			i = i->next;
			while(match(" ", i->s))
			{
				i = i->next;
			}
			if(match("<", i->s))
			{
				reset_hold_string();
				strcat(hold_string, "<");
				require(NULL != i->next, "incomplete #include < block>\n");
				strcat(hold_string, i->next->s);
				require(NULL != i->next->next, "incomplete #include <block>\n");
				require(match(i->next->next->s, "."), "not a proper #include <name>\n");
				strcat(hold_string, ".");
				require(NULL != i->next->next->next, "incomplete #include <block>\n");
				strcat(hold_string, i->next->next->next->s);
				require(NULL != i->next->next->next->next, "incomplete #include <block>\n");
				require(match(i->next->next->next->next->s, ">"), "not a properly terminated #include <name>\n");
				strcat(hold_string, ">");
				/* Free up old string */
				free(i->s);
				i->s = calloc(strlen(hold_string)+1, sizeof(char));
				strcpy(i->s, hold_string);
				hold = i->next;
				i->next = i->next->next->next->next->next;

				/* Clean up the bits */
				free(hold->next->next->next->s);
				free(hold->next->next->next);
				free(hold->next->next->s);
				free(hold->next->next);
				free(hold->next->s);
				free(hold->next);
				free(hold->s);
				free(hold);

			}
			else
			{
				i = i->next;
			}
		}
		else if(pattern_compress(i, leftassign)) i->s = "<<=";
		else if(pattern_compress(i, rightassign)) i->s = ">>=";
		else if(pattern_compress(i, decrement)) i->s = "--";
		else if(pattern_compress(i, increment)) i->s = "++";


@@ 100,7 146,55 @@ void combine_common()
		else if(pattern_compress(i, arrow)) i->s = "->";
		else i = i->next;
	}
}

void sort_out_labels()
{
	/* This is just my guess at a heuristic for figuring out the difference between */
	/* label: and Ternary ? conditional : alt */
	/* This will fail if labels are not on their own lines alone */
	struct token_list* i = global_token;
	struct token_list* hold;
	int count;
	struct token_list* maybe = NULL;
	while(NULL != i)
	{
		count = 0;
		require(NULL != i, "hit null while trying to sort out labels\n");
		while(!match(i->s, "\n"))
		{
			if(NULL == i) break;
			if(NULL == i->next) break;
			if(match(i->next->s, ":"))
			{
				maybe = i;
			}
			else if(!match(i->s, " ") && !match(i->s, "\t") && !match(i->s, "\n"))
			{
				count = count + 1;
			}
			i = i->next;
		}
		if(1 == count)
		{
			if(NULL == maybe) continue;
			reset_hold_string();
			strcat(hold_string, maybe->s);
			strcat(hold_string, ":");
			free(maybe->s);
			maybe->s = calloc(strlen(hold_string)+1, sizeof(char));
			strcpy(maybe->s, hold_string);
			hold = maybe->next;
			maybe->next = maybe->next->next;
			free(hold->s);
			free(hold);
		}
		else
		{
			maybe = NULL;
			i = i->next;
		}
	}
}

void stage1_preprocess()


@@ 114,5 208,7 @@ void stage1_preprocess()
	combine_common();
	if(4 == DUMP_STAGE) dump_stage_raw();
	if(5 == DUMP_STAGE) dump_stage_straight();

	sort_out_labels();
	if(6 == DUMP_STAGE) dump_stage_raw();
	if(7 == DUMP_STAGE) dump_stage_straight();
}

M cc_globals.c => cc_globals.c +1 -0
@@ 38,6 38,7 @@ size_t MAX_STRING;

/* enable preprocessor-only mode */
int PREPROCESSOR_MODE;
int C_PREPROCESS;

/* enable spawn behavior to be effective */
char* M2LIBC_PATH;

M cc_globals.h => cc_globals.h +1 -0
@@ 41,6 41,7 @@ extern size_t MAX_STRING;

/* enable preprocessor-only mode */
extern int PREPROCESSOR_MODE;
extern int C_PREPROCESS;

/* enable spawn behavior to be effective */
extern char* M2LIBC_PATH;

M cc_reader.c => cc_reader.c +33 -7
@@ 216,14 216,40 @@ struct token_list* reverse_list(struct token_list* head)

void insert_file_header(char* name, int line)
{
	if(C_PREPROCESS) line = line-1;
	char* hold_line = int2str(line, 10, FALSE);
	reset_hold_string();
	strcat(hold_string, "#FILENAME ");
	strcat(hold_string, name);
	strcat(hold_string, " ");
	strcat(hold_string, hold_line);
	token = new_token(hold_string, strlen(hold_string)+2, name, line, token, token);
	token = new_token("\n", 3, name, line, token, token);

	if(C_PREPROCESS)
	{
		reset_hold_string();
		strcat(hold_string, "# ");
		strcat(hold_string, hold_line);
		if('<' == name[0])
		{
			strcat(hold_string, " ");
			strcat(hold_string, name);
			strcat(hold_string, " ");
		}
		else
		{
			strcat(hold_string, " \"");
			strcat(hold_string, name);
			strcat(hold_string, "\" ");
		}
		strcat(hold_string, " ");
		token = new_token(hold_string, strlen(hold_string)+2, name, line, token, token);
		token = new_token("\n", 3, name, line, token, token);
	}
	else
	{
		reset_hold_string();
		strcat(hold_string, "#FILENAME ");
		strcat(hold_string, name);
		strcat(hold_string, " ");
		strcat(hold_string, hold_line);
		token = new_token(hold_string, strlen(hold_string)+2, name, line, token, token);
		token = new_token("\n", 3, name, line, token, token);
	}
}

struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename)

M cpp.c => cpp.c +1 -1
@@ 142,10 142,10 @@ int main(int argc, char** argv)
	Architecture = NULL;
	DESTINATION_NAME = "/dev/stdout";
	DESTINATION_FILE = stdout;
	C_PREPROCESS = FALSE;
	global_token = NULL;

	/* Our fun locals */
	int C_PREPROCESS = FALSE;
	FILE* in = stdin;
	char* name;
	int follow_includes = TRUE;