/* * Copyright (c) 2025 Quinn Stephens and the OSMORA team. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "lexer.h" #include "log.h" #include "parser.h" #include "parser/ast.h" static const char *src = "int x;void **ptr;\nvoid *alloc();void test();\nint main();\n"; static void print_func(struct ast_node *func) { if (func->ptr_levels > 0) { log_debug("found function \"%.*s\" (returns %d-level pointer to %s)\n", func->name_len, func->name, func->ptr_levels, func->type->name); } else { log_debug("found function \"%.*s\" (returns %s)\n", func->name_len, func->name, func->type->name); } } static void print_var(struct ast_node *var) { if (var->ptr_levels > 0) { log_debug("found variable \"%.*s\" (%d-level pointer to %s)\n", var->name_len, var->name, var->ptr_levels, var->type->name); } else { log_debug("found variable \"%.*s\" (%s)\n", var->name_len, var->name, var->type->name); } } static void print_syms(struct hashmap *syms) { struct list *list; struct ast_node *node; /* Iterate hashmap rows */ for (size_t r = 0; r < syms->row_count; r++) { /* Iterate row entries */ list = &syms->rows[r]; node = (struct ast_node *)list->head; while (node != (struct ast_node *)list) { if (node->kind == NOK_FUNCTION) { print_func(node); } else if (node->kind == NOK_VARIABLE) { print_var(node); } node = (struct ast_node *)node->hashmap_entry.list_entry.next; } } } int main(int argc, char **argv) { struct lexer lexer; struct parser parser; bool success; (void)argc; (void)argv; if (!lexer_init(&lexer, src)) { log_error("failed to initialize lexer\n"); return EXIT_FAILURE; } parser.lexer = &lexer; parser.syms.rows = NULL; success = parser_parse(&parser); if (parser.syms.rows != NULL) { print_syms(&parser.syms); } return success ? EXIT_SUCCESS:EXIT_FAILURE; }