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

Format: refactor 'asm' formatting #4654

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions spec/compiler/formatter/formatter_spec.cr
Expand Up @@ -625,6 +625,13 @@ describe Crystal::Formatter do
assert_format %(asm("nop" :::: "volatile" , "alignstack" , "intel" )), %(asm("nop" :::: "volatile", "alignstack", "intel"))
assert_format %(asm("nop" ::: "eax" , "ebx" : "volatile" , "alignstack" )), %(asm("nop" ::: "eax", "ebx" : "volatile", "alignstack"))
assert_format %(asm("a" : "b"(c) : "d"(e) :: "volatile"))
assert_format %(asm("a" : "b"(c)\n)), %(asm("a" : "b"(c)))
assert_format %(asm("a" :: "d"(e)\n)), %(asm("a" :: "d"(e)))
assert_format %(asm("a" ::: "f"\n)), %(asm("a" ::: "f"))
assert_format %(asm("a" :::: "volatile"\n)), %(asm("a" :::: "volatile"))
assert_format %(asm("a" : "b"(c) : "d"(e)\n : "f"))
assert_format %(asm("a" : "b"(c) : "d"(e)\n : "f",\n "g"))
assert_format %(asm("a" ::: "a"\n : "volatile",\n "intel"))

assert_format "1 # foo\n1234 # bar", "1 # foo\n1234 # bar"
assert_format "1234 # foo\n1 # bar", "1234 # foo\n1 # bar"
Expand Down
97 changes: 52 additions & 45 deletions src/compiler/crystal/tools/formatter.cr
Expand Up @@ -3856,27 +3856,24 @@ module Crystal

skip_space_or_newline

colon_column = @column + 1
if @token.type == :"::"
write " ::"
next_token_skip_space_or_newline
elsif @token.type == :":"
dot_column = @column + 1
space_after_output = true

write " :"
next_token

skip_space_or_newline
next_token_skip_space_or_newline

output = node.output
if output
if output = node.output
write " "
accept output
skip_space
if @token.type == :NEWLINE
if node.inputs
consume_newlines
write_indent(dot_column)
write_indent(colon_column)
space_after_output = false
else
skip_space_or_newline
Expand All @@ -3892,55 +3889,23 @@ module Crystal
end

if inputs = node.inputs
write " "
input_column = @column
inputs.each_with_index do |input, i|
visit_asm_parts inputs, colon_column, write_colon: false do |input|
accept input
skip_space

if @token.type == :","
write "," unless last?(i, inputs)
next_token_skip_space

unless last?(i, inputs)
if @token.type == :NEWLINE
consume_newlines
write_indent(input_column)
else
write " " unless last?(i, inputs)
end
skip_space_or_newline
end
end
end
end

if clobbers = node.clobbers
write_token :":"
write " "
skip_space_or_newline
clobbers.each_with_index do |clobber, i|
visit_asm_parts clobbers, colon_column, write_colon: true do |clobber|
accept StringLiteral.new(clobber)
skip_space_or_newline
if @token.type == :","
write ", " unless last?(i, clobbers)
next_token_skip_space_or_newline
end
end
end

if @token.type == :"::" || @token.type == :":"
write " " if inputs || clobbers
write @token.type
write " "
next_token_skip_space_or_newline
while @token.type == :DELIMITER_START
write_token @token.type
skip_space_or_newline
parts = [node.volatile?, node.alignstack?, node.intel?].select(&.itself)
visit_asm_parts parts, colon_column, write_colon: false do
accept StringLiteral.new("")
skip_space_or_newline
if @token.type == :","
write ", "
next_token_skip_space_or_newline
end
end
end

Expand Down Expand Up @@ -3969,6 +3934,48 @@ module Crystal
false
end

def visit_asm_parts(parts, colon_column, write_colon) : Nil
if write_colon
write_token :":"
skip_space_or_newline
end
write " "
column = @column

parts.each_with_index do |part, i|
yield part
skip_space

if @token.type == :","
write "," unless last?(i, parts)
next_token_skip_space
end

if @token.type == :NEWLINE
if last?(i, parts)
next_token_skip_space_or_newline
if @token.type == :":" || @token.type == :"::"
write_line
write_indent(colon_column)
end
else
consume_newlines
write_indent(last?(i, parts) ? colon_column : column)
skip_space_or_newline
end
else
skip_space_or_newline
if last?(i, parts)
if @token.type == :":" || @token.type == :"::"
write " "
end
else
write " "
end
end
end
end

def visit(node : ASTNode)
raise "BUG: unexpected node: #{node.class} at #{node.location}"
end
Expand Down