/* Runner File - Compiles alpha Compiler */ /* The Translators - Spring 2025 */ #include "runner.h" int main(int argc, char *argv[]) { if (argc == 1) { fprintf(stderr, INVALID); return -1; } else if (argc == 2) { if (is_help(argv[1])) { return 0; } else if (is_alpha_file(argv[1], strlen(argv[1])) == 0) { no_flag = SET_FLAG; alpha_file = fopen(argv[1], "r"); } else { fprintf(stderr, INVALID); return -1; } } else { if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) { fprintf(stderr, INVALID); return -1; } else { for (int i = 1; i < argc - 1; i++) { if (check_flag(argv[i], argv[argc - 1]) != 0) { fprintf(stderr, INVALID); return -1; } } alpha_file = fopen(argv[argc - 1], "r"); } } return run(alpha_file); } int check_flag(char *arg, char *alpha) { if (strcmp("-tok", arg) == 0) { if (tok_flag == NULL) { return new_file(arg, alpha); } fprintf(stderr, "FLAGS REPEAT\n"); return -1; } else if (strcmp("-st", arg) == 0) { if (st_flag == NULL) { return new_file(arg, alpha); } fprintf(stderr, "FLAGS REPEAT\n"); return -1; } else if (strcmp("-asc", arg) == 0) { if (asc_flag == NULL) { return new_file(arg, alpha); } fprintf(stderr, "FLAGS REPEAT\n"); return -1; } else if (strcmp("-tc", arg) == 0) { if (tc_flag == false) { tc_flag = true; return 0; } fprintf(stderr, "FLAGS REPEAT\n"); return -1; } else if (strcmp("-ir", arg) == 0) { if (ir_flag == NULL) { return new_file(arg, alpha); } fprintf(stderr, "FLAGS REPEAT\n"); return -1; } else if (strcmp("-cg", arg) == 0) { if (cg_flag == NULL) { return new_file(arg, alpha); } fprintf(stderr, "FLAGS REPEAT\n"); return -1; } else if (strcmp("-debug", arg) == 0) { DEBUG = true; return 0; } else { fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n"); return -1; } } void incr(int lnum, int cnum, int tok) { for (int i = 0; i < yyleng; i++) { if (yytext[i] == '\n') { line_number++; column_number = 0; } column_number++; } } void print_tok(int tok) { fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok, yytext); } int run(FILE *alpha) { int token; top = cur = init(CreateScope(NULL, 1, 1)); // If file is not found if (alpha == NULL) { fprintf(stderr, "INPUT FILE NOT FOUND\n"); return -1; } char *line; int i = 1; while ((line = file_read_line(alpha)) != NULL) { CodeLine *code_line = malloc(sizeof(CodeLine)); code_line->line_number = i; code_line->line = malloc(strlen(line) + 1); strcpy(code_line->line, line); code_line->next = NULL; code_line->is_error = false; append_code_line(code_line); free(line); i++; } fseek(alpha, 0, SEEK_SET); yyin = alpha; stack = S_Init(); TrueList = S_Init(); FalseList = S_Init(); yyparse(); if (tok_flag != NULL) { while (0 != (token = yylex())) { // Don't delete me 🥺 } fclose(tok_flag); } if (st_flag != NULL) { printdebug("[-st] Symbol Table is enabled."); print_symbol_table(top, st_flag); fclose(st_flag); } if (asc_flag != NULL) { printdebug("[-asc] Annotated Source Code is enabled."); print_code_lines(); fclose(asc_flag); } if (tc_flag != false) { printdebug("[-tc] Type checking is enabled."); } if (ir_flag != NULL) { printdebug("[-ir] Intermediate code is enabled."); emit_as_file(ir_flag, begin); fclose(ir_flag); } if (cg_flag != NULL) { printdebug("[-cg] Code generation is enabled."); generate(); fclose(cg_flag); } if (yyin != NULL) { fclose(yyin); } return 0; } bool is_help(char *input) { if (strcmp(input, "-help") == 0) { printf("%s", HELP); return true; } return false; } int new_file(char *arg, char *alpha) { int type_len; const char *basename = alpha; const char *slash = strchr(alpha, '/'); while (slash != NULL) { basename = slash + 1; slash = strchr(basename, '/'); } mkdir("./out", 0777); char *new_basename = calloc(strlen(basename) + 7, sizeof(char)); strcpy(new_basename, "./out/"); strcat(new_basename, basename); basename = new_basename; if (strcmp(arg, "-tok") == 0) { type_len = TOK_LEN; } else if (strcmp(arg, "-st") == 0) { type_len = ST_LEN; } else if (strcmp(arg, "-asc") == 0) { type_len = ASC_LEN; } else if (strcmp(arg, "-ir") == 0) { type_len = IR_LEN; } else if (strcmp(arg, "-cg") == 0) { type_len = CG_LEN; } else { fprintf(stderr, INVALID); return -1; } // calculate lengths int basename_len = strlen(basename); char *file_name = calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); // coy filename and add extension if (strcmp(arg, "-cg") == 0) { strncpy(file_name, basename, basename_len - ALPHA_OFFSET); strcat(file_name, ".s"); } else { strncpy(file_name, basename, basename_len - ALPHA_OFFSET); strcat(file_name, "."); strcat(file_name, arg + 1); } if (strcmp(arg, "-tok") == 0) { tok_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-st") == 0) { st_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-asc") == 0) { asc_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-ir") == 0) { ir_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-cg") == 0) { cg_flag = fopen(file_name, "w"); } return 0; } int is_alpha_file(char *alpha, int file_len) { if (strcmp(".alpha", alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) { return -1; // not alpha file } return 0; // is alpha file } void insert_code_line(char *error_message, int line_number) { CodeLine *error_line = malloc(sizeof(CodeLine)); error_line->line_number = line_number; error_line->line = malloc(strlen(error_message) + 1); strcpy(error_line->line, error_message); error_line->next = NULL; error_line->is_error = true; if (error_line == NULL || code_head == NULL) return; int line = error_line->line_number; CodeLine *current = code_head; while (current != NULL) { if (current->line_number == line) { if (current->is_error == false) { CodeLine *next_code_line = current->next; current->next = error_line; error_line->next = next_code_line; } } current = current->next; } } void append_code_line(CodeLine *code_line) { if (code_line == NULL) return; if (code_head == NULL) { code_head = code_line; } else { CodeLine *current = code_head; while (current->next != NULL) { current = current->next; } current->next = code_line; } } void print_code_lines() { if (code_head == NULL) { printf("No code lines to print.\n"); return; } CodeLine *current = code_head; while (current != NULL) { if (current->is_error) { fprintf(asc_flag, "%s", current->line); } else { fprintf(asc_flag, "%03d: %s", current->line_number, current->line); } current = current->next; } } char *file_read_line(FILE *fp) { if (fp == NULL) return NULL; size_t size = 128; size_t len = 0; char *str = malloc(size); if (!str) return NULL; int c; while ((c = fgetc(fp)) != EOF) { if (len + 1 >= size) { size *= 2; char *new_buffer = realloc(str, size); if (!new_buffer) { free(str); return NULL; } str = new_buffer; } str[len++] = (char)c; if (c == '\n') break; } if (len == 0 && c == EOF) { free(str); return NULL; } str[len] = '\0'; return str; }