Skip to content

Commit 2fb745d

Browse files
committed
feat: add index field to repeat blocks to name loop index
Signed-off-by: Louis Mandel <[email protected]>
1 parent 3724dfa commit 2fb745d

File tree

7 files changed

+65
-2
lines changed

7 files changed

+65
-2
lines changed

pdl-live-react/src/pdl_ast.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,11 @@ export type Kind10 = "repeat"
14831483
export type For = {
14841484
[k: string]: LocalizedExpression | unknown[] | string
14851485
} | null
1486+
/**
1487+
* Name of the variable containing the loop iteration.
1488+
*
1489+
*/
1490+
export type Index = string | null
14861491
/**
14871492
* Condition to stay at the beginning of the loop.
14881493
*
@@ -3834,6 +3839,16 @@ export interface Defs9 {
38343839
* repeat:
38353840
* "${ name }'s number is ${ number }\n"
38363841
* ```
3842+
*
3843+
* Bounded loop:
3844+
* ```PDL
3845+
* index: i
3846+
* max_iterations: 5
3847+
* repeat:
3848+
* ${ i }
3849+
* join:
3850+
* as: array
3851+
* ```
38373852
*/
38383853
export interface RepeatBlock {
38393854
description?: Description10
@@ -3873,6 +3888,7 @@ export interface RepeatBlock {
38733888
context?: IndependentEnum5
38743889
kind?: Kind10
38753890
for?: For
3891+
index?: Index
38763892
while?: While
38773893
repeat: Repeat
38783894
until?: Until

pdl-live-react/src/pdl_code_cleanup.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ function clean_repeat_block(block: RepeatBlock) {
123123
if (block.for === null) {
124124
delete block.for
125125
}
126+
if (block.index === null) {
127+
delete block.index
128+
}
126129
if (block.while === true) {
127130
delete block.while
128131
}

src/pdl/pdl-schema.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10642,7 +10642,7 @@
1064210642
},
1064310643
"RepeatBlock": {
1064410644
"additionalProperties": false,
10645-
"description": "Repeat the execution of a block.\n\nFor loop example:\n```PDL\nfor:\n number: [1, 2, 3, 4]\n name: [\"Bob\", \"Carol\", \"David\", \"Ernest\"]\nrepeat:\n \"${ name }'s number is ${ number }\\n\"\n```",
10645+
"description": "Repeat the execution of a block.\n\nFor loop example:\n```PDL\nfor:\n number: [1, 2, 3, 4]\n name: [\"Bob\", \"Carol\", \"David\", \"Ernest\"]\nrepeat:\n \"${ name }'s number is ${ number }\\n\"\n```\n\nBounded loop:\n```PDL\nindex: i\nmax_iterations: 5\nrepeat:\n ${ i }\njoin:\n as: array\n```",
1064610646
"properties": {
1064710647
"description": {
1064810648
"anyOf": [
@@ -11042,6 +11042,19 @@
1104211042
"description": "Arrays to iterate over.\n ",
1104311043
"title": "For"
1104411044
},
11045+
"index": {
11046+
"anyOf": [
11047+
{
11048+
"type": "string"
11049+
},
11050+
{
11051+
"type": "null"
11052+
}
11053+
],
11054+
"default": null,
11055+
"description": "Name of the variable containing the loop iteration.\n ",
11056+
"title": "Index"
11057+
},
1104511058
"while": {
1104611059
"anyOf": [
1104711060
{

src/pdl/pdl_ast.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,12 +872,25 @@ class RepeatBlock(StructuredBlock):
872872
repeat:
873873
"${ name }'s number is ${ number }\\n"
874874
```
875+
876+
Bounded loop:
877+
```PDL
878+
index: i
879+
max_iterations: 5
880+
repeat:
881+
${ i }
882+
join:
883+
as: array
884+
```
875885
"""
876886

877887
kind: Literal[BlockKind.REPEAT] = BlockKind.REPEAT
878888
for_: Optional[dict[str, ExpressionType[list]]] = Field(default=None, alias="for")
879889
"""Arrays to iterate over.
880890
"""
891+
index: Optional[str] = None
892+
"""Name of the variable containing the loop iteration.
893+
"""
881894
while_: ExpressionType[bool] = Field(default=True, alias="while")
882895
"""Condition to stay at the beginning of the loop.
883896
"""

src/pdl/pdl_dumper.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ def block_to_dict( # noqa: C901
231231
case RepeatBlock():
232232
if block.for_ is not None:
233233
d["for"] = expr_to_dict(block.for_, json_compatible)
234+
if block.index is not None:
235+
d["index"] = block.index
234236
if block.while_ is not None:
235237
d["while"] = expr_to_dict(block.while_, json_compatible)
236238
d["repeat"] = block_to_dict(block.repeat, json_compatible)

src/pdl/pdl_interpreter.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,8 @@ def process_block_body(
807807
first = True
808808
saved_background: PdlLazy[list[dict[str, Any]]] = PdlList([])
809809
while True:
810+
if block.index is not None:
811+
scope = scope | {block.index: iidx}
810812
if max_iterations is not None and iidx >= max_iterations:
811813
break
812814
if lengths is not None and iidx >= lengths[0]:
@@ -859,8 +861,8 @@ def process_block_body(
859861
results.append(iteration_result)
860862
iter_trace.append(body_trace)
861863
iteration_state = iteration_state.with_pop()
862-
iidx = iidx + 1
863864
stop, _ = process_condition_of(block, "until", scope, loc)
865+
iidx = iidx + 1
864866
if stop:
865867
break
866868
except PDLRuntimeError as exc:

tests/test_repeat.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,20 @@ def test_for_max_iterations2():
174174
assert result == "012"
175175

176176

177+
def _for_max_iterations_index_prog(n):
178+
return f"""
179+
index: i
180+
repeat: {'${i}'}
181+
max_iterations: {'${'}{n}{'}'}
182+
"""
183+
184+
185+
def test_for_max_iterations_index1():
186+
prog = _for_max_iterations_index_prog(10)
187+
result = exec_str(prog)
188+
assert result == "0123456789"
189+
190+
177191
def _for_until_prog(n):
178192
return f"""
179193
for:

0 commit comments

Comments
 (0)