lean4-htt/bin/lean-gdb.py
2016-11-10 15:46:50 -08:00

158 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
#
# Copyright (c) 2016 Microsoft Corporation. All rights reserved.
# Released under Apache 2.0 license as described in the file LICENSE.
#
# Authors: Sebastian Ullrich, Gabriel Ebner
#
import gdb
import gdb.printing
class LeanNamePrinter:
"""Print a lean::name object."""
def __init__(self, val):
self.val = val
def to_string(self):
def rec(imp):
s = ("'%s'" % imp['m_str'].string()) if imp['m_is_string'] else str(imp['m_k'])
if imp['m_prefix']:
return "%s.%s" % (rec(imp['m_prefix'].dereference()), s)
else:
return s
if not self.val['m_ptr']:
return ""
else:
return rec(self.val['m_ptr'].dereference())
class LeanExprPrinter:
"""Print a lean::expr object."""
expr_kinds = [
'lean::expr_var',
'lean::expr_sort',
'lean::expr_const',
'lean::expr_mlocal',
'lean::expr_mlocal',
'lean::expr_app',
'lean::expr_binding',
'lean::expr_binding',
'lean::expr_let',
'lean::expr_macro',
]
def __init__(self, val):
kind = val['m_ptr']['m_kind']
subtype = gdb.lookup_type(LeanExprPrinter.expr_kinds[kind])
self.val = val['m_ptr'].cast(subtype.pointer()).dereference()
def to_string(self):
return str(self.val.type)
def children(self):
def deep_fields(v):
for f in v.type.fields():
if f.is_base_class:
for g in deep_fields(v[f]):
yield g
elif f.name == 'm_kind':
yield (f.name, v[f].cast(gdb.lookup_type('lean::expr_kind')))
else:
yield (f.name, v[f])
return deep_fields(self.val)
class LeanListPrinter:
"""Print a lean::list object."""
def __init__(self, val):
self.val = val
def children(self):
l = self.val
i = 0
while l['m_ptr']:
cell = l['m_ptr'].dereference()
yield ('[%s]' % i, cell['m_head'])
l = cell['m_tail']
i += 1
def to_string(self):
return str(self.val.type)
def display_hint(self):
return 'array'
class LeanBufferPrinter:
"""Print a lean::buffer object."""
def __init__(self, val):
self.val = val
def children(self):
p = self.val['m_buffer']
for i in range(int(self.val['m_pos'])):
yield ('[%s]' % i, p.dereference())
p += 1
def to_string(self):
return str(self.val.type)
def display_hint(self):
return 'array'
class LeanRBTreePrinter:
"""Print a lean::rb_tree object."""
def __init__(self, val):
self.val = val
def children(self):
def rec(node):
if node['m_ptr']:
cell = node['m_ptr'].dereference()
for i in rec(cell['m_left']): yield i
yield ('', cell['m_value'])
for i in rec(cell['m_right']): yield i
return rec(self.val['m_root'])
def to_string(self):
return 'lean::rb_tree' # full type is way too verbose
def display_hint(self):
return 'array'
class LeanRBMapPrinter:
"""Print a lean::rb_map object."""
def __init__(self, val):
self.val = val
def children(self):
for (_, child) in LeanRBTreePrinter(self.val['m_map']).children():
yield ('', child['first'])
yield ('', child['second'])
def to_string(self):
return 'lean::rb_map' # full type is way too verbose
def display_hint(self):
return 'map'
def build_pretty_printer():
pp = gdb.printing.RegexpCollectionPrettyPrinter("lean")
pp.add_printer('name', '^lean::name$', LeanNamePrinter)
pp.add_printer('expr', '^lean::expr$', LeanExprPrinter)
pp.add_printer('list', '^lean::list', LeanListPrinter)
pp.add_printer('buffer', '^lean::buffer', LeanBufferPrinter)
pp.add_printer('rb_tree', '^lean::rb_tree', LeanRBTreePrinter)
pp.add_printer('rb_map', '^lean::rb_map', LeanRBMapPrinter)
return pp
gdb.printing.register_pretty_printer(
gdb.current_objfile(),
build_pretty_printer(),
replace=True)