20 pokefmt

pokefmt is a template system to embed Poke code in files. It copies the content from standard input to standard output and replaces the Poke code with the result of execution. You can write Poke code between %{ and }% delimters. To simplify printing of expressions, pokefmt also supports embedding of Poke expressions between %( and %) delimiters.

As as example, pokefmt will transform the following text

%{
  load riscv;

  var a = 1, b = 2;
}%
The encoding of ADD R3, R2, R1 instruction in RISC-V instruction set
is %{printf "0x%u32x", rv32_add (3, 2, 1);}%.

The result of %(a)% + %(b)% is %(a + b)%.

to this text:


The encoding of ADD R3, R2, R1 instruction in RISC-V instruct set
is 0x001101b3.

The result of 1 + 2 is 3.

You can customize the printer for expressions by re-defining pokefmt_expr_printer function. For example,

#as: -march=rv32i
#objdump: -dr
%{
  load riscv;
  fun pokefmt_expr_printer = (any i32) void:
  {
    printf ("%u32x", i32 as uint<32>);
  }
}%
.*:[    ]+file format .*


Disassembly of section .text:

0+000 <target>:
#...
[       ]+40:[  ]+%(+(rv32_auipc :rd 0 :imm 0))%[  ]+auipc[        ]+zero,0x0
%{
  /* Change the expression printer to accept RV32_Insn.  */
  fun pokefmt_expr_printer = (any rv32insn) void:
  {
    printf ("%u32x", +(rv32insn as RV32_Insn));
  }
}%[       ]+44:[  ]+%(rv32_lw :rd 0 :rs1 0 :imm 0)%[  ]+lw[   ]+zero,0\(zero\) # 0 .*

will be transformed to:

#as: -march=rv32i
#objdump: -dr

.*:[    ]+file format .*


Disassembly of section .text:

0+000 <target>:
#...
[       ]+40:[  ]+00000017[  ]+auipc[        ]+zero,0x0
[       ]+44:[  ]+00002003[  ]+lw[   ]+zero,0\(zero\) # 0 .*