Skip to content

Commit

Permalink
Merge pull request #1148 from DanielXMoore/infinite-for
Browse files Browse the repository at this point in the history
Infinite range [x..]
  • Loading branch information
edemaine authored Apr 4, 2024
2 parents 5e6d143 + f6a7991 commit b4b9828
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 9 deletions.
12 changes: 9 additions & 3 deletions source/generate.civet
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ type Options =
js?: boolean
errors?: unknown[]

function stringify(node: ???): string
try
return JSON.stringify node
catch e
return `${node}`

function gen(node: any, options: Options): string
if node is null or node is undefined
return ""
Expand Down Expand Up @@ -45,15 +51,15 @@ function gen(node: any, options: Options): string
if !node.children
switch node.type
when "Ref"
throw new Error(`Unpopulated ref ${JSON.stringify(node)}`)
throw new Error(`Unpopulated ref ${stringify node}`)

debugger
throw new Error(`Unknown node ${JSON.stringify(node)}`)
throw new Error(`Unknown node ${stringify node}`)

return gen node.children, options

debugger
throw new Error(`Unknown node ${JSON.stringify(node)}`)
throw new Error(`Unknown node ${stringify node}`)

export default gen

Expand Down
16 changes: 16 additions & 0 deletions source/parser.hera
Original file line number Diff line number Diff line change
Expand Up @@ -2740,6 +2740,22 @@ RangeExpression
end: e,
}

# NOTE: [x..] range to infinity, valid only in for loops
ExtendedExpression:s __:ws DotDot &( __ CloseBracket ) ->
return {
type: "RangeExpression",
children: ["[]", {
type: "Error",
message: "Infinite range [x..] is only valid in for loops",
}],
start: s,
end: {
type: "Identifier",
name: "Infinity",
children: ["Infinity"],
},
}

ArrayLiteralContent
RangeExpression
# NOTE: No longer need to special-case implicit object literals separated
Expand Down
19 changes: 13 additions & 6 deletions source/parser/for.civet
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ function forRange(

counterRef := makeRef("i")

//infinite := if {type: "Identifier", name: "Infinity"} := end then true
infinite := end.type is "Identifier" and end.name is "Infinity"

let stepRef
if stepExp
stepExp = insertTrimmingSpace(stepExp, "")
stepRef = maybeRef(stepExp, "step")
else if infinite
stepExp = stepRef = "1"

startRef .= maybeRef(start, "start")
endRef .= maybeRef(end, "end")
Expand Down Expand Up @@ -75,17 +80,19 @@ function forRange(
? [counterRef, " <= ", endRef, " : ", counterRef, " >= ", endRef]
: [counterRef, " < ", endRef, " : ", counterRef, " > ", endRef]

condition := stepRef
condition := infinite ? [] : stepRef
? [stepRef, " !== 0 && (", stepRef, " > 0 ? ", ...counterPart, ")"]
: ascRef
? [ascRef, " ? ", ...counterPart]
: asc ? counterPart.slice(0, 3) : counterPart.slice(4)

increment := stepRef
? [...varAssign, counterRef, " += ", stepRef]
: ascRef
? [...varAssign, ascRef, " ? ++", counterRef, " : --", counterRef]
: [...varAssign, asc ? "++" : "--", counterRef]
increment := infinite
? [...varAssign, "++", counterRef]
: stepRef
? [...varAssign, counterRef, " += ", stepRef]
: ascRef
? [...varAssign, ascRef, " ? ++", counterRef, " : --", counterRef]
: [...varAssign, asc ? "++" : "--", counterRef]

return {
declaration,
Expand Down
29 changes: 29 additions & 0 deletions test/for.civet
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ describe "for", ->
}
"""

testCase """
infinite range
---
for i of [1..]
console.log(i)
---
for (let i1 = 1; ; ++i1) {
const i = i1;
console.log(i)
}
"""

testCase """
range without declaration
---
Expand Down Expand Up @@ -179,6 +191,23 @@ describe "for", ->
}
"""

testCase """
infinite range without declaration
---
for [1..]
console.log("hello")
---
for (let i = 1; ; ++i) {
console.log("hello")
}
"""

throws """
infinite range without for
---
[1..]
"""

testCase """
for of character range
---
Expand Down

0 comments on commit b4b9828

Please sign in to comment.