a few bugfixes and a new TODO

This commit is contained in:
2024-12-30 22:36:35 +02:00
parent 2ae1ac885b
commit d551ba3d12
2 changed files with 74 additions and 61 deletions

128
parser.c
View File

@@ -30,14 +30,35 @@ typedef struct {
} payload; } payload;
} SmallSpan; } SmallSpan;
void parseRoot(Parser* p) { static AstSubRange listToSpan(Parser* p, const AstNodeIndex* list, uint32_t count) {
p->nodes.tags[p->nodes.len++] = AST_NODE_TAG_ROOT; SLICE_ENSURE_CAPACITY(AstNodeIndex, &p->extra_data, count);
p->nodes.main_tokens[p->nodes.len] = 0; memcpy(&p->extra_data.arr, list, count * sizeof(AstNodeIndex));
p->extra_data.len += count;
// members root_members = parseContainerMembers(p); return (AstSubRange) {
.start = p->extra_data.len - count,
.end = p->extra_data.len,
};
} }
static AstTokenIndex nextToken(Parser* p) { return p->tok_i++; } typedef struct {
uint32_t len;
AstNodeIndex lhs;
AstNodeIndex rhs;
bool trailing;
} Members;
static AstSubRange membersToSpan(const Members self, Parser* p) {
if (self.len <= 2) {
const AstNodeIndex nodes[] = { self.lhs, self.rhs };
return listToSpan(p, nodes, self.len);
} else {
return (AstSubRange) { .start = self.lhs, .end = self.rhs };
}
}
static AstTokenIndex nextToken(Parser* p) {
return p->tok_i++;
}
static AstTokenIndex eatToken(Parser* p, TokenizerTag tag, bool* ok) { static AstTokenIndex eatToken(Parser* p, TokenizerTag tag, bool* ok) {
if (p->token_tags[p->tok_i] == tag) { if (p->token_tags[p->tok_i] == tag) {
@@ -103,15 +124,6 @@ static AstNodeIndex addExtra(Parser* p, const AstNodeIndex* extra, uint32_t coun
return result; return result;
} }
static AstNodeIndex parseTypeExpr(Parser* p);
static AstNodeIndex expectTypeExpr(Parser* p) {
const AstNodeIndex node = parseTypeExpr(p);
if (node == 0)
exit(1);
return node;
}
static AstNodeIndex parseByteAlign(Parser* p) { static AstNodeIndex parseByteAlign(Parser* p) {
bool ok; bool ok;
eatToken(p, TOKENIZER_TAG_KEYWORD_ALIGN, &ok); eatToken(p, TOKENIZER_TAG_KEYWORD_ALIGN, &ok);
@@ -152,6 +164,8 @@ static AstNodeIndex parseCallconv(Parser* p) {
return 0; // tcc return 0; // tcc
} }
static AstNodeIndex parseTypeExpr(Parser*);
typedef struct { typedef struct {
AstNodeIndex align_expr, value_expr; AstNodeIndex align_expr, value_expr;
} NodeContainerField; } NodeContainerField;
@@ -162,7 +176,7 @@ static AstNodeIndex expectContainerField(Parser* p) {
if (p->token_tags[p->tok_i] == TOKENIZER_TAG_IDENTIFIER && p->token_tags[p->tok_i + 1] == TOKENIZER_TAG_COLON) if (p->token_tags[p->tok_i] == TOKENIZER_TAG_IDENTIFIER && p->token_tags[p->tok_i + 1] == TOKENIZER_TAG_COLON)
p->tok_i += 2; p->tok_i += 2;
const AstNodeIndex type_expr = expectTypeExpr(p); const AstNodeIndex type_expr = parseTypeExpr(p);
const AstNodeIndex align_expr = parseByteAlign(p); const AstNodeIndex align_expr = parseByteAlign(p);
bool ok; bool ok;
eatToken(p, TOKENIZER_TAG_EQUAL, &ok); eatToken(p, TOKENIZER_TAG_EQUAL, &ok);
@@ -291,6 +305,9 @@ static AstNodeIndex parseSuffixExpr(Parser* p) {
fprintf(stderr, "parseSuffixExpr does not support expr with parens\n"); fprintf(stderr, "parseSuffixExpr does not support expr with parens\n");
exit(1); exit(1);
} }
// TODO more work
// const bool comma = p->token_tags[p->tok_i - 2] == TOKENIZER_TAG_COMMA;
return res; return res;
} }
} }
@@ -322,8 +339,9 @@ static AstNodeIndex parseErrorUnionExpr(Parser* p) {
.main_token = bang, .main_token = bang,
.data = { .data = {
.lhs = suffix_expr, .lhs = suffix_expr,
.rhs = expectTypeExpr(p), .rhs = parseTypeExpr(p),
} }); },
});
} }
static AstNodeIndex parseTypeExpr(Parser* p) { static AstNodeIndex parseTypeExpr(Parser* p) {
@@ -536,7 +554,8 @@ static AstNodeIndex parseBlock(Parser* p) {
expectToken(p, TOKENIZER_TAG_R_BRACE, NULL); expectToken(p, TOKENIZER_TAG_R_BRACE, NULL);
const bool semicolon = (p->token_tags[p->tok_i] - 2 == TOKENIZER_TAG_SEMICOLON); const bool semicolon = (p->token_tags[p->tok_i] - 2 == TOKENIZER_TAG_SEMICOLON);
switch (p->scratch.len - scratch_top.old_len) { const uint32_t statements_len = p->scratch.len - scratch_top.old_len;
switch (statements_len) {
case 0: case 0:
return addNode( return addNode(
&p->nodes, &p->nodes,
@@ -571,21 +590,15 @@ static AstNodeIndex parseBlock(Parser* p) {
}, },
}); });
default:; default:;
const uint32_t extra = p->scratch.len - scratch_top.old_len; const AstSubRange span = listToSpan(p, &p->scratch.arr[scratch_top.old_len], statements_len);
SLICE_ENSURE_CAPACITY(AstNodeIndex, &p->scratch, extra);
memcpy(
&p->extra_data.arr[p->extra_data.len],
&p->scratch.arr[scratch_top.old_len],
sizeof(AstNodeIndex) * extra);
p->extra_data.len += extra;
return addNode( return addNode(
&p->nodes, &p->nodes,
(AstNodeItem) { (AstNodeItem) {
.tag = semicolon ? AST_NODE_TAG_BLOCK_SEMICOLON : AST_NODE_TAG_BLOCK, .tag = semicolon ? AST_NODE_TAG_BLOCK_SEMICOLON : AST_NODE_TAG_BLOCK,
.main_token = lbrace, .main_token = lbrace,
.data = { .data = {
.lhs = p->scratch.arr[scratch_top.old_len], .lhs = span.start,
.rhs = p->scratch.arr[p->scratch.len], .rhs = span.end,
}, },
}); });
} }
@@ -748,30 +761,29 @@ void findNextContainerMember(Parser* p) {
} }
static Members parseContainerMembers(Parser* p) { static Members parseContainerMembers(Parser* p) {
const uint32_t scratch_top = p->scratch.len; CleanupScratch scratch_top __attribute__((__cleanup__(cleanupScratch))) = {
// ast_token_index last_field; .scratch = &p->scratch,
.old_len = p->scratch.len,
};
bool ok; bool ok;
while (eatToken(p, TOKENIZER_TAG_CONTAINER_DOC_COMMENT, &ok) && ok) while (eatToken(p, TOKENIZER_TAG_CONTAINER_DOC_COMMENT, &ok), ok)
; ;
FieldState field_state = { .tag = FIELD_STATE_NONE }; FieldState field_state = { .tag = FIELD_STATE_NONE };
bool trailing = false; bool trailing = false;
AstNodeIndex top_level_decl;
while (1) { while (1) {
eatDocComments(p); eatDocComments(p);
switch (p->token_tags[p->tok_i]) { switch (p->token_tags[p->tok_i]) {
case TOKENIZER_TAG_KEYWORD_TEST: case TOKENIZER_TAG_KEYWORD_TEST:
case TOKENIZER_TAG_KEYWORD_COMPTIME: case TOKENIZER_TAG_KEYWORD_COMPTIME:
case TOKENIZER_TAG_KEYWORD_USINGNAMESPACE:; case TOKENIZER_TAG_KEYWORD_USINGNAMESPACE:;
const char* str = tokenizerGetTagString(p->token_tags[p->tok_i]); const char* str = tokenizerGetTagString(p->token_tags[p->tok_i]);
fprintf(stderr, "%s not implemented in parseContainerMembers\n", str); fprintf(stderr, "%s not implemented in parseContainerMembers\n", str);
exit(1); exit(1);
case TOKENIZER_TAG_KEYWORD_PUB: case TOKENIZER_TAG_KEYWORD_PUB: {
p->tok_i++; p->tok_i++;
top_level_decl = expectTopLevelDecl(p); AstNodeIndex top_level_decl = expectTopLevelDecl(p);
if (top_level_decl != 0) { if (top_level_decl != 0) {
if (field_state.tag == FIELD_STATE_SEEN) { if (field_state.tag == FIELD_STATE_SEEN) {
field_state.tag = FIELD_STATE_END; field_state.tag = FIELD_STATE_END;
@@ -779,9 +791,9 @@ static Members parseContainerMembers(Parser* p) {
} }
SLICE_APPEND(AstNodeIndex, &p->scratch, top_level_decl); SLICE_APPEND(AstNodeIndex, &p->scratch, top_level_decl);
} }
trailing = (p->token_tags[p->tok_i - 1] == TOKENIZER_TAG_SEMICOLON); trailing = p->token_tags[p->tok_i - 1] == TOKENIZER_TAG_SEMICOLON;
break; break;
}
case TOKENIZER_TAG_KEYWORD_CONST: case TOKENIZER_TAG_KEYWORD_CONST:
case TOKENIZER_TAG_KEYWORD_VAR: case TOKENIZER_TAG_KEYWORD_VAR:
case TOKENIZER_TAG_KEYWORD_THREADLOCAL: case TOKENIZER_TAG_KEYWORD_THREADLOCAL:
@@ -789,8 +801,8 @@ static Members parseContainerMembers(Parser* p) {
case TOKENIZER_TAG_KEYWORD_EXTERN: case TOKENIZER_TAG_KEYWORD_EXTERN:
case TOKENIZER_TAG_KEYWORD_INLINE: case TOKENIZER_TAG_KEYWORD_INLINE:
case TOKENIZER_TAG_KEYWORD_NOINLINE: case TOKENIZER_TAG_KEYWORD_NOINLINE:
case TOKENIZER_TAG_KEYWORD_FN:; case TOKENIZER_TAG_KEYWORD_FN: {
top_level_decl = expectTopLevelDecl(p); const AstNodeIndex top_level_decl = expectTopLevelDecl(p);
if (top_level_decl != 0) { if (top_level_decl != 0) {
if (field_state.tag == FIELD_STATE_SEEN) { if (field_state.tag == FIELD_STATE_SEEN) {
field_state.tag = FIELD_STATE_END; field_state.tag = FIELD_STATE_END;
@@ -800,6 +812,7 @@ static Members parseContainerMembers(Parser* p) {
} }
trailing = (p->token_tags[p->tok_i - 1] == TOKENIZER_TAG_SEMICOLON); trailing = (p->token_tags[p->tok_i - 1] == TOKENIZER_TAG_SEMICOLON);
break; break;
}
case TOKENIZER_TAG_EOF: case TOKENIZER_TAG_EOF:
case TOKENIZER_TAG_R_BRACE: case TOKENIZER_TAG_R_BRACE:
goto break_loop; goto break_loop;
@@ -826,8 +839,7 @@ static Members parseContainerMembers(Parser* p) {
case TOKENIZER_TAG_EOF: case TOKENIZER_TAG_EOF:
trailing = false; trailing = false;
goto break_loop; goto break_loop;
default: default:;
continue;
} }
findNextContainerMember(p); findNextContainerMember(p);
@@ -837,11 +849,8 @@ static Members parseContainerMembers(Parser* p) {
break_loop:; break_loop:;
const uint32_t scratch_len = p->scratch.len; const uint32_t items_len = p->scratch.len - scratch_top.old_len;
p->scratch.len = scratch_top; switch (items_len) {
const uint32_t n_items = scratch_len - scratch_top;
switch (n_items) {
case 0: case 0:
return (Members) { return (Members) {
.len = 0, .len = 0,
@@ -852,23 +861,34 @@ break_loop:;
case 1: case 1:
return (Members) { return (Members) {
.len = 1, .len = 1,
.lhs = p->scratch.arr[scratch_top], .lhs = p->scratch.arr[scratch_top.old_len],
.rhs = 0, .rhs = 0,
.trailing = trailing, .trailing = trailing,
}; };
case 2: case 2:
return (Members) { return (Members) {
.len = 2, .len = 2,
.lhs = p->scratch.arr[scratch_top], .lhs = p->scratch.arr[scratch_top.old_len],
.rhs = p->scratch.arr[scratch_top + 1], .rhs = p->scratch.arr[scratch_top.old_len + 1],
.trailing = trailing, .trailing = trailing,
}; };
default: default:;
const AstSubRange span = listToSpan(p, &p->scratch.arr[scratch_top.old_len], items_len);
return (Members) { return (Members) {
.len = n_items, .len = items_len,
.lhs = p->scratch.arr[scratch_top], .lhs = span.start,
.rhs = p->scratch.arr[scratch_len], .rhs = span.end,
.trailing = trailing, .trailing = trailing,
}; };
} }
} }
void parseRoot(Parser* p) {
addNode(&p->nodes, (AstNodeItem) { .tag = AST_NODE_TAG_ROOT, .main_token = 0 });
Members root_members = parseContainerMembers(p);
AstSubRange root_decls = membersToSpan(root_members, p);
p->nodes.datas[0].lhs = root_decls.start;
p->nodes.datas[0].rhs = root_decls.end;
}

View File

@@ -7,13 +7,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
typedef struct {
uint32_t len;
AstNodeIndex lhs;
AstNodeIndex rhs;
bool trailing;
} Members;
typedef struct { typedef struct {
const char* source; const char* source;
uint32_t source_len; uint32_t source_len;