diff --git a/scripts/expressions_from_blocks.py b/scripts/expressions_from_blocks.py new file mode 100644 index 00000000..7205d622 --- /dev/null +++ b/scripts/expressions_from_blocks.py @@ -0,0 +1,47 @@ +""" +Script that computes all the expressions in a Yul JSON +""" +import sys +from typing import List, Dict +from parser.parser import parse_CFG +from parser.cfg_instruction import CFGInstruction + + +def create_expression(instruction: CFGInstruction, term_map: Dict[str, str]) -> str: + term_args = [] + for in_arg in instruction.in_args: + term_args.append(term_map.get(in_arg, in_arg)) + if len(term_args) > 0: + term_args_str = '(' + ', '.join(term_args) + ')' + else: + term_args_str = "" + full_term_repr = instruction.get_op_name() + term_args_str + + # Only store the term repr if there is more than one element + if len(instruction.out_args) == 1: + term_map[instruction.out_args[0]] = full_term_repr + + # We need to store a distinct term for each value produced by the opcode + elif len(instruction.out_args) > 1: + for i, out_arg in enumerate(instruction.out_args): + term_map[out_arg] = f"{full_term_repr}_{i}" + + return full_term_repr + + +def compute_expressions(instructions: List[CFGInstruction]) -> List[str]: + """ + Returns the list of all expressions generated by the instructions in the list + """ + term_map = dict() + return [create_expression(instruction, term_map) for instruction in instructions if instruction.op != "PhiFunction"] + + +if __name__ == "__main__": + input_file = sys.argv[1] + cfg = parse_CFG(input_file) + + for block_list_name, block_list in cfg.block_list.items(): + print("Blocks in...", block_list_name) + for block_name, cfg_block in block_list.blocks.items(): + print(block_name, compute_expressions(cfg_block.get_instructions()))