Skip to content

Commit f6c66cb

Browse files
committed
Use distinct kind for juxtaposition
This allows us to easily distinguish juxtaposition syntax from explicit multiplication.
1 parent cb907f3 commit f6c66cb

File tree

5 files changed

+27
-21
lines changed

5 files changed

+27
-21
lines changed

src/expr.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ function _to_expr(node::SyntaxNode; iteration_spec=false, need_linenodes=true,
305305
end
306306
elseif headsym == :return && isempty(args)
307307
push!(args, nothing)
308+
elseif headsym == :juxtapose
309+
headsym = :call
310+
pushfirst!(args, :*)
308311
end
309312
return Expr(headsym, args...)
310313
end

src/kinds.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,7 @@ const _kind_names =
879879
"comparison"
880880
"curly"
881881
"inert" # QuoteNode; not quasiquote
882+
"juxtapose" # Numeric juxtaposition like 2x
882883
"string" # A string interior node (possibly containing interpolations)
883884
"cmdstring" # A cmd string node (containing delimiters plus string)
884885
"char" # A char string node (containing delims + char data)

src/parser.jl

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,13 +1105,13 @@ function is_juxtapose(ps, prev_k, t)
11051105
!is_initial_reserved_word(ps, k)
11061106
end
11071107

1108-
# Juxtoposition. Ugh!
1108+
# Juxtoposition. Ugh! But so useful for units and Field identities like `im`
11091109
#
1110-
# 2x ==> (call-i 2 * x)
1111-
# 2(x) ==> (call-i 2 * x)
1112-
# (2)(3)x ==> (call-i 2 * 3 x)
1113-
# (x-1)y ==> (call-i (call-i x - 1) * y)
1114-
# x'y ==> (call-i (call-post x ') * y)
1110+
# 2x ==> (juxtapose 2 x)
1111+
# 2(x) ==> (juxtapose 2 x)
1112+
# (2)(3)x ==> (juxtapose 2 3 x)
1113+
# (x-1)y ==> (juxtapose (call-i x - 1) y)
1114+
# x'y ==> (juxtapose (call-post x ') y)
11151115
#
11161116
# flisp: parse-juxtapose
11171117
function parse_juxtapose(ps::ParseState)
@@ -1124,15 +1124,12 @@ function parse_juxtapose(ps::ParseState)
11241124
if !is_juxtapose(ps, prev_kind, t)
11251125
break
11261126
end
1127-
if n_terms == 1
1128-
bump_invisible(ps, K"*")
1129-
end
11301127
if prev_kind == K"string" || is_string_delim(t)
11311128
# issue #20575
11321129
#
1133-
# "a""b" ==> (call-i (string "a") * (error-t) (string "b"))
1134-
# "a"x ==> (call-i (string "a") * (error-t) x)
1135-
# "$y"x ==> (call-i (string (string y)) * (error-t) x)
1130+
# "a""b" ==> (juxtapose (string "a") (error-t) (string "b"))
1131+
# "a"x ==> (juxtapose (string "a") (error-t) x)
1132+
# "$y"x ==> (juxtapose (string (string y)) (error-t) x)
11361133
bump_invisible(ps, K"error", TRIVIA_FLAG,
11371134
error="cannot juxtapose string literal")
11381135
end
@@ -1144,7 +1141,7 @@ function parse_juxtapose(ps::ParseState)
11441141
n_terms += 1
11451142
end
11461143
if n_terms > 1
1147-
emit(ps, mark, K"call", INFIX_FLAG)
1144+
emit(ps, mark, K"juxtapose")
11481145
end
11491146
end
11501147

test/expr.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@
296296
Expr(:block, LineNumberNode(1), :z))
297297
end
298298

299+
@testset "juxtapose" begin
300+
@test parse(Expr, "2x") == Expr(:call, :*, 2, :x)
301+
@test parse(Expr, "(2)(3)x") == Expr(:call, :*, 2, 3, :x)
302+
end
303+
299304
@testset "Core.@doc" begin
300305
@test parse(Expr, "\"x\" f") ==
301306
Expr(:macrocall, GlobalRef(Core, Symbol("@doc")), LineNumberNode(1), "x", :f)

test/parser.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,15 @@ tests = [
179179
"x >> y >> z" => "(call-i (call-i x >> y) >> z)"
180180
],
181181
JuliaSyntax.parse_juxtapose => [
182-
"2x" => "(call-i 2 * x)"
183-
"2x" => "(call-i 2 * x)"
184-
"2(x)" => "(call-i 2 * x)"
185-
"(2)(3)x" => "(call-i 2 * 3 x)"
186-
"(x-1)y" => "(call-i (call-i x - 1) * y)"
187-
"x'y" => "(call-i (call-post x ') * y)"
182+
"2x" => "(juxtapose 2 x)"
183+
"2x" => "(juxtapose 2 x)"
184+
"2(x)" => "(juxtapose 2 x)"
185+
"(2)(3)x" => "(juxtapose 2 3 x)"
186+
"(x-1)y" => "(juxtapose (call-i x - 1) y)"
187+
"x'y" => "(juxtapose (call-post x ') y)"
188188
# errors
189-
"\"a\"\"b\"" => "(call-i (string \"a\") * (error-t) (string \"b\"))"
190-
"\"a\"x" => "(call-i (string \"a\") * (error-t) x)"
189+
"\"a\"\"b\"" => "(juxtapose (string \"a\") (error-t) (string \"b\"))"
190+
"\"a\"x" => "(juxtapose (string \"a\") (error-t) x)"
191191
# Not juxtaposition - parse_juxtapose will consume only the first token.
192192
"x.3" => "x"
193193
"sqrt(2)2" => "(call sqrt 2)"

0 commit comments

Comments
 (0)