debug.ha (2392B)
1 use fmt; 2 use strings; 3 use io; 4 5 export fn debug_automata(mata: *automata) (void | nomem | io::error) = { 6 fmt::errorln("digraph {")?; 7 for (let state .. mata.states) { 8 match (state.result) { 9 case void => void; 10 case let res: size => 11 fmt::errorf("s{} [", state.index)?; 12 fmt::error("color = blue; ")?; 13 fmt::errorf("xlabel = \"A: {}\"; ", res)?; 14 fmt::errorln("]")?; 15 }; 16 }; 17 for (let state .. mata.states) { 18 for (let trans .. state.transitions) { 19 const to = trans.to; 20 fmt::errorf("s{} -> s{} [", state.index, to.index)?; 21 if (trans.negate) fmt::error("color = red; ")?; 22 fmt::error("arrowsize = 0.5; ")?; 23 fmt::error("headlabel = \"")?; 24 for (let a .. trans.accepts) { 25 match(a) { 26 case let r: rune => 27 print_rune(r)?; 28 case let r: (rune, rune) => 29 print_rune(r.0)?; 30 fmt::errorf("-")?; 31 print_rune(r.1)?; 32 case => void; 33 }; 34 }; 35 fmt::error("\"; ")?; 36 if (!mata.deterministic) { 37 fmt::errorf("taillabel = \"T: {}\"; ", trans.tree)?; 38 }; 39 if (trans.epsilon) 40 fmt::error("color = green; ")?; 41 fmt::errorfln("]")?; 42 }; 43 }; 44 fmt::errorln("}")?; 45 }; 46 47 fn debug_dfa_transition(dfa: *dfa_transition) (void | nomem | io::error) = { 48 for (let trans_state .. dfa.trans_states) { 49 fmt::error("{")?; 50 for (let i = 0z; i < len(trans_state.states); i += 1) { 51 if (i != 0z) fmt::error(",")?; 52 fmt::errorf("s{}", trans_state.states[i].index)?; 53 }; 54 fmt::error("}: ")?; 55 for (let i = 0z; i < len(trans_state.transitions); i += 1) { 56 let trans = trans_state.transitions[i]; 57 if (i != 0z) fmt::error("; ")?; 58 match (trans.input) { 59 case let acc: dfa_accept => 60 fmt::error(acc)?; 61 case let neg: dfa_negate => 62 fmt::error("^")?; 63 for (let i = 0z; i < len(neg); i += 1) { 64 fmt::error(neg[i])?; 65 }; 66 }; 67 fmt::error(" {")?; 68 let to = trans.to; 69 for (let i = 0z; i < len(to.states); i += 1) { 70 if (i != 0z) fmt::error(",")?; 71 fmt::errorf("s{}", to.states[i].index)?; 72 }; 73 fmt::error("}")?; 74 }; 75 fmt::errorln()?; 76 }; 77 }; 78 79 fn print_rune(r: rune) (void | io::error) = { 80 switch (r) { 81 case '\n' => fmt::error(`\\n`)?; 82 case '\t' => fmt::error(`\\t`)?; 83 case '\r' => fmt::error(`\\r`)?; 84 case '"' => fmt::error(`\"`)?; 85 case '\\' => fmt::error(`\\`)?; 86 case ' ' => fmt::error(`\\w`)?; 87 case => 88 const accept = strings::fromrunes([r])?; 89 defer free(accept); 90 fmt::error(accept)?; 91 }; 92 };