OILS / pea / header.py View on Github | oilshell.org

84 lines, 40 significant
1from dataclasses import dataclass
2import ast
3from ast import AST, Module, ClassDef, FunctionDef, Assign
4from pprint import pprint
5import sys
6
7from typing import Any
8
9from mycpp import pass_state
10
11
12def log(msg: str, *args: Any) -> None:
13 if args:
14 msg = msg % args
15 #print('%.2f %s' % (time.time() - START_TIME, msg), file=sys.stderr)
16 print(msg, file=sys.stderr)
17
18
19@dataclass
20class PyFile:
21 filename: str
22 namespace: str # C++ namespace
23 module: ast.Module # parsed representation
24
25
26class Program:
27 """A program is a collection of PyFiles."""
28
29 def __init__(self) -> None:
30 self.py_files: list[PyFile] = []
31
32 # As we parse, we add modules, and fill in the dictionaries with parsed
33 # types. Then other passes can retrieve the types with the same
34 # dictionaries.
35
36 # right now types are modules? Could change that
37 self.func_types: dict[FunctionDef, AST] = {}
38 self.method_types: dict[FunctionDef, AST] = {}
39 self.class_types: dict[ClassDef, Module] = {}
40 self.assign_types: dict[Assign, Module] = {}
41
42 # like mycpp: type and variable string. TODO: We shouldn't flatten it to a
43 # C type until later.
44 #
45 # Note: ImplPass parses the types. So I guess this could be limited to
46 # that?
47 # DoFunctionMethod() could make two passes?
48 # 1. collect vars
49 # 2. print code
50
51 self.local_vars: dict[FunctionDef, list[tuple[str, str]]] = {}
52
53 # ForwardDeclPass:
54 # OnMethod()
55 # OnSubclass()
56
57 # Then
58 # Calculate()
59 #
60 # PrototypesPass: # IsVirtual
61 self.virtual = pass_state.Virtual()
62
63 self.stats: dict[str, int] = {
64 # parsing stats
65 'num_files': 0,
66 'num_funcs': 0,
67 'num_classes': 0,
68 'num_methods': 0,
69 'num_assign': 0,
70
71 # ConstPass stats
72 'num_strings': 0,
73 }
74
75 def PrintStats(self) -> None:
76 pprint(self.stats, stream=sys.stderr)
77 print('', file=sys.stderr)
78
79
80class TypeSyntaxError(Exception):
81
82 def __init__(self, lineno: int, code_str: str):
83 self.lineno = lineno
84 self.code_str = code_str