From a083588887d9e3dc6010a4302c55029176f68df0 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Sat, 25 May 2024 01:34:53 +0200 Subject: [PATCH] Document spec in README --- README.md | 8 ++++++++ src/Runic.jl | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2a5959..8da07a4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ # Runic.jl *A code formatter with rules set in stone.* + +## Formatting specification + +This is a list of the rules and formatting transformations performed by Runic: + + - No trailing whitespace + - Normalized line endings (`\r\n` -> `\n`) (TODO: Is this bad on Windows with Git's autocrlf?) + - Hex/octal/binary literals are padded with zeroes diff --git a/src/Runic.jl b/src/Runic.jl index 423559d..64f3bec 100644 --- a/src/Runic.jl +++ b/src/Runic.jl @@ -146,7 +146,7 @@ function format_node!(ctx::Context, node::JuliaSyntax.GreenNode) @assert span > 2 # 0x prefix target_spans = 2 .+ (2, 4, 8, 16, 32) # 0x + expected chars if span < 34 && !(span in target_spans) - i::Int = findfirst(x -> x > span, target_spans) + i = findfirst(x -> x > span, target_spans)::Int bytes = node_bytes(ctx, node) while length(bytes) < target_spans[i] insert!(bytes, 3, '0') @@ -157,7 +157,42 @@ function format_node!(ctx::Context, node::JuliaSyntax.GreenNode) node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), nb, ()) return node′ else - # Do nothing: correctly formatted or a BigInt literal + # Do nothing: correctly formatted or a BigInt hex literal + end + end + + # Oct literals + if node_kind === K"OctInt" + @assert JuliaSyntax.flags(node) == 0 + @assert !JuliaSyntax.haschildren(node) + span = JuliaSyntax.span(node) + # Padding depends on the value of the literal + str = String(node_bytes(ctx, node)) + n = tryparse(UInt128, str) + if n !== nothing + target_span_from_value = + n <= typemax(UInt8) ? 5 : n <= typemax(UInt16) ? 8 : + n <= typemax(UInt32) ? 13 : n <= typemax(UInt64) ? 24 : + n <= typemax(UInt128) ? 45 : error("unreachable") + target_spans = (5, 8, 13, 24, 45) + i = findfirst(x -> x >= span, target_spans)::Int + target_span_from_source = target_spans[i] + target_span = max(target_span_from_value, target_span_from_source) + if span != target_span + bytes = node_bytes(ctx, node) + while length(bytes) < target_span + insert!(bytes, 3, '0') + end + nb = write_and_reset(ctx, bytes) + @assert nb == length(bytes) == target_span + # Create new node and return it + node′ = JuliaSyntax.GreenNode(JuliaSyntax.head(node), nb, ()) + return node′ + else + # Do nothing: correctly formatted oct literal + end + else + # Do nothing: BigInt oct literal end end