diff --git a/utils/gdb/seer_pretty_printers.py b/utils/gdb/seer_pretty_printers.py index 523c52f..1072cb8 100644 --- a/utils/gdb/seer_pretty_printers.py +++ b/utils/gdb/seer_pretty_printers.py @@ -114,6 +114,89 @@ class Piece(enum.IntEnum): return self.name.title() +class Move(object): + """ + Wrapper around GDB's representation of a 'seer::board::move::Move' + in memory. + """ + + # Should be kept in sync with the values in `move.rs` + PIECE_SHIFT = 0 + PIECE_MASK = 0b111 + START_SHIFT = 3 + START_MASK = 0b11_1111 + DESTINATION_SHIFT = 9 + DESTINATION_MASK = 0b11_1111 + CAPTURE_SHIFT = 15 + CAPTURE_MASK = 0b111 + PROMOTION_SHIFT = 18 + PROMOTION_MASK = 0b111 + EN_PASSANT_SHIFT = 21 + EN_PASSANT_MASK = 0b1 + DOUBLE_STEP_SHIFT = 22 + DOUBLE_STEP_MASK = 0b1 + CASTLING_SHIFT = 23 + CASTLING_MASK = 0b1 + + def __init__(self, val): + self._val = val + + @property + def piece(self): + return Piece(self._val >> self.PIECE_SHIFT & self.PIECE_MASK) + + @property + def start(self): + return Square(self._val >> self.START_SHIFT & self.START_MASK) + + @property + def destination(self): + return Square(self._val >> self.DESTINATION_SHIFT & self.DESTINATION_MASK) + + @property + def capture(self): + index = self._val >> self.CAPTURE_SHIFT & self.CAPTURE_MASK + if index == 7: + return None + return Piece(index) + + @property + def promotion(self): + index = self._val >> self.PROMOTION_SHIFT & self.PROMOTION_MASK + if index == 7: + return None + return Piece(index) + + @property + def en_passant(self): + return bool(self._val >> self.EN_PASSANT_SHIFT & self.EN_PASSANT_MASK) + + @property + def double_step(self): + return bool(self._val >> self.DOUBLE_STEP_SHIFT & self.DOUBLE_STEP_MASK) + + @property + def castling(self): + return bool(self._val >> self.CASTLING_SHIFT & self.CASTLING_MASK) + + def __str__(self): + KEYS = [ + "piece", + "start", + "destination", + "capture", + "promotion", + "en_passant", + "double_step", + "castling", + ] + print_opt = lambda val: "(None)" if val is None else str(val) + indent = lambda s: " " + s + + values = [key + ": " + print_opt(getattr(self, key)) + ",\n" for key in KEYS] + return "Move{\n" + "".join(map(indent, values)) + "}" + + class SquarePrinter(object): "Print a seer::board::square::Square" @@ -174,6 +257,16 @@ class PiecePrinter(object): return str(self._val) +class MovePrinter(object): + "Print a seer::board::move::Move" + + def __init__(self, val): + self._val = Move(int(val["__0"])) + + def to_string(self): + return str(self._val) + + def build_pretty_printer(): pp = gdb.printing.RegexpCollectionPrettyPrinter('seer') @@ -183,6 +276,7 @@ def build_pretty_printer(): pp.add_printer('File', '^seer::board::file::File$', FilePrinter) pp.add_printer('Rank', '^seer::board::rank::Rank$', RankPrinter) pp.add_printer('Piece', '^seer::board::piece::Piece$', ColorPrinter) + pp.add_printer('Move', '^seer::board::move::Move$', MovePrinter) return pp