#unroll(N) for

This commit is contained in:
gingerBill
2025-01-10 12:14:43 +00:00
parent 4a2b13f1c2
commit 328d893cb5
7 changed files with 339 additions and 77 deletions

View File

@@ -348,10 +348,11 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) {
n->RangeStmt.body = clone_ast(n->RangeStmt.body, f);
break;
case Ast_UnrollRangeStmt:
n->UnrollRangeStmt.val0 = clone_ast(n->UnrollRangeStmt.val0, f);
n->UnrollRangeStmt.val1 = clone_ast(n->UnrollRangeStmt.val1, f);
n->UnrollRangeStmt.expr = clone_ast(n->UnrollRangeStmt.expr, f);
n->UnrollRangeStmt.body = clone_ast(n->UnrollRangeStmt.body, f);
n->UnrollRangeStmt.args = clone_ast_array(n->UnrollRangeStmt.args, f);
n->UnrollRangeStmt.val0 = clone_ast(n->UnrollRangeStmt.val0, f);
n->UnrollRangeStmt.val1 = clone_ast(n->UnrollRangeStmt.val1, f);
n->UnrollRangeStmt.expr = clone_ast(n->UnrollRangeStmt.expr, f);
n->UnrollRangeStmt.body = clone_ast(n->UnrollRangeStmt.body, f);
break;
case Ast_CaseClause:
n->CaseClause.list = clone_ast_array(n->CaseClause.list, f);
@@ -1037,15 +1038,16 @@ gb_internal Ast *ast_range_stmt(AstFile *f, Token token, Slice<Ast *> vals, Toke
return result;
}
gb_internal Ast *ast_unroll_range_stmt(AstFile *f, Token unroll_token, Token for_token, Ast *val0, Ast *val1, Token in_token, Ast *expr, Ast *body) {
gb_internal Ast *ast_unroll_range_stmt(AstFile *f, Token unroll_token, Slice<Ast *> args, Token for_token, Ast *val0, Ast *val1, Token in_token, Ast *expr, Ast *body) {
Ast *result = alloc_ast_node(f, Ast_UnrollRangeStmt);
result->UnrollRangeStmt.unroll_token = unroll_token;
result->UnrollRangeStmt.args = args;
result->UnrollRangeStmt.for_token = for_token;
result->UnrollRangeStmt.val0 = val0;
result->UnrollRangeStmt.val1 = val1;
result->UnrollRangeStmt.in_token = in_token;
result->UnrollRangeStmt.expr = expr;
result->UnrollRangeStmt.body = body;
result->UnrollRangeStmt.val0 = val0;
result->UnrollRangeStmt.val1 = val1;
result->UnrollRangeStmt.in_token = in_token;
result->UnrollRangeStmt.expr = expr;
result->UnrollRangeStmt.body = body;
return result;
}
@@ -5137,6 +5139,40 @@ gb_internal Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, T
gb_internal Ast *parse_unrolled_for_loop(AstFile *f, Token unroll_token) {
Array<Ast *> args = {};
if (allow_token(f, Token_OpenParen)) {
f->expr_level++;
if (f->curr_token.kind == Token_CloseParen) {
syntax_error(f->curr_token, "#unroll expected at least 1 argument, got 0");
} else {
args = array_make<Ast *>(ast_allocator(f));
while (f->curr_token.kind != Token_CloseParen &&
f->curr_token.kind != Token_EOF) {
Ast *arg = nullptr;
arg = parse_value(f);
if (f->curr_token.kind == Token_Eq) {
Token eq = expect_token(f, Token_Eq);
if (arg != nullptr && arg->kind != Ast_Ident) {
syntax_error(arg, "Expected an identifier for 'key=value'");
}
Ast *value = parse_value(f);
arg = ast_field_value(f, arg, value, eq);
}
array_add(&args, arg);
if (!allow_field_separator(f)) {
break;
}
}
}
f->expr_level--;
Token close = expect_closing(f, Token_CloseParen, str_lit("#unroll"));
gb_unused(close);
}
Token for_token = expect_token(f, Token_for);
Ast *val0 = nullptr;
Ast *val1 = nullptr;
@@ -5180,7 +5216,7 @@ gb_internal Ast *parse_unrolled_for_loop(AstFile *f, Token unroll_token) {
if (bad_stmt) {
return ast_bad_stmt(f, unroll_token, f->curr_token);
}
return ast_unroll_range_stmt(f, unroll_token, for_token, val0, val1, in_token, expr, body);
return ast_unroll_range_stmt(f, unroll_token, slice_from_array(args), for_token, val0, val1, in_token, expr, body);
}
gb_internal Ast *parse_stmt(AstFile *f) {