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