|
| 1 | +import open /Pretty |
| 2 | +import /List |
| 3 | +import Pretty/Style as Style |
| 4 | + |
| 5 | +{## |
| 6 | + Pretty printer example 1: |
| 7 | + IMP lang formatter |
| 8 | + ##} |
| 9 | + |
| 10 | +data rec AExp = |
| 11 | + | AVal of Int |
| 12 | + | AOp of String, AExp, AExp |
| 13 | + | ANeg of AExp |
| 14 | + | AVar of String |
| 15 | + |
| 16 | +data rec BExp = |
| 17 | + | BVal of Bool |
| 18 | + | BOp of String, BExp, BExp |
| 19 | + | BCmp of String, AExp, AExp |
| 20 | + | BNeg of BExp |
| 21 | + |
| 22 | +data rec Imp = |
| 23 | + | Skip |
| 24 | + | Ass of String, AExp |
| 25 | + | Seq of Imp, Imp |
| 26 | + | If of BExp, Imp, Imp |
| 27 | + | While of BExp, Imp |
| 28 | + |
| 29 | +method rec pretty (self : AExp) = match self with |
| 30 | + | AVal v => style {fg=Style.Magenta} (text v.format) |
| 31 | + | AOp op e1 e2 => |
| 32 | + style {fg=Style.Red} (text "(") |
| 33 | + <> (e1.pretty </> (text op <+> e2.pretty)) |
| 34 | + <> style {fg=Style.Red} (text ")") |
| 35 | + | ANeg e => text "-" <> e.pretty |
| 36 | + | AVar v => text v |
| 37 | + end |
| 38 | + |
| 39 | +method rec pretty (self : BExp) = match self with |
| 40 | + | BVal v => style {fg=Style.Green} (text v.format) |
| 41 | + | BOp op e1 e2 => |
| 42 | + style {fg=Style.Red} (text "(") |
| 43 | + <> (e1.pretty </> (text op <+> e2.pretty)) |
| 44 | + <> style {fg=Style.Red} (text ")") |
| 45 | + | BCmp op e1 e2 => |
| 46 | + style {fg=Style.Red} (text "(") |
| 47 | + <> (e1.pretty </> (text op <+> e2.pretty)) |
| 48 | + <> style {fg=Style.Red} (text ")") |
| 49 | + | BNeg e => text "~" <> e.pretty |
| 50 | + end |
| 51 | + |
| 52 | +method rec pretty (self : Imp) = match self with |
| 53 | + | Skip => text "skip;" |
| 54 | + | Ass v e => |
| 55 | + hang 2 |
| 56 | + (text ("let " + v + " =")) |
| 57 | + (e.pretty <> text ";") |
| 58 | + | Seq p1 p2 => p1.pretty $$ p2.pretty |
| 59 | + | If cond p1 p2 => |
| 60 | + anyHang |
| 61 | + [ (0, text "if " <> cond.pretty <> text " {") |
| 62 | + , (2, p1.pretty) |
| 63 | + , (0, text "} else {") |
| 64 | + , (2, p2.pretty) |
| 65 | + , (0, text "}") |
| 66 | + ] |
| 67 | + | While cond p => |
| 68 | + anyHang |
| 69 | + [ (0, text "while " <> cond.pretty <> text " {") |
| 70 | + , (2, p.pretty) |
| 71 | + , (0, text "}") |
| 72 | + ] |
| 73 | + end |
| 74 | + |
| 75 | +let arith = |
| 76 | + (ANeg |
| 77 | + (AOp "/" |
| 78 | + (AVar "x") |
| 79 | + (AVal 50))) |
| 80 | + |
| 81 | +let boolean = |
| 82 | + BOp "&&" |
| 83 | + (BCmp "==" arith arith) |
| 84 | + (BNeg (BVal True)) |
| 85 | + |
| 86 | +let program = |
| 87 | + Seq |
| 88 | + (Ass "myVar" arith) |
| 89 | + (While |
| 90 | + boolean |
| 91 | + (If |
| 92 | + (BVal True) |
| 93 | + Skip |
| 94 | + (Ass "xyz" (AVal 10)))) |
| 95 | + |
| 96 | +let _ = [160, 80, 40, 20].iter (fn width => |
| 97 | + printStrLn (generate {width} program.pretty)) |
0 commit comments