17db96d56Sopenharmony_ciimport re 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_cifrom ._regexes import ( 47db96d56Sopenharmony_ci GLOBAL as _GLOBAL, 57db96d56Sopenharmony_ci) 67db96d56Sopenharmony_cifrom ._common import ( 77db96d56Sopenharmony_ci log_match, 87db96d56Sopenharmony_ci parse_var_decl, 97db96d56Sopenharmony_ci set_capture_groups, 107db96d56Sopenharmony_ci) 117db96d56Sopenharmony_cifrom ._compound_decl_body import DECL_BODY_PARSERS 127db96d56Sopenharmony_ci#from ._func_body import parse_function_body 137db96d56Sopenharmony_cifrom ._func_body import parse_function_statics as parse_function_body 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ciGLOBAL = set_capture_groups(_GLOBAL, ( 177db96d56Sopenharmony_ci 'EMPTY', 187db96d56Sopenharmony_ci 'COMPOUND_LEADING', 197db96d56Sopenharmony_ci 'COMPOUND_KIND', 207db96d56Sopenharmony_ci 'COMPOUND_NAME', 217db96d56Sopenharmony_ci 'FORWARD_KIND', 227db96d56Sopenharmony_ci 'FORWARD_NAME', 237db96d56Sopenharmony_ci 'MAYBE_INLINE_ACTUAL', 247db96d56Sopenharmony_ci 'TYPEDEF_DECL', 257db96d56Sopenharmony_ci 'TYPEDEF_FUNC_PARAMS', 267db96d56Sopenharmony_ci 'VAR_STORAGE', 277db96d56Sopenharmony_ci 'FUNC_INLINE', 287db96d56Sopenharmony_ci 'VAR_DECL', 297db96d56Sopenharmony_ci 'FUNC_PARAMS', 307db96d56Sopenharmony_ci 'FUNC_DELIM', 317db96d56Sopenharmony_ci 'FUNC_LEGACY_PARAMS', 327db96d56Sopenharmony_ci 'VAR_INIT', 337db96d56Sopenharmony_ci 'VAR_ENDING', 347db96d56Sopenharmony_ci)) 357db96d56Sopenharmony_ciGLOBAL_RE = re.compile(rf'^ \s* {GLOBAL}', re.VERBOSE) 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_cidef parse_globals(source, anon_name): 397db96d56Sopenharmony_ci for srcinfo in source: 407db96d56Sopenharmony_ci m = GLOBAL_RE.match(srcinfo.text) 417db96d56Sopenharmony_ci if not m: 427db96d56Sopenharmony_ci # We need more text. 437db96d56Sopenharmony_ci continue 447db96d56Sopenharmony_ci for item in _parse_next(m, srcinfo, anon_name): 457db96d56Sopenharmony_ci if callable(item): 467db96d56Sopenharmony_ci parse_body = item 477db96d56Sopenharmony_ci yield from parse_body(source) 487db96d56Sopenharmony_ci else: 497db96d56Sopenharmony_ci yield item 507db96d56Sopenharmony_ci else: 517db96d56Sopenharmony_ci # We ran out of lines. 527db96d56Sopenharmony_ci if srcinfo is not None: 537db96d56Sopenharmony_ci srcinfo.done() 547db96d56Sopenharmony_ci return 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_cidef _parse_next(m, srcinfo, anon_name): 587db96d56Sopenharmony_ci ( 597db96d56Sopenharmony_ci empty, 607db96d56Sopenharmony_ci # compound type decl (maybe inline) 617db96d56Sopenharmony_ci compound_leading, compound_kind, compound_name, 627db96d56Sopenharmony_ci forward_kind, forward_name, maybe_inline_actual, 637db96d56Sopenharmony_ci # typedef 647db96d56Sopenharmony_ci typedef_decl, typedef_func_params, 657db96d56Sopenharmony_ci # vars and funcs 667db96d56Sopenharmony_ci storage, func_inline, decl, 677db96d56Sopenharmony_ci func_params, func_delim, func_legacy_params, 687db96d56Sopenharmony_ci var_init, var_ending, 697db96d56Sopenharmony_ci ) = m.groups() 707db96d56Sopenharmony_ci remainder = srcinfo.text[m.end():] 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci if empty: 737db96d56Sopenharmony_ci log_match('global empty', m) 747db96d56Sopenharmony_ci srcinfo.advance(remainder) 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci elif maybe_inline_actual: 777db96d56Sopenharmony_ci log_match('maybe_inline_actual', m) 787db96d56Sopenharmony_ci # Ignore forward declarations. 797db96d56Sopenharmony_ci # XXX Maybe return them too (with an "isforward" flag)? 807db96d56Sopenharmony_ci if not maybe_inline_actual.strip().endswith(';'): 817db96d56Sopenharmony_ci remainder = maybe_inline_actual + remainder 827db96d56Sopenharmony_ci yield srcinfo.resolve(forward_kind, None, forward_name) 837db96d56Sopenharmony_ci if maybe_inline_actual.strip().endswith('='): 847db96d56Sopenharmony_ci # We use a dummy prefix for a fake typedef. 857db96d56Sopenharmony_ci # XXX Ideally this case would not be caught by MAYBE_INLINE_ACTUAL. 867db96d56Sopenharmony_ci _, name, data = parse_var_decl(f'{forward_kind} {forward_name} fake_typedef_{forward_name}') 877db96d56Sopenharmony_ci yield srcinfo.resolve('typedef', data, name, parent=None) 887db96d56Sopenharmony_ci remainder = f'{name} {remainder}' 897db96d56Sopenharmony_ci srcinfo.advance(remainder) 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci elif compound_kind: 927db96d56Sopenharmony_ci kind = compound_kind 937db96d56Sopenharmony_ci name = compound_name or anon_name('inline-') 947db96d56Sopenharmony_ci # Immediately emit a forward declaration. 957db96d56Sopenharmony_ci yield srcinfo.resolve(kind, name=name, data=None) 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci # un-inline the decl. Note that it might not actually be inline. 987db96d56Sopenharmony_ci # We handle the case in the "maybe_inline_actual" branch. 997db96d56Sopenharmony_ci srcinfo.nest( 1007db96d56Sopenharmony_ci remainder, 1017db96d56Sopenharmony_ci f'{compound_leading or ""} {compound_kind} {name}', 1027db96d56Sopenharmony_ci ) 1037db96d56Sopenharmony_ci def parse_body(source): 1047db96d56Sopenharmony_ci _parse_body = DECL_BODY_PARSERS[compound_kind] 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ci data = [] # members 1077db96d56Sopenharmony_ci ident = f'{kind} {name}' 1087db96d56Sopenharmony_ci for item in _parse_body(source, anon_name, ident): 1097db96d56Sopenharmony_ci if item.kind == 'field': 1107db96d56Sopenharmony_ci data.append(item) 1117db96d56Sopenharmony_ci else: 1127db96d56Sopenharmony_ci yield item 1137db96d56Sopenharmony_ci # XXX Should "parent" really be None for inline type decls? 1147db96d56Sopenharmony_ci yield srcinfo.resolve(kind, data, name, parent=None) 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ci srcinfo.resume() 1177db96d56Sopenharmony_ci yield parse_body 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci elif typedef_decl: 1207db96d56Sopenharmony_ci log_match('typedef', m) 1217db96d56Sopenharmony_ci kind = 'typedef' 1227db96d56Sopenharmony_ci _, name, data = parse_var_decl(typedef_decl) 1237db96d56Sopenharmony_ci if typedef_func_params: 1247db96d56Sopenharmony_ci return_type = data 1257db96d56Sopenharmony_ci # This matches the data for func declarations. 1267db96d56Sopenharmony_ci data = { 1277db96d56Sopenharmony_ci 'storage': None, 1287db96d56Sopenharmony_ci 'inline': None, 1297db96d56Sopenharmony_ci 'params': f'({typedef_func_params})', 1307db96d56Sopenharmony_ci 'returntype': return_type, 1317db96d56Sopenharmony_ci 'isforward': True, 1327db96d56Sopenharmony_ci } 1337db96d56Sopenharmony_ci yield srcinfo.resolve(kind, data, name, parent=None) 1347db96d56Sopenharmony_ci srcinfo.advance(remainder) 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci elif func_delim or func_legacy_params: 1377db96d56Sopenharmony_ci log_match('function', m) 1387db96d56Sopenharmony_ci kind = 'function' 1397db96d56Sopenharmony_ci _, name, return_type = parse_var_decl(decl) 1407db96d56Sopenharmony_ci func_params = func_params or func_legacy_params 1417db96d56Sopenharmony_ci data = { 1427db96d56Sopenharmony_ci 'storage': storage, 1437db96d56Sopenharmony_ci 'inline': func_inline, 1447db96d56Sopenharmony_ci 'params': f'({func_params})', 1457db96d56Sopenharmony_ci 'returntype': return_type, 1467db96d56Sopenharmony_ci 'isforward': func_delim == ';', 1477db96d56Sopenharmony_ci } 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci yield srcinfo.resolve(kind, data, name, parent=None) 1507db96d56Sopenharmony_ci srcinfo.advance(remainder) 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_ci if func_delim == '{' or func_legacy_params: 1537db96d56Sopenharmony_ci def parse_body(source): 1547db96d56Sopenharmony_ci yield from parse_function_body(source, name, anon_name) 1557db96d56Sopenharmony_ci yield parse_body 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci elif var_ending: 1587db96d56Sopenharmony_ci log_match('global variable', m) 1597db96d56Sopenharmony_ci kind = 'variable' 1607db96d56Sopenharmony_ci _, name, vartype = parse_var_decl(decl) 1617db96d56Sopenharmony_ci data = { 1627db96d56Sopenharmony_ci 'storage': storage, 1637db96d56Sopenharmony_ci 'vartype': vartype, 1647db96d56Sopenharmony_ci } 1657db96d56Sopenharmony_ci yield srcinfo.resolve(kind, data, name, parent=None) 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci if var_ending == ',': 1687db96d56Sopenharmony_ci # It was a multi-declaration, so queue up the next one. 1697db96d56Sopenharmony_ci _, qual, typespec, _ = vartype.values() 1707db96d56Sopenharmony_ci remainder = f'{storage or ""} {qual or ""} {typespec} {remainder}' 1717db96d56Sopenharmony_ci srcinfo.advance(remainder) 1727db96d56Sopenharmony_ci 1737db96d56Sopenharmony_ci if var_init: 1747db96d56Sopenharmony_ci _data = f'{name} = {var_init.strip()}' 1757db96d56Sopenharmony_ci yield srcinfo.resolve('statement', _data, name=None) 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci else: 1787db96d56Sopenharmony_ci # This should be unreachable. 1797db96d56Sopenharmony_ci raise NotImplementedError 180