Files
zig0/ast.c
2024-12-22 22:31:16 +02:00

89 lines
2.5 KiB
C

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#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,
};
}