diff --git a/LOG.md b/LOG.md index 37b7bf3..659ed23 100644 --- a/LOG.md +++ b/LOG.md @@ -102,3 +102,30 @@ To tie together the lexer and parser, and to provide a convenient means of decoupling other components from them for testing purposes, I then implemented the Rust standard library's `FromStr` trait, which is for types that can be parsed from a string. + +## Printer + +For expression printing, a simple recursive tree-walking algorithm, +dispatching on the various kinds of expression was sufficient. +Satisfyingly, I found I was able to use the same binding power algebra +I defined for the parser in deciding when to use parentheses, and thus +got correct associativity handling effectively for free, while also +keeping all associativity-handling logic well-factored in one place. + +The only complication was in the handling of products, as here there +was some ambiguity as to when to use explicit or implicit +multiplication (that is `x*y` or `xy`). Products of symbols with +other symbols and integers with symbols are more naturally expressed +with implicit multiplication, but of course this couldn't be used for +products of integers with other integers as this would result in +incorrect serialisations (such as "12" for the product of 1 and 2). I +ultimately settled on an approach where the right-hand operand is +first printed into a string, and an explicit multiplication sign is +used whenever that serialisation begins with a numerical character +(either a digit or a minus sign). This nicely handled all of the +cases I could think of and systematically avoids any erroneous +serialisations. + +The printing logic could then be packaged up in an implementation of +the Rust standard library's `Display` trait, which is for types that +have a textual representation.