/ scripts / phase0 / function_puller.py
function_puller.py
 1  import sys
 2  from typing import List
 3  
 4  
 5  def get_spec(file_name: str) -> List[str]:
 6      code_lines = []
 7      pulling_from = None
 8      current_name = None
 9      current_typedef = None
10      type_defs = []
11      for linenum, line in enumerate(open(sys.argv[1]).readlines()):
12          line = line.rstrip()
13          if pulling_from is None and len(line) > 0 and line[0] == '#' and line[-1] == '`':
14              current_name = line[line[:-1].rfind('`') + 1: -1]
15          if line[:9] == '```python':
16              assert pulling_from is None
17              pulling_from = linenum + 1
18          elif line[:3] == '```':
19              if pulling_from is None:
20                  pulling_from = linenum
21              else:
22                  if current_typedef is not None:
23                      assert code_lines[-1] == '}'
24                      code_lines[-1] = '})'
25                      current_typedef[-1] = '})'
26                      type_defs.append((current_name, current_typedef))
27                  pulling_from = None
28                  current_typedef = None
29          else:
30              if pulling_from == linenum and line == '{':
31                  code_lines.append('%s = SSZType({' % current_name)
32                  current_typedef = ['global_vars["%s"] = SSZType({' % current_name]
33              elif pulling_from is not None:
34                  # Add some whitespace between functions
35                  if line[:3] == 'def':
36                      code_lines.append('')
37                      code_lines.append('')
38                  code_lines.append(line)
39                  # Remember type def lines
40                  if current_typedef is not None:
41                      current_typedef.append(line)
42              elif pulling_from is None and len(line) > 0 and line[0] == '|':
43                  row = line[1:].split('|')
44                  if len(row) >= 2:
45                      for i in range(2):
46                          row[i] = row[i].strip().strip('`')
47                          if '`' in row[i]:
48                              row[i] = row[i][:row[i].find('`')]
49                      eligible = True
50                      if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':
51                          eligible = False
52                      for c in row[0]:
53                          if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':
54                              eligible = False
55                      if eligible:
56                          code_lines.append(row[0] + ' = ' + (row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')))
57      # Build type-def re-initialization
58      code_lines.append('')
59      code_lines.append('def init_SSZ_types():')
60      code_lines.append('    global_vars = globals()')
61      for ssz_type_name, ssz_type in type_defs:
62          code_lines.append('')
63          for type_line in ssz_type:
64              code_lines.append('    ' + type_line)
65      code_lines.append('\n')
66      code_lines.append('ssz_types = [' + ', '.join([f'\'{ssz_type_name}\'' for (ssz_type_name, _) in type_defs]) + ']')
67      code_lines.append('\n')
68      code_lines.append('def get_ssz_type_by_name(name: str) -> SSZType:')
69      code_lines.append('    return globals()[name]')
70      code_lines.append('')
71      return code_lines