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

Allow spaces in (op), force spaces in (in) and (instanceof) #1684

Merged
merged 1 commit into from
Jan 6, 2025
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
20 changes: 16 additions & 4 deletions source/parser.hera
Original file line number Diff line number Diff line change
Expand Up @@ -2437,15 +2437,17 @@ FunctionExpression
block,
}

# BinaryOp function shorthand
!ArrowFunction OpenParen:open BinaryOp:op CloseParen:close ->
# BinaryOp function shorthand (op)
!ArrowFunction OpenParen:open __:ws1 BinaryOp:op __:ws2 CloseParen:close ->
// (foo) doesn't need an arrow wrapper; just foo suffices
if (op.special && op.call && !op.negated) return op.call

if (!ws1) ws1 = op.spaced ? [" "] : []
if (!ws2) ws2 = op.spaced ? [" "] : []
const refA = makeRef("a"),
refB = makeRef("b"),
body = processBinaryOpExpression([refA, [
[[], op, [], refB] // BinaryOpRHS
[ws1, op, ws2, refB] // BinaryOpRHS
]])

const parameterList = [ [ refA, "," ], refB ]
Expand Down Expand Up @@ -2474,6 +2476,8 @@ FunctionExpression

# Haskell-style sections
OpenParen:open NonPipelineAssignmentExpression:lhs __:ws1 BinaryOp:op __:ws2 CloseParen:close ->
if (!ws1) ws1 = op.spaced ? [" "] : []
if (!ws2) ws2 = op.spaced ? [" "] : []
const refB = makeRef("b")
const fn = makeAmpersandFunction({
ref: refB,
Expand Down Expand Up @@ -2520,6 +2524,8 @@ FunctionExpression
expression: fn,
}
OpenParen:open __:ws1 !/\+\+|--|⧺|—|[\+\-&]\S/ !( Placeholder ( TypePostfix / BinaryOpRHS ) ) BinaryOp:op __:ws2 NonPipelineAssignmentExpression:rhs CloseParen:close ->
if (!ws1) ws1 = op.spaced ? [" "] : []
if (!ws2) ws2 = op.spaced ? [" "] : []
const refA = makeRef("a")
const fn = makeAmpersandFunction({
ref: refA,
Expand Down Expand Up @@ -4222,13 +4228,15 @@ BinaryOpSymbol
return {
$loc,
token: "instanceof",
spaced: true,
relational: true,
special: true,
}
"!<?" ->
return {
$loc,
token: "instanceof",
spaced: true,
relational: true,
special: true,
negated: true,
Expand Down Expand Up @@ -4283,6 +4291,7 @@ BinaryOpSymbol
return {
$loc,
token: $1,
spaced: true,
relational: true,
special: true, // for typeof shorthand
}
Expand Down Expand Up @@ -4363,6 +4372,7 @@ CoffeeOfOp
return {
$loc,
token: "in",
spaced: true,
special: true,
negated: true,
}
Expand All @@ -4380,6 +4390,7 @@ NotOp
return {
$loc,
token: "instanceof",
spaced: true,
relational: true,
special: true,
negated: true,
Expand All @@ -4388,6 +4399,7 @@ NotOp
return {
$loc,
token: "in",
spaced: true,
special: true,
negated: true,
}
Expand Down Expand Up @@ -6778,7 +6790,7 @@ Import

In
"in" NonIdContinue ->
return { $loc, token: $1 }
return { $loc, token: $1, spaced: true }

Infer
"infer" NonIdContinue ->
Expand Down
2 changes: 2 additions & 0 deletions source/parser/types.civet
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,14 @@ export type CommentNode =

export type BinaryOp = (string &
name?: never
spaced?: never
special?: never
relational?: never
assoc?: never
type?: undefined
) | (ASTLeaf &
type?: undefined
spaced?: boolean
special?: true
// The following are allowed only when special is true:
prec?: string | number | undefined
Expand Down
76 changes: 70 additions & 6 deletions test/function-block-shorthand.civet
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,34 @@ describe "(op) shorthand", ->
items.reduce(((a2,b2) => a2||b2), false)
"""

testCase """
binary op with spaces
---
( +/*rhs*/)
(in)
( in)
(in )
( in )
(not in)
(!in)
(instanceof)
(!instanceof)
(<?)
(!<?)
---
((a,b) => a +/*rhs*/b);
((a1,b1) => a1 in b1);
((a2,b2) => a2 in b2);
((a3,b3) => a3 in b3);
((a4,b4) => a4 in b4);
((a5,b5) => !(a5 in b5));
((a6,b6) => !(a6 in b6));
((a7,b7) => a7 instanceof b7);
((a8,b8) => !(a8 instanceof b8));
((a9,b9) => a9 instanceof b9);
((a10,b10) => !(a10 instanceof b10))
"""

testCase """
binary &
---
Expand Down Expand Up @@ -1064,9 +1092,27 @@ describe "operator sections", ->
testCase """
left section with spaces
---
items.map (1 + )
---
items.map((b => 1 + b))
(1 +/*rhs*/)
(1 in)
(1 in )
(1 in )
(1 not in)
(1 !in)
(1 instanceof)
(1 !instanceof)
(1 <?)
(1 !<?)
---
(b => 1 +/*rhs*/b);
(b1 => 1 in b1);
(b2 => 1 in b2);
(b3 => 1 in b3);
(b4 => !(1 in b4));
(b5 => !(1 in b5));
(b6 => 1 instanceof b6);
(b7 => !(1 instanceof b7));
(b8 => 1 instanceof b8);
(b9 => !(1 instanceof b9))
"""

testCase """
Expand All @@ -1088,9 +1134,27 @@ describe "operator sections", ->
testCase """
right section with spaces
---
items.map ( + 1)
---
items.map((a => a + 1))
(/*lhs*/+ x)
(in x)
( in x)
( in x)
(not in x)
(!in x)
(instanceof x)
(!instanceof x)
(<? x)
(!<? x)
---
(a => a/*lhs*/+ x);
(a1 => a1 in x);
(a2 => a2 in x);
(a3 => a3 in x);
(a4 => !(a4 in x));
(a5 => !(a5 in x));
(a6 => a6 instanceof x);
(a7 => !(a7 instanceof x));
(a8 => a8 instanceof x);
(a9 => !(a9 instanceof x))
"""

testCase """
Expand Down
Loading