Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:label supports Civet reserved words (but not JS reserved words) #1641

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion civet.dev/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2102,7 +2102,9 @@ while item?

::: info
Labels have the colon on the left to avoid conflict with implicit object
literals. The colons are optional in `break` and `continue`.
literals. The colons are optional in `break` and `continue`,
except for Civet reserved words (e.g. `and`) where a colon is required.
JavaScript reserved words are invalid as labels.
:::

### Controlling Loop Value
Expand Down
12 changes: 10 additions & 2 deletions source/parser.hera
Original file line number Diff line number Diff line change
Expand Up @@ -4460,7 +4460,10 @@ LabelledStatement

Label
# NOTE: `:label` instead of `label:` to not clash with implicit object literal
Colon:colon Identifier:id Whitespace:w ->
Colon:colon IdentifierName:id Whitespace:w ->
// If `id` is a JavaScript reserved word, JS or TS will output an error.
// `:void` is sometimes useful as a return-type annotation, so leave that.
if (id.name === "void") return $skip
return {
type: "Label",
name: id.name,
Expand All @@ -4469,8 +4472,13 @@ Label

# Argument to break/continue, which can include colon or not in input,
# but should not have colon in output
# Colon is required if the identifier is a Civet keyword,
# except for 'loop' which we special-case
LabelIdentifier
Colon? Identifier:id -> id
Colon IdentifierName:id -> id
# Infinite loop of break/continue isn't helpful, so treat as label
&Loop IdentifierName:id -> id
Identifier

LabelledItem
Statement
Expand Down
33 changes: 32 additions & 1 deletion test/label.civet
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{testCase, wrapper} from ./helper.civet
{testCase, throws, wrapper} from ./helper.civet

describe "labels", ->
testCase """
Expand Down Expand Up @@ -107,3 +107,34 @@ describe "labels", ->
}
}
"""

testCase """
reserved word label
---
:and while x
break :and
---
and: while (x) {
break and
}
"""

throws """
reserved word label without colon
---
:and while x
break and
---
ParseError
"""

testCase """
loop label
---
:loop while x
break loop
---
loop: while (x) {
break loop
}
"""
Loading