#include #include #include #include #include "ast.h" #include "parse.h" ast ast_parse(const char* source, const uint32_t len, int* err) { uint32_t estimated_token_count = len / 8; tokenizer_tag* token_tags = NULL; ast_index* token_starts = NULL; ast_node_tag* nodes_tags = NULL; ast_token_index* main_tokens = NULL; ast_data* nodes_datas = NULL; ast_node_index* extra_data_arr = NULL; ast_node_index* scratch_arr = NULL; if (!(token_tags = calloc(estimated_token_count, sizeof(tokenizer_tag)))) goto err; if (!(token_starts = calloc(estimated_token_count, sizeof(ast_index)))) goto err; tokenizer tok = tokenizer_init(source, len); uint32_t tokens_len = 0; for (; tokens_len <= estimated_token_count; tokens_len++) { if (tokens_len == estimated_token_count) { fprintf(stderr, "too many tokens, bump estimated_token_count\n"); goto err; } tokenizer_token token = tokenizer_next(&tok); token_tags[tokens_len] = token.tag; token_starts[tokens_len] = token.loc.start; } uint32_t estimated_node_count = (tokens_len + 2) / 2; if (!(nodes_tags = calloc(estimated_node_count, sizeof(ast_node_tag)))) goto err; if (!(main_tokens = calloc(estimated_node_count, sizeof(ast_token_index)))) goto err; if (!(nodes_datas = calloc(estimated_node_count, sizeof(ast_data)))) goto err; if (!(extra_data_arr = calloc(16, sizeof(ast_token_index)))) goto err; if (!(scratch_arr = calloc(16, sizeof(ast_token_index)))) goto err; parser p = (parser) { .source = source, .source_len = len, .token_tags = token_tags, .token_starts = token_starts, .tokens_len = tokens_len, .tok_i = 0, .nodes = (ast_node_list) { .len = 0, .cap = estimated_node_count, .tags = nodes_tags, .main_tokens = main_tokens, .datas = nodes_datas, }, .extra_data = (parser_node_index_slice) { .len = 0, .cap = 16, .arr = extra_data_arr }, .scratch = (parser_node_index_slice) { .len = 0, .cap = 16, .arr = scratch_arr }, }; free(scratch_arr); // TODO work return (ast) { .source = source, .tokens.tags = token_tags, .tokens.starts = token_starts, .nodes = p.nodes, .extra_data = p.extra_data.arr, .extra_data_len = p.extra_data.len, }; err: free(token_tags); free(token_starts); free(nodes_tags); free(main_tokens); free(nodes_datas); free(extra_data_arr); free(scratch_arr); *err = 1; return (ast) {}; }