Skip to content

Commit

Permalink
Merge pull request #1604 from DanielXMoore/for-join
Browse files Browse the repository at this point in the history
`for join` reduction to concatenate strings
  • Loading branch information
edemaine authored Nov 16, 2024
2 parents c5a374e + 1d7da23 commit f705f79
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 5 deletions.
10 changes: 9 additions & 1 deletion civet.dev/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,7 @@ numEven := for count item of array
numKeys := for count key in object
</Playground>
`for sum` adds up the body values with `+`.
`for sum` adds up the body values with `+`, starting from `0`.
If there is no body, it adds the item being looped over.
<Playground>
Expand All @@ -1962,6 +1962,14 @@ min := for min item of array
max := for max item of array
</Playground>
`for join` concatenates the body values as strings, using `+`.
It's like `for sum` but starting from `""` instead of `0`.
<Playground>
all := for join item of array
`[${item.type}] ${item.title}`
</Playground>
### Object Comprehensions
Loops can also accumulate their body values into an object.
Expand Down
2 changes: 1 addition & 1 deletion source/parser.hera
Original file line number Diff line number Diff line change
Expand Up @@ -4767,7 +4767,7 @@ ForStatementControlWithReduction
return { ...control, reduction }

ForReduction
( "some" / "every" / "count" / "sum" / "product" / "min" / "max" ):subtype NonIdContinue __:ws ->
( "some" / "every" / "count" / "sum" / "product" / "min" / "max" / "join" ):subtype NonIdContinue __:ws ->
return {
type: "ForReduction",
subtype,
Expand Down
3 changes: 2 additions & 1 deletion source/parser/function.civet
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ function iterationDeclaration(statement: IterationStatement | ForStatement)
when "min" then "Infinity"
when "max" then "-Infinity"
when "product" then "1"
when "join" then '""'
else "0"
else if statement.object
declaration.children.push "={}"
Expand Down Expand Up @@ -696,7 +697,7 @@ function iterationDeclaration(statement: IterationStatement | ForStatement)
resultsRef, " = false; break}" ]
when "count"
[ "if (", node, ") ++", resultsRef ]
when "sum" then [ resultsRef, " += ", node ]
when "sum", "join" then [ resultsRef, " += ", node ]
when "product" then [ resultsRef, " *= ", node ]
when "min" then [ resultsRef, " = Math.min(", resultsRef, ", ", node, ")" ]
when "max" then [ resultsRef, " = Math.max(", resultsRef, ", ", node, ")" ]
Expand Down
2 changes: 1 addition & 1 deletion source/parser/types.civet
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ export type ForDeclaration

export type ForReduction
type: "ForReduction"
subtype: "some" | "every" | "count" | "sum" | "product" | "min" | "max"
subtype: "some" | "every" | "count" | "sum" | "product" | "min" | "max" | "join"

export type SwitchStatement
type: "SwitchStatement"
Expand Down
19 changes: 18 additions & 1 deletion test/for.civet
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,7 @@ describe "for", ->
z = for product of y
z = for min of y
z = for max of y
z = for join of y
---
const results=[];for (const some of y) {results.push(some)};z = results
const results1=[];for (const every of y) {results1.push(every)};z = results1
Expand All @@ -1290,6 +1291,7 @@ describe "for", ->
const results4=[];for (const product of y) {results4.push(product)};z = results4
const results5=[];for (const min of y) {results5.push(min)};z = results5
const results6=[];for (const max of y) {results6.push(max)};z = results6
const results7=[];for (const join of y) {results7.push(join)};z = results7
"""

testCase """
Expand All @@ -1302,6 +1304,7 @@ describe "for", ->
z = for product x of y
z = for min x of y
z = for max x of y
z = for join x of y
---
let results=false;for (const x of y) {results = true; break};z = results
let results1=true;for (const x of y) {results1 = false; break};z = results1
Expand All @@ -1310,6 +1313,7 @@ describe "for", ->
let results4=1;for (const x of y) {results4 *= x};z = results4
let results5=Infinity;for (const x of y) {results5 = Math.min(results5, x)};z = results5
let results6=-Infinity;for (const x of y) {results6 = Math.max(results6, x)};z = results6
let results7="";for (const x of y) {results7 += x};z = results7
"""

testCase """
Expand All @@ -1329,6 +1333,8 @@ describe "for", ->
f x
z = for max x of y
f x
z = for join x of y
f x
---
let results=false;for (const x of y) {
if (f(x)) {results = true; break}
Expand All @@ -1351,6 +1357,9 @@ describe "for", ->
let results6=-Infinity;for (const x of y) {
results6 = Math.max(results6, f(x))
};z = results6
let results7="";for (const x of y) {
results7 += f(x)
};z = results7
"""

testCase """
Expand All @@ -1363,6 +1372,7 @@ describe "for", ->
z or for product x of y
z or for min x of y
z or for max x of y
z or for join x of y
---
z || (()=>{let results=false;for (const x of y) {results = true; break}return results})()
z || (()=>{let results1=true;for (const x of y) {results1 = false; break}return results1})()
Expand All @@ -1371,6 +1381,7 @@ describe "for", ->
z || (()=>{let results4=1;for (const x of y) {results4 *= x}return results4})()
z || (()=>{let results5=Infinity;for (const x of y) {results5 = Math.min(results5, x)}return results5})()
z || (()=>{let results6=-Infinity;for (const x of y) {results6 = Math.max(results6, x)}return results6})()
z || (()=>{let results7="";for (const x of y) {results7 += x}return results7})()
"""

testCase """
Expand All @@ -1383,6 +1394,7 @@ describe "for", ->
for product x of y
for min x of y
for max x of y
for join x of y
---
let results=false;for (const x of y) {results = true; break}results
let results1=true;for (const x of y) {results1 = false; break}results1
Expand All @@ -1391,6 +1403,7 @@ describe "for", ->
let results4=1;for (const x of y) {results4 *= x}results4
let results5=Infinity;for (const x of y) {results5 = Math.min(results5, x)}results5
let results6=-Infinity;for (const x of y) {results6 = Math.max(results6, x)}results6
let results7="";for (const x of y) {results7 += x}results7
"""

testCase """
Expand All @@ -1403,14 +1416,16 @@ describe "for", ->
=> for product x of y
=> for min x of y
=> for max x of y
=> for join x of y
---
() => { let results=false;for (const x of y) {results = true; break};return results; };
() => { let results1=true;for (const x of y) {results1 = false; break};return results1; };
() => { let results2=0;for (const x of y) {++results2};return results2; };
() => { let results3=0;for (const x of y) {results3 += x};return results3; };
() => { let results4=1;for (const x of y) {results4 *= x};return results4; };
() => { let results5=Infinity;for (const x of y) {results5 = Math.min(results5, x)};return results5; };
() => { let results6=-Infinity;for (const x of y) {results6 = Math.max(results6, x)};return results6; }
() => { let results6=-Infinity;for (const x of y) {results6 = Math.max(results6, x)};return results6; };
() => { let results7="";for (const x of y) {results7 += x};return results7; }
"""

testCase """
Expand All @@ -1423,6 +1438,7 @@ describe "for", ->
e := x for product x of y
f := x for min x of y
g := x for max x of y
h := x for join x of y
---
const a =(()=>{let results=false;for (const x of y) { if ( x) {results = true; break} }return results})()
const b =(()=>{let results1=true;for (const x of y) { if (! x) {results1 = false; break} }return results1})()
Expand All @@ -1431,6 +1447,7 @@ describe "for", ->
const e =(()=>{let results4=1;for (const x of y) { results4 *= x }return results4})()
const f =(()=>{let results5=Infinity;for (const x of y) { results5 = Math.min(results5, x) }return results5})()
const g =(()=>{let results6=-Infinity;for (const x of y) { results6 = Math.max(results6, x) }return results6})()
const h =(()=>{let results7="";for (const x of y) { results7 += x }return results7})()
"""

testCase """
Expand Down

0 comments on commit f705f79

Please sign in to comment.