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