#include #include #include #include #include "ast.h" #include "parser.h" #define N 1024 ast astParse(const char* source, const uint32_t len) { uint32_t estimated_token_count = len / 8; TokenizerTag* token_tags = NULL; AstIndex* token_starts = NULL; AstNodeTag* nodes_tags = NULL; AstTokenIndex* main_tokens = NULL; AstData* nodes_datas = NULL; AstNodeIndex* extra_data_arr = NULL; AstNodeIndex* scratch_arr = NULL; if (!(token_tags = calloc(estimated_token_count, sizeof(TokenizerTag)))) exit(1); if (!(token_starts = calloc(estimated_token_count, sizeof(AstIndex)))) exit(1); Tokenizer tok = tokenizerInit(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"); exit(1); } TokenizerToken token = tokenizerNext(&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(AstNodeTag)))) exit(1); if (!(main_tokens = calloc(estimated_node_count, sizeof(AstTokenIndex)))) exit(1); if (!(nodes_datas = calloc(estimated_node_count, sizeof(AstData)))) exit(1); if (!(extra_data_arr = calloc(N, sizeof(AstNodeIndex)))) exit(1); if (!(scratch_arr = calloc(N, sizeof(AstNodeIndex)))) exit(1); Parser p = (Parser) { .source = source, .source_len = len, .token_tags = token_tags, .token_starts = token_starts, .tokens_len = tokens_len, .tok_i = 0, .nodes = (AstNodeList) { .len = 0, .cap = estimated_node_count, .tags = nodes_tags, .main_tokens = main_tokens, .datas = nodes_datas, }, .extra_data = (ParserNodeIndexSlice) { .len = 0, .cap = N, .arr = extra_data_arr }, .scratch = (ParserNodeIndexSlice) { .len = 0, .cap = N, .arr = scratch_arr }, }; free(scratch_arr); parseRoot(&p); 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, }; }