Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7455aa4

Browse files
authored
feat: add index field to repeat blocks to name loop index (#950)
Signed-off-by: Louis Mandel <[email protected]>
1 parent 4b15d82 commit 7455aa4

File tree

12 files changed

+86
-9
lines changed

12 files changed

+86
-9
lines changed

docs/tutorial.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ This results in the following output:
794794
{"Bob": 1, "Carol": 2, "David": 3, "Ernest": 4}
795795
```
796796

797-
### While Loop
797+
### Other loops
798798

799799
The following example shows a while loop in PDL:
800800

@@ -804,8 +804,14 @@ The following example shows a while loop in PDL:
804804

805805
The `while` field indicates the looping condition and `repeat` contains the body of the loop.
806806

807-
Notice that `for`, `while`, `until`, and `maxIterations` can all be combined in the same `repeat` block. The loop exits
808-
as soon as one of the exit conditions is satisfied:
807+
This loop can be rewritten using `max_iterations` to bound the number of iterations and `index` to name the iteration number.
808+
809+
```yaml
810+
--8<-- "./examples/tutorial/loop_index.pdl"
811+
```
812+
813+
814+
Notice that `for`, `while`, `until`, and `max_iterations` can all be combined in the same `repeat` block. The loop exits as soon as one of the exit conditions is satisfied:
809815

810816
```yaml
811817
--8<-- "./examples/tutorial/repeat.pdl"

examples/tutorial/loop_index.pdl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
index: i
2+
repeat:
3+
text: ${i + 1}
4+
max_iterations: 3

examples/tutorial/repeat.pdl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
description: repeat loop with multiple conditions
22
defs:
33
numbers:
4-
data: [1, 2, 3, 4]
4+
data: [42, 2, 4012, 27]
55
names:
66
data: ["Bob", "Carol", "David", "Ernest"]
77
for:
88
number: ${ numbers }
99
name: ${ names }
10+
index: i
1011
repeat:
11-
"${ name }'s number is ${ number }\n"
12+
"${i}: ${ name }'s number is ${ number }\n"
1213
until: ${ name == "Carol"}
13-
max_iterations: 1
14+
max_iterations: 3

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:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
123

0 commit comments

Comments
 (0)