MEGATRON



LOG | FILES | OVERVIEW


#ifndef PROGRAM_C
#define PROGRAM_C
#include<program.h>

struct Source* extract_source(char *src_name)
{
	FILE *file;

	struct Source *ret;
	
	file=fopen(src_name,"r");
	if(file==NULL)
	{
		fprintf(stderr,"Could not open source file. ");
		exit(1);
	}
	if(fseek(file,0L,SEEK_END)!=0)
	{
		fprintf(stderr,"Could not open source file. ");
		exit(1);
	}

	ret=malloc(sizeof(struct Source));
	ret->src_size=ftell(file);
	ret->where_in_src=0;
	ret->src_name=src_name;
	ret->src=malloc(ret->src_size);
	ret->current_column=0;
	ret->current_row=0;

	fseek(file,0L,SEEK_SET);


	fread(ret->src,sizeof(char),ret->src_size,file);

	fclose(file);
	return ret;
}
struct Options* parse_command_line(int argc,char **argv)
{
	struct Options *ret;
	int i;

	assert(argv!=NULL && argc>0);

	ret=malloc(sizeof(struct Options));
	ret->target=OPTION_DEFAULT;
	ret->src_name=NULL;
	ret->output_name=NULL;
	ret->is_quiet=0;
	ret->providing_own_queue_implementation=0;
	ret->providing_own_buffer_implementation=0;
	ret->has_mutex=0;
	ret->has_context=0; /*inline is the default*/

	for(i=0;i<argc;++i)
	{
		if(!strncmp(argv[i],"--print-tokens",sizeof("--print-tokens")))
			ret->target=OPTION_TARGET_TOKENS;
		else if(!strncmp(argv[i],"--print-ast",sizeof("--print-ast")))
			ret->target=OPTION_TARGET_AST;
		else if(!strncmp(argv[i],"--print-c",sizeof("--print-c")))
			ret->target=OPTION_TARGET_C;
		else if(!strncmp(argv[i],"--extern-queue",sizeof("--extern-queue")))
			ret->providing_own_queue_implementation=1;
		else if(!strncmp(argv[i],"--extern-buffer",sizeof("--extern-buffer")))
			ret->providing_own_buffer_implementation=1;
		else if(!strncmp(argv[i],"--extern-mutex",sizeof("--extern-mutex")))
			ret->has_mutex=1;
		else if(!strncmp(argv[i],"--with-context",sizeof("--extern-mutex")))
			ret->has_context=1;
		else if(!strncmp(argv[i],"--help",sizeof("--help")) || !strncmp(argv[i],"-h",sizeof("-h")))
		{
			printf("Wonky automata options:\n"
				"--print-tokens Prints the tokens of the programs, used for debugging\n"
				"--print-ast Prints the ast of the program, used for debugging\n"
				"--print-c Transpiles to C and outputs the result to stdout ( default )\n"
				"--extern-queue delegates the queue implementation to user\n"
				"--extern-buffer delegates the buffer implementation to the user\n"
				"--extern-mutex delegates the mutex implementation to the user and generates mutex guards\n"
				"--with-context have a context struct, so you can have multiple instances of the automata\n"
				"\n");
				exit(0);
		}
		else if(!strncmp(argv[i],"-o",sizeof("-o")) || !strncmp(argv[i],"--output",sizeof("--output")))
		{
			if(++i<argc)
			{
				if(strnlen(argv[i],101)<100)
					ret->output_name=argv[i];
				else if(!ret->is_quiet)
				{
					fprintf(stderr,"Error: Output filename is too long\n");
					exit(1);
				}else
				{
					exit(1);
				}
			}
		}else if(argv[i][0]=='-')
		{
			fprintf(stderr,"Error: Invalid command line option %s\n",argv[i]);
			exit(1);
		}else if(strnlen(argv[i],101)<100)
		{
			ret->src_name=argv[i];	
		}else if(!ret->is_quiet)
		{
			fprintf(stderr,"Error: Input filename is too long\n");
			exit(1);
		}else
		{
			exit(1);
		}

	}

	if(ret->target==OPTION_DEFAULT)
		ret->target=OPTION_TARGET_C;

	return ret;
}
struct Translation_Data* get_translation_data()
{
	struct Translation_Data *ret;
	ret=malloc(sizeof(struct Translation_Data));
	ret->errors=malloc(sizeof(struct Queue));
	ret->tokens=malloc(sizeof(struct Queue));
	
	Queue_Init(ret->errors);
	Queue_Init(ret->tokens);

	ret->hold_number_of_errors=0;

	return ret;
}
struct Error* get_error(char *message,size_t row,size_t column)
{
	struct Error *ret;
	ret=malloc(sizeof(struct Error));
	ret->message=message;
	ret->row=row+1;
	ret->column=column+1;
}
void push_lexing_error(char *error_message,struct Source *src,struct Translation_Data *translation_data)
{
	Queue_Push(translation_data->errors,get_error(error_message,src->current_row,src->current_column));
}
void push_parsing_error(char *error_message,struct Translation_Data *translation_data)
{
	struct token *error_token;
	error_token=Queue_Pop(translation_data->tokens);
	Queue_Push(translation_data->errors,get_error(error_message,error_token->row,error_token->column));
}
char has_new_errors(struct Translation_Data *translation_data)
{
	if(translation_data->hold_number_of_errors!=translation_data->errors->size)
	{
		translation_data->hold_number_of_errors=translation_data->errors->size;
		return 1;
	}else
	{
		return 0;
	}
}

void delete_translation_data(struct Translation_Data *data)
{
	struct Error *hold_error;
	struct token *hold_token;

	while(data->tokens->size>0)
		delete_token(Queue_Pop(data->tokens));
	free(data->tokens);
	while(data->errors->size>0)
		delete_error(Queue_Pop(data->errors));
	free(data->errors);

	free(data);
}
void delete_source(struct Source *src)
{
	free(src->src_name);
	free(src->src);
	free(src);
}
void delete_options(struct Options *options)
{
	free(options);
}
void delete_error(struct Error *error)
{
	free(error->message);
	free(error);
}
char get_and_check(struct Translation_Data *translation_data,enum Keyword kw)
{
	if( ( (struct token *)translation_data->tokens->first->data)->type==kw)
	{
		delete_token(Queue_Pop(translation_data->tokens));
		return 1;
	}else
	{
		return 0;
	}
}
enum Keyword get_kw(struct Translation_Data *translation_data)
{
	return ( (struct token*)translation_data->tokens->first->data)->type;
}
void chomp(struct Translation_Data *translation_data)
{
	assert(translation_data->tokens->size>0);
	delete_token(Queue_Pop(translation_data->tokens));
}
void touch_errors(struct Translation_Data *translation_data)
{
	assert(translation_data->hold_number_of_errors>0);
	--translation_data->hold_number_of_errors;
}
void push_error_with_token(char *error_message,struct token *token,struct Translation_Data *translation_data)
{
	Queue_Push(translation_data->errors,get_error(error_message,token->row,token->column));
}
#endif