#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

@@ -432,10 +432,13 @@ Range_Stmt :: struct {
reverse: bool,
}
Inline_Range_Stmt :: struct {
Inline_Range_Stmt :: Unroll_Range_Stmt
Unroll_Range_Stmt :: struct {
using node: Stmt,
label: ^Expr,
inline_pos: tokenizer.Pos,
unroll_pos: tokenizer.Pos,
args: []^Expr,
for_pos: tokenizer.Pos,
val0: ^Expr,
val1: ^Expr,

View File

@@ -242,8 +242,9 @@ clone_node :: proc(node: ^Node) -> ^Node {
r.vals = clone(r.vals)
r.expr = clone(r.expr)
r.body = clone(r.body)
case ^Inline_Range_Stmt:
case ^Unroll_Range_Stmt:
r.label = clone(r.label)
r.args = clone(r.args)
r.val0 = clone(r.val0)
r.val1 = clone(r.val1)
r.expr = clone(r.expr)

View File

@@ -1262,11 +1262,49 @@ parse_foreign_decl :: proc(p: ^Parser) -> ^ast.Decl {
parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast.Stmt {
for_tok := expect_token(p, .For)
val0, val1: ^ast.Expr
in_tok: tokenizer.Token
expr: ^ast.Expr
body: ^ast.Stmt
args: [dynamic]^ast.Expr
if allow_token(p, .Open_Paren) {
p.expr_level += 1
if p.curr_tok.kind == .Close_Paren {
error(p, p.curr_tok.pos, "#unroll expected at least 1 argument, got 0")
} else {
args = make([dynamic]^ast.Expr)
for p.curr_tok.kind != .Close_Paren &&
p.curr_tok.kind != .EOF {
arg := parse_value(p)
if p.curr_tok.kind == .Eq {
eq := expect_token(p, .Eq)
if arg != nil {
if _, ok := arg.derived.(^ast.Ident); !ok {
error(p, arg.pos, "expected an identifier for 'key=value'")
}
}
value := parse_value(p)
fv := ast.new(ast.Field_Value, arg.pos, value)
fv.field = arg
fv.sep = eq.pos
fv.value = value
arg = fv
}
append(&args, arg)
allow_token(p, .Comma) or_break
}
}
p.expr_level -= 1
_ = expect_token_after(p, .Close_Paren, "#unroll")
}
for_tok := expect_token(p, .For)
bad_stmt := false
@@ -1309,7 +1347,8 @@ parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast
}
range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body)
range_stmt.inline_pos = inline_tok.pos
range_stmt.unroll_pos = inline_tok.pos
range_stmt.args = args[:]
range_stmt.for_pos = for_tok.pos
range_stmt.val0 = val0
range_stmt.val1 = val1