Previous part: Balancing brackets - 2

Instead of taking a sequence of brackets, we would accept any ASCII symbols. Let’s try on this:

"fn main() { println('hello, <world>!') }"

We don’t have to touch old functions, it’s enough to pattern match on ASCII character groups.

  • ASCII is either a Glyph or a Caret modifying signal (non-printable character)
  • Glyph is either a Number, a Letter or a Symbol
  • Symbol is either a mark to Punctuate or a Bracket

How do I exactly know to get Bracket from ASCII? By looking at constructors here.

Having this information in mind, we can pattern match on exact types:

on @Glyph `ho'ho` on @Symbol `ho` row `ho'ho` on @Bracket `ho` row

… and we would end up with many options! You can see how we literally case split:

 `li` is @(ASCII `MN` Glyph) `ho` _
 `la` is @(Glyph `MN` Symbol) `ho` _
 `la` is @(Symbol `MN` Bracket) `ho` _
 `la` is @Bracket `ho` _

If you rather want to show what is exactly you are supposed to handle, just evaluate subtraction:

 `li` is @Caret `ho` _
 `la` is @(Letter `ML` Number) `ho` _
 `la` is @Punctuate `ho` _
 `la` is @Bracket `ho` _

The bright side of opened interface like ASCII in ya-ascii package is that you have more freedom to refactor things. Since almost all operators are left biased (including Sum) you can rewrite the code snippet above to its shorter form:

 `li` is @(ASCII `MN` Glyph `ML_` Glyph `MN` Symbol `ML_` Symbol `MN` Bracket) `ho` _
 `la` is @Bracket `ho` _

Let’s say we actually don’t care about other characters except for brackets:

is `hu` enter `la_` deposit `la` analyze `ho'yu` Unit

Full source code is available here.

Next time we are going to elaborate on error messages.

Continue this tutorial