#include #include #include #include #include #include #include #include // Build arguments setup descriptor typedef struct { char *filepath; bool verbose; bool help; } build_args_t; // Print command usage hint void print_usage() { printf("Usage: fzc [flags] \n"); printf("Flags:\n"); printf("\t-v\t--verbose\tdisplay debug information\n"); printf("\t-h\t--help\t\tprint usage hint (which you're looking at)\n"); } // Read the arguments and build `build_args_t` struct build_args_t *getargs(int argc, char **argv) { build_args_t *args = malloc(sizeof(build_args_t)); if (!args) return NULL; args->filepath = NULL; args->verbose = false; args->help = false; size_t args_total = 0; if (argc > 2) { for (int i = 1; i < argc; i++) { if (argv[i][0] != '-') continue; args_total++; if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { args->help = true; } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) { args->verbose = true; } else { printf("Error: unknown argument '%s'\n", argv[i]); return NULL; } } } if (argc - 1 - args_total < 1) { printf("Error: source code file is not specified.\n"); print_usage(); return NULL; } if (argv[argc - 1][0] == '-') { printf("Error: last argument MUST be a path to file.\n"); printf("Write 'fzc --help' to read help\n"); return NULL; } args->filepath = argv[argc - 1]; return args; } int main(int argc, char **argv) { build_args_t *args = getargs(argc, argv); if (args == NULL) return -1; else if (args->help) return 0; if (args->verbose) printf("> analyze\n-> reading file..."); char source[8192]; FILE *fd = fopen(args->filepath, "r"); if (!fd) { printf("Error: failed to open file '%s'\n", args->filepath); return -1; } fseek(fd, 0L, SEEK_END); size_t fsz = ftell(fd); rewind(fd); fread(source, fsz, 1, fd); fclose(fd); if (args->verbose) { printf("ok!\n"); printf("-> tokenizing..."); } fzl_reader_t *rd = fzl_mkreader(source); int result = fzl_read(rd); if (result != 0) { printf("error: %s\n", fzl_reader_geterror()); return -1; } if (args->verbose) printf("ok!\n"); fzl_reader_ll_t *entry = rd->first; if (args->verbose) { printf("--> structure: "); while (entry) { if (entry->token) { if (entry->token->store_value) printf("", entry->token->type, (char *)entry->token->value); else printf("", entry->token->type); } entry = entry->next; } printf("\n"); printf("-> parsing..."); } fzl_parser_t *parser = fzl_mkparser(rd->first); result = fzl_parse(parser); if (result != 0) { printf("Error: %s\n", fzl_parser_geterror()); return -1; } if (args->verbose) { printf("ok!\n"); fzl_debug_print_ast(parser->root); printf("-> walking AST..."); } fzl_walker_t *walker = fzl_mkwalker(parser->root); result = fzl_walk(walker); if (result != 0) { printf("Error: %s\n", fzl_walker_geterror()); return -1; } if (args->verbose) { printf("ok!\n"); printf("--> Constants table:\n"); for (size_t i = 0; i < walker->consts->size; i++) printf("---> %s\n", walker->consts->array[i].as.string.chars); printf("--> Ops:\n"); for (size_t i = 0; i < walker->op_count; i++) printf("---> %lu\n", walker->ops[i]); } free(args); fzl_freereader(rd); fzl_freeparser(parser); fzl_freeast(parser->root); fzl_freewalker(walker); printf("done.\n"); return 0; }