#ifndef PROGRAM_C #define PROGRAM_C #include struct Source* extract_source(char *src_name) { FILE *file; struct Source *ret; file=fopen(src_name,"r"); if(file==NULL) return NULL; if(fseek(file,0L,SEEK_END)!=0) return NULL; 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; for(i=0;itarget=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],"-o",sizeof("-o")) || !strncmp(argv[i],"--output",sizeof("--output"))) { if(++ioutput_name=argv[i]; else if(!ret->is_quiet) { fprintf(stderr,"Error: Output filename is too long"); exit(1); }else { 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"); 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