#include #include #include #include #include #include #include #include #include #include char aerrors[256][256]; size_t aerrors_top; char awarnings[256][256]; size_t awarnings_top; char an_problem[256]; fzl_analyzer_t *fzl_mkanalyzer(fzl_node_t *node) { if (!node) return NULL; fzl_analyzer_t *analyzer = malloc(sizeof(fzl_analyzer_t)); if (!analyzer) return NULL; analyzer->root = node; analyzer->warnings_top = 0; analyzer->errors_top = 0; analyzer->symbols_top = 0; analyzer->alloc_names_top = 0; memset(analyzer->errors, 0, sizeof(analyzer->errors)); memset(analyzer->warnings, 0, sizeof(analyzer->warnings)); memset(analyzer->symbols, 0, sizeof(analyzer->symbols)); memset(analyzer->alloc_names, 0, sizeof(analyzer->alloc_names)); memset(aerrors, 0, sizeof(aerrors)); memset(awarnings, 0, sizeof(awarnings)); return analyzer; } bool an_push_error(fzl_analyzer_t *analyzer, fzl_token_t *tok, char *error) { if (analyzer->errors_top >= 256 || !analyzer || !error) return false; size_t ei = aerrors_top++; if (tok != NULL) snprintf(aerrors[ei], sizeof(aerrors[ei]), "'%s':%zu:%zu => %s", tok->filename, tok->ln, tok->cn, error); else snprintf(aerrors[ei], sizeof(aerrors[ei]), " => %s", error); analyzer->errors[analyzer->errors_top++] = aerrors[ei]; return true; } bool an_push_warning(fzl_analyzer_t *analyzer, fzl_token_t *tok, char *warning) { if (analyzer->warnings_top >= 256 || !analyzer || !warning) return false; size_t wi = awarnings_top++; if (tok != NULL) snprintf(awarnings[wi], sizeof(awarnings[wi]), "'%s':%zu:%zu => %s", tok->filename, tok->ln, tok->cn, warning); else snprintf(awarnings[wi], sizeof(awarnings[wi]), " => %s", warning); analyzer->warnings[analyzer->warnings_top++] = awarnings[wi]; return true; } void fzl_analyze(fzl_analyzer_t *analyzer) { if (!analyzer) return; if (an_nest_ctx(analyzer, FZL_AN_CTX_TYPE_UNNECESSARY) == NULL) { an_push_error(analyzer, NULL, "failed to make global context"); return; } fzl_node_t *current = analyzer->root; while (current != NULL) { fzl_an_res_t res = analyze_common(analyzer, current); if (res.error) break; current = current->next; } for (ssize_t i = analyzer->symbols_top; i > 0; i--) an_fin_ctx(analyzer); } void fzl_freeanalyzer(fzl_analyzer_t *analyzer) { if (!analyzer) return; if (analyzer->alloc_names_top > 0) for (ssize_t i = analyzer->alloc_names_top - 1; i >= 0; i--) free(analyzer->alloc_names[i]); memset(analyzer->errors, 0, sizeof(analyzer->errors)); memset(analyzer->warnings, 0, sizeof(analyzer->warnings)); memset(analyzer->symbols, 0, sizeof(analyzer->symbols)); memset(analyzer->alloc_names, 0, sizeof(analyzer->alloc_names)); free(analyzer); }