moonrockz/krueger/printer does not have a README file

    PrintError

    pub suberror PrintError {
    PrintError(path~ :
    NodePath
    , problem~ : PrintProblem)
    } derive(
    Debug
    )

    An AST that cannot print as valid Elm. path leads from the node given to the printer to the bad node, with elm-syntax JSON field names (see NodePath); for print_file it starts at the file.

    NameKind

    pub(all) enum NameKind {
    Lower
    Upper
    Operator
    } derive(Eq,
    Debug
    )

    The kind of name that a PrintProblem::InvalidName is about.

    PrintProblem

    pub(all) enum PrintProblem {
    InvalidName(NameKind, String)
    EmptyModuleName
    NonFiniteFloat(Double)
    UnrepresentableInt(Int64)
    NegativePattern
    ShortApplication
    ShortTuple
    NoFields
    EmptyExposing
    EmptyCase
    EmptyLet
    NoConstructors
    NoLambdaArguments
    UnknownOperator(String)
    InvalidPrecedence(Int)
    InvalidGlsl
    InvalidDocumentation
    LetDocumentation
    TooDeep
    } derive(Eq,
    Debug
    )

    Why an AST cannot print as valid Elm.

    The Elm source of a declaration, without a trailing line feed. A port's doc comment is not part of its declaration (elm-syntax keeps it in File.comments), so only print_file prints it.

    test {
    let r : @ast.Range = {
    start: { row: 0, column: 0, },
    end: { row: 0, column: 0, },
    }
    let int : @ast.Node[@ast.TypeAnnotation] = {
    range: r,
    value: Typed({ range: r, value: ([][:], "Int"), }, [][:]),
    }
    let decl : @ast.Node[@ast.Declaration] = {
    range: r,
    value: AliasDeclaration({
    documentation: None,
    name: { range: r, value: "Age", },
    generics: [][:],
    type_annotation: int,
    }),
    }
    inspect(
    @printer.print_declaration(decl),
    content=(
    #|type alias Age =
    #| Int
    ),
    )
    }

    The Elm source of an expression. Parentheses are added where precedence needs them; parentheses in the AST stay. if, case and let are always multi-line (elm-format). Raises PrintError for an expression that cannot print as valid Elm; the error's path starts at e.

    test {
    let r : @ast.Range = {
    start: { row: 0, column: 0, },
    end: { row: 0, column: 0, },
    }
    fn v(name : String) -> @ast.Node[@ast.Expression] {
    { range: r, value: FunctionOrValue([][:], name), }
    }
    let sum : @ast.Node[@ast.Expression] = {
    range: r,
    value: OperatorApplication("+", Left, v("a"), v("b")),
    }
    let product : @ast.Node[@ast.Expression] = {
    range: r,
    value: OperatorApplication("*", Left, sum, v("c")),
    }
    inspect(@printer.print_expression(product), content="(a + b) * c")
    }
    fn print_file(file :
    File
    , width? : Int, dialect? :
    Dialect
    ) -> String raise PrintError

    The Elm source of a file in the elm-format layout, ending with one line feed. Fixed shapes (declaration bodies, custom types, if, case, let) are always multi-line; other constructs stay on one line when they fit in width columns. Prints documentation and the doc comments of File.comments (module and port documentation), not regular comments. Text inside doc comments and GLSL is written as it is, line ends included: a doc comment from a CRLF source keeps its \r\n. Raises PrintError for an AST that cannot print as valid Elm; the error's path starts at the file.

    UnConsPattern(a, AsPattern(b, c)) prints as a :: b as c, which elm make 0.19.1 and elm-format read as (a :: b) as c (see print_pattern).

    test {
    let text = "module Main exposing (main)\n\n\nmain =\n 1 + 2\n"
    let result = @parser.parse_module(
    @scanner.SourceText::new(text),
    @scanner.DefaultScanner::new(),
    )
    inspect(@printer.print_file(result.ast.unwrap()) == text, content="true")
    }

    The Elm source of a pattern. Raises PrintError for a pattern that Elm cannot write (a negative number, a bad name, a tuple with one item); the error's path starts at p.

    UnConsPattern(a, AsPattern(b, c)) prints as a :: b as c, because krueger and elm-syntax read that text back as the same AST. elm make 0.19.1 and elm-format read a :: b as c as (a :: b) as c. To bind only the tail, use ParenthesizedPattern: a :: (b as c).

    test {
    let r : @ast.Range = {
    start: { row: 0, column: 0, },
    end: { row: 0, column: 0, },
    }
    fn pvar(name : String) -> @ast.Node[@ast.Pattern] {
    { range: r, value: VarPattern(name), }
    }
    let inner : @ast.Node[@ast.Pattern] = {
    range: r,
    value: UnConsPattern(pvar("a"), pvar("b")),
    }
    let outer : @ast.Node[@ast.Pattern] = {
    range: r,
    value: UnConsPattern(inner, pvar("rest")),
    }
    // `::` is right-associative, so an `::` on its left gets parentheses.
    inspect(@printer.print_pattern(outer), content="(a :: b) :: rest")
    }

    The Elm source of a type annotation, laid out in width columns where elm-format allows a choice. Parentheses are added where precedence needs them. Raises PrintError when the type cannot print as valid Elm; the error's path starts at t.

    test {
    let r : @ast.Range = {
    start: { row: 0, column: 0, },
    end: { row: 0, column: 0, },
    }
    let a : @ast.Node[@ast.TypeAnnotation] = {
    range: r,
    value: GenericType("a"),
    }
    let maybe : @ast.Node[@ast.TypeAnnotation] = {
    range: r,
    value: Typed({ range: r, value: ([][:], "Maybe"), }, [a][:]),
    }
    let list : @ast.Node[@ast.TypeAnnotation] = {
    range: r,
    value: Typed({ range: r, value: ([][:], "List"), }, [maybe][:]),
    }
    inspect(@printer.print_type_annotation(list), content="List (Maybe a)")
    }

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io