[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] Convention for marking pretty-printers output

From: Jose E. Marchesi
Subject: [RFC] Convention for marking pretty-printers output
Date: Sat, 26 Oct 2019 20:23:05 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux)

Hi people!
I need some feedback on an issue related to pretty-printing.

Poke data structures can be very detailed, which is a good thing, since
it provides a lot of flexibility for manipulating the different

However, this also leads to long printouts in the REPL that can get
tiresome to read, and also the way the information is stored is often
not very reader-friendly.  That's the reason why poke supports

Let's consider BPF instructions, for example.  There is an
implementation of the BPF ISA in pickles/bpf.pk.  Several types there
have pretty-printers defined, which are the methods called _print.

For example:

defvar bpf_alu_opcodes =
  ["add", "sub", "mul", "div", "or", "and", "lsh",
   "rsh", "neg", "mod", "xor", "mov", "arsh", "end"];


deftype BPF_Insn_Opcode =
        BPF_Insn_Op_Code code;
        BPF_Insn_Source src;
        BPF_Insn_Class class : bpf_class_is_alujmp (class);

        defun _print = void:
           print "#<";
           if (class == BPF_INSN_CLASS_ALU
               || class == BPF_INSN_CLASS_ALU64)
             print bpf_alu_opcodes[code];
             print bpf_jmp_opcodes[code];
           print ">";
      } alujmp;


Another example from the same file, for 64-bit signed immediates which
are stored non-consecutively:

deftype BPF_Insn =
        uint<32> lo;
        uint<32> hi;

        defun _print = void:
           print "#<";
           printf "%<integer:%i64x%>", hi::lo;
           print ">";
      } imm64 : imm64_p;

This is how a BPF instruction looks like in Poke without pretty

$ bpf-unknown-none-gcc -c foo.c
$ poke foo.o
(poke) .load bpf.pk
(poke) .load elf.pk
(poke) defvar text = elf_section_by_name (Elf64_Ehdr @ 0#B, ".text")
(poke) defvar insns = BPF_Insn[text.sh_size] @ text.sh_offset
(poke) .set pretty-print no
(poke) insns[0]
(poke) insns[0]
BPF_Insn {opcode=BPF_Insn_Opcode {ldst=struct {mode=(uint<3>) 
0x0,size=(uint<2>) 0x3,class=(uint<3>) 0x0}},regs=BPF_Insn_Regs {src=BPF_Reg 
{code=0x0UN},dst=BPF_Reg {code=0x0UN}},offset=0x0H,imm=struct {imm64=struct 

And this is how the same instruction looks with pretty-printing:

(poke) .set pretty-print yes
(poke) insn[0]
BPF_Insn {opcode=BPF_Insn_Opcode {ldst=#<lddw>},regs=BPF_Insn_Regs 
{src=#<%r0>,dst=#<%r0>},offset=0x0H,imm=struct {imm64=#<0000000000000000>}}

Much better! :)

However, and this is the question I have for you people, it seems to me
that it is important to use a convention so the user can identify what
is pretty-printed and what not.

I am using #<...> for that, as you can see in the example above.

I expect many people will .set pretty-print yes in their .pokerc files
(I certainly do that) and when working with data described by pickles
written by other people, when you see #<...> in the values you know you
should deactivate pretty-printing to see the gory details.

Do you agree in that keeping a convention is a good idea?
Do #<...> feel good to you?

PS: I'm working in a patch that adds another flag .set
    output-val-multiline (yes|no) that makes pvm_print_val to insert
    newlines to make the output even more readable.  But that's
    orthogonal to this.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]