Skip to content

Commit

Permalink
Use distinct kind for juxtaposition
Browse files Browse the repository at this point in the history
This allows us to easily distinguish juxtaposition syntax from explicit
multiplication.
  • Loading branch information
c42f committed Mar 15, 2023
1 parent cb907f3 commit f6c66cb
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 21 deletions.
3 changes: 3 additions & 0 deletions src/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ function _to_expr(node::SyntaxNode; iteration_spec=false, need_linenodes=true,
end
elseif headsym == :return && isempty(args)
push!(args, nothing)
elseif headsym == :juxtapose
headsym = :call
pushfirst!(args, :*)
end
return Expr(headsym, args...)
end
Expand Down
1 change: 1 addition & 0 deletions src/kinds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ const _kind_names =
"comparison"
"curly"
"inert" # QuoteNode; not quasiquote
"juxtapose" # Numeric juxtaposition like 2x
"string" # A string interior node (possibly containing interpolations)
"cmdstring" # A cmd string node (containing delimiters plus string)
"char" # A char string node (containing delims + char data)
Expand Down
23 changes: 10 additions & 13 deletions src/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1105,13 +1105,13 @@ function is_juxtapose(ps, prev_k, t)
!is_initial_reserved_word(ps, k)
end

# Juxtoposition. Ugh!
# Juxtoposition. Ugh! But so useful for units and Field identities like `im`
#
# 2x ==> (call-i 2 * x)
# 2(x) ==> (call-i 2 * x)
# (2)(3)x ==> (call-i 2 * 3 x)
# (x-1)y ==> (call-i (call-i x - 1) * y)
# x'y ==> (call-i (call-post x ') * y)
# 2x ==> (juxtapose 2 x)
# 2(x) ==> (juxtapose 2 x)
# (2)(3)x ==> (juxtapose 2 3 x)
# (x-1)y ==> (juxtapose (call-i x - 1) y)
# x'y ==> (juxtapose (call-post x ') y)
#
# flisp: parse-juxtapose
function parse_juxtapose(ps::ParseState)
Expand All @@ -1124,15 +1124,12 @@ function parse_juxtapose(ps::ParseState)
if !is_juxtapose(ps, prev_kind, t)
break
end
if n_terms == 1
bump_invisible(ps, K"*")
end
if prev_kind == K"string" || is_string_delim(t)
# issue #20575
#
# "a""b" ==> (call-i (string "a") * (error-t) (string "b"))
# "a"x ==> (call-i (string "a") * (error-t) x)
# "$y"x ==> (call-i (string (string y)) * (error-t) x)
# "a""b" ==> (juxtapose (string "a") (error-t) (string "b"))
# "a"x ==> (juxtapose (string "a") (error-t) x)
# "$y"x ==> (juxtapose (string (string y)) (error-t) x)
bump_invisible(ps, K"error", TRIVIA_FLAG,
error="cannot juxtapose string literal")
end
Expand All @@ -1144,7 +1141,7 @@ function parse_juxtapose(ps::ParseState)
n_terms += 1
end
if n_terms > 1
emit(ps, mark, K"call", INFIX_FLAG)
emit(ps, mark, K"juxtapose")
end
end

Expand Down
5 changes: 5 additions & 0 deletions test/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@
Expr(:block, LineNumberNode(1), :z))
end

@testset "juxtapose" begin
@test parse(Expr, "2x") == Expr(:call, :*, 2, :x)
@test parse(Expr, "(2)(3)x") == Expr(:call, :*, 2, 3, :x)
end

@testset "Core.@doc" begin
@test parse(Expr, "\"x\" f") ==
Expr(:macrocall, GlobalRef(Core, Symbol("@doc")), LineNumberNode(1), "x", :f)
Expand Down
16 changes: 8 additions & 8 deletions test/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ tests = [
"x >> y >> z" => "(call-i (call-i x >> y) >> z)"
],
JuliaSyntax.parse_juxtapose => [
"2x" => "(call-i 2 * x)"
"2x" => "(call-i 2 * x)"
"2(x)" => "(call-i 2 * x)"
"(2)(3)x" => "(call-i 2 * 3 x)"
"(x-1)y" => "(call-i (call-i x - 1) * y)"
"x'y" => "(call-i (call-post x ') * y)"
"2x" => "(juxtapose 2 x)"
"2x" => "(juxtapose 2 x)"
"2(x)" => "(juxtapose 2 x)"
"(2)(3)x" => "(juxtapose 2 3 x)"
"(x-1)y" => "(juxtapose (call-i x - 1) y)"
"x'y" => "(juxtapose (call-post x ') y)"
# errors
"\"a\"\"b\"" => "(call-i (string \"a\") * (error-t) (string \"b\"))"
"\"a\"x" => "(call-i (string \"a\") * (error-t) x)"
"\"a\"\"b\"" => "(juxtapose (string \"a\") (error-t) (string \"b\"))"
"\"a\"x" => "(juxtapose (string \"a\") (error-t) x)"
# Not juxtaposition - parse_juxtapose will consume only the first token.
"x.3" => "x"
"sqrt(2)2" => "(call sqrt 2)"
Expand Down

0 comments on commit f6c66cb

Please sign in to comment.