Showing
5 changed files
with
230 additions
and
12 deletions
cctlib/cast.py
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
... | @@ -177,7 +177,14 @@ class CodeGenVisitor (Visitor) : | ... | @@ -177,7 +177,14 @@ class CodeGenVisitor (Visitor) : |
177 | def concat (cls, outfile, chunks) : | 177 | def concat (cls, outfile, chunks) : |
178 | outfile.write("# Generated by cct\n" | 178 | outfile.write("# Generated by cct\n" |
179 | "# Franck Pommereau (2018)\n" | 179 | "# Franck Pommereau (2018)\n" |
180 | - "# Adapted from Atul Varma's c.py (Spring 2004)\n") | 180 | + "# Adapted from Atul Varma's c.py (Spring 2004)\n\n") |
181 | + outfile.write("#\n" | ||
182 | + "# on computer start: call main and halt\n" | ||
183 | + "#\n\n" | ||
184 | + "IRQ0:\n" | ||
185 | + " set R9 @main\n" | ||
186 | + " call R9\n" | ||
187 | + " halt\n") | ||
181 | for c in chunks : | 188 | for c in chunks : |
182 | s = c.curr_str.getvalue() | 189 | s = c.curr_str.getvalue() |
183 | if s.strip() : | 190 | if s.strip() : |
... | @@ -194,13 +201,6 @@ class CodeGenVisitor (Visitor) : | ... | @@ -194,13 +201,6 @@ class CodeGenVisitor (Visitor) : |
194 | outfile.write("\n#\n# string literals from file %r\n#\n\n" | 201 | outfile.write("\n#\n# string literals from file %r\n#\n\n" |
195 | % c.path) | 202 | % c.path) |
196 | outfile.write(s) | 203 | outfile.write(s) |
197 | - outfile.write("\n#\n" | ||
198 | - "# call main\n" | ||
199 | - "#\n\n" | ||
200 | - "IRQ0:\n" | ||
201 | - " set R9 @main\n" | ||
202 | - " call R9\n" | ||
203 | - " halt\n") | ||
204 | 204 | ||
205 | def _calc_function_var_addrs(self, symtab, last_fp_loc): | 205 | def _calc_function_var_addrs(self, symtab, last_fp_loc): |
206 | self._calc_function_arg_addrs(symtab) | 206 | self._calc_function_arg_addrs(symtab) |
... | @@ -353,7 +353,7 @@ class CodeGenVisitor (Visitor) : | ... | @@ -353,7 +353,7 @@ class CodeGenVisitor (Visitor) : |
353 | 353 | ||
354 | label_str = "_LC%d" % self.__str_literal_label | 354 | label_str = "_LC%d" % self.__str_literal_label |
355 | self.str_literal_dict[str] = label_str | 355 | self.str_literal_dict[str] = label_str |
356 | - str = str.replace('\n', '\\12') | 356 | + str = str.replace('\n', '\\n') |
357 | self.str_literal_str.write("""%s:\n str "%s\\0"\n""" % (label_str, str)) | 357 | self.str_literal_str.write("""%s:\n str "%s\\0"\n""" % (label_str, str)) |
358 | self.__class__.__str_literal_label += 1 | 358 | self.__class__.__str_literal_label += 1 |
359 | return label_str | 359 | return label_str | ... | ... |
... | @@ -340,11 +340,9 @@ class SymtabVisitor(Visitor): | ... | @@ -340,11 +340,9 @@ class SymtabVisitor(Visitor): |
340 | # TODO: might be best to just move this to the code | 340 | # TODO: might be best to just move this to the code |
341 | # generation phase, since this doesn't have anything to | 341 | # generation phase, since this doesn't have anything to |
342 | # do with symbol table generation. | 342 | # do with symbol table generation. |
343 | - param_num = 0 | 343 | + for param_num, param in enumerate(node.nodes): |
344 | - for param in node.nodes: | ||
345 | param.accept(self) | 344 | param.accept(self) |
346 | param.param_num = param_num | 345 | param.param_num = param_num |
347 | - param_num += 1 | ||
348 | 346 | ||
349 | def vTranslationUnit(self, node): | 347 | def vTranslationUnit(self, node): |
350 | self.root_symtab = Symtab() | 348 | self.root_symtab = Symtab() | ... | ... |
cctlib/parser.py
0 → 100644
1 | +import pycparser | ||
2 | + | ||
3 | +from . import cast | ||
4 | + | ||
5 | +def _coord (node) : | ||
6 | + if node.coord is not None : | ||
7 | + return {"lineno" : node.coord.line, | ||
8 | + "colno" : node.coord.column - 1, | ||
9 | + "filename" : node.coord.file} | ||
10 | + else : | ||
11 | + return {} | ||
12 | + | ||
13 | +class ast2ast (object) : | ||
14 | + def __call__ (self, node) : | ||
15 | + return getattr(self, "v" + node.__class__.__name__)(node) | ||
16 | + | ||
17 | + # # This is the top of the AST, representing a single C file (a | ||
18 | + # # translation unit in K&R jargon). It contains a list of | ||
19 | + # # "external-declaration"s, which is either declarations (Decl), | ||
20 | + # # Typedef or function definitions (FuncDef). | ||
21 | + # # | ||
22 | + # FileAST: [ext**] | ||
23 | + def vFileAST (self, node) : | ||
24 | + ret = cast.TranslationUnit(None, **_coord(node)) | ||
25 | + for _, child in node.children() : | ||
26 | + ret.add(self(child)) | ||
27 | + return ret | ||
28 | + | ||
29 | + # # name: the variable being declared | ||
30 | + # # quals: list of qualifiers (const, volatile) | ||
31 | + # # funcspec: list function specifiers (i.e. inline in C99) | ||
32 | + # # storage: list of storage specifiers (extern, register, etc.) | ||
33 | + # # type: declaration type (probably nested with all the modifiers) | ||
34 | + # # init: initialization value, or None | ||
35 | + # # bitsize: bit field size, or None | ||
36 | + # # | ||
37 | + # Decl: [name, quals, storage, funcspec, type*, init*, bitsize*] | ||
38 | + def vDecl (self, node) : | ||
39 | + typ = self(node.type) | ||
40 | + ret = cast.Declaration(node.name, typ, **_coord(node)) | ||
41 | + ret.extern = "extern" in node.storage | ||
42 | + ret.static = "static" in node.quals | ||
43 | + return ret | ||
44 | + | ||
45 | + # # A typedef declaration. | ||
46 | + # # Very similar to Decl, but without some attributes | ||
47 | + # # | ||
48 | + # Typedef: [name, quals, storage, type*] | ||
49 | + def vTypedef (self, node) : | ||
50 | + raise NotImplementedError("typdef") | ||
51 | + | ||
52 | + # # type <decl>(args) | ||
53 | + # # | ||
54 | + # FuncDecl: [args*, type*] | ||
55 | + def vFuncDecl (self, node) : | ||
56 | + return cast.FunctionType(self(node.args), self(node.type)) | ||
57 | + | ||
58 | + # # a list of comma separated function parameter declarations | ||
59 | + # # | ||
60 | + # ParamList: [params**] | ||
61 | + def vParamList (self, node) : | ||
62 | + pass | ||
63 | + | ||
64 | + # # A base type declaration | ||
65 | + # # | ||
66 | + # TypeDecl: [declname, quals, type*] | ||
67 | + def vTypeDecl (self, node) : | ||
68 | + pass | ||
69 | + | ||
70 | + # # Function definition: a declarator for the function name and | ||
71 | + # # a body, which is a compound statement. | ||
72 | + # # There's an optional list of parameter declarations for old | ||
73 | + # # K&R-style definitions | ||
74 | + # # | ||
75 | + # FuncDef: [decl*, param_decls**, body*] | ||
76 | + def vFuncDef (self, node) : | ||
77 | + pass | ||
78 | + | ||
79 | + # # ArrayDecl is a nested declaration of an array with the given type. | ||
80 | + # # dim: the dimension (for example, constant 42) | ||
81 | + # # dim_quals: list of dimension qualifiers, to support C99's allowing 'const' | ||
82 | + # # and 'static' within the array dimension in function declarations. | ||
83 | + # ArrayDecl: [type*, dim*, dim_quals] | ||
84 | + | ||
85 | + # ArrayRef: [name*, subscript*] | ||
86 | + | ||
87 | + # # op: =, +=, /= etc. | ||
88 | + # # | ||
89 | + # Assignment: [op, lvalue*, rvalue*] | ||
90 | + | ||
91 | + # BinaryOp: [op, left*, right*] | ||
92 | + | ||
93 | + # Break: [] | ||
94 | + | ||
95 | + # Case: [expr*, stmts**] | ||
96 | + | ||
97 | + # Cast: [to_type*, expr*] | ||
98 | + | ||
99 | + # # Compound statement in C99 is a list of block items (declarations or | ||
100 | + # # statements). | ||
101 | + # # | ||
102 | + # Compound: [block_items**] | ||
103 | + | ||
104 | + # # Compound literal (anonymous aggregate) for C99. | ||
105 | + # # (type-name) {initializer_list} | ||
106 | + # # type: the typename | ||
107 | + # # init: InitList for the initializer list | ||
108 | + # # | ||
109 | + # CompoundLiteral: [type*, init*] | ||
110 | + | ||
111 | + # # type: int, char, float, etc. see CLexer for constant token types | ||
112 | + # # | ||
113 | + # Constant: [type, value] | ||
114 | + | ||
115 | + # Continue: [] | ||
116 | + | ||
117 | + # DeclList: [decls**] | ||
118 | + | ||
119 | + # Default: [stmts**] | ||
120 | + | ||
121 | + # DoWhile: [cond*, stmt*] | ||
122 | + | ||
123 | + # # Represents the ellipsis (...) parameter in a function | ||
124 | + # # declaration | ||
125 | + # # | ||
126 | + # EllipsisParam: [] | ||
127 | + | ||
128 | + # # An empty statement (a semicolon ';' on its own) | ||
129 | + # # | ||
130 | + # EmptyStatement: [] | ||
131 | + | ||
132 | + # # Enumeration type specifier | ||
133 | + # # name: an optional ID | ||
134 | + # # values: an EnumeratorList | ||
135 | + # # | ||
136 | + # Enum: [name, values*] | ||
137 | + | ||
138 | + # # A name/value pair for enumeration values | ||
139 | + # # | ||
140 | + # Enumerator: [name, value*] | ||
141 | + | ||
142 | + # # A list of enumerators | ||
143 | + # # | ||
144 | + # EnumeratorList: [enumerators**] | ||
145 | + | ||
146 | + # # A list of expressions separated by the comma operator. | ||
147 | + # # | ||
148 | + # ExprList: [exprs**] | ||
149 | + | ||
150 | + # # for (init; cond; next) stmt | ||
151 | + # # | ||
152 | + # For: [init*, cond*, next*, stmt*] | ||
153 | + | ||
154 | + # # name: Id | ||
155 | + # # args: ExprList | ||
156 | + # # | ||
157 | + # FuncCall: [name*, args*] | ||
158 | + | ||
159 | + # Goto: [name] | ||
160 | + | ||
161 | + # ID: [name] | ||
162 | + | ||
163 | + # # Holder for types that are a simple identifier (e.g. the built | ||
164 | + # # ins void, char etc. and typedef-defined types) | ||
165 | + # # | ||
166 | + # IdentifierType: [names] | ||
167 | + | ||
168 | + # If: [cond*, iftrue*, iffalse*] | ||
169 | + | ||
170 | + # # An initialization list used for compound literals. | ||
171 | + # # | ||
172 | + # InitList: [exprs**] | ||
173 | + | ||
174 | + # Label: [name, stmt*] | ||
175 | + | ||
176 | + # # A named initializer for C99. | ||
177 | + # # The name of a NamedInitializer is a sequence of Nodes, because | ||
178 | + # # names can be hierarchical and contain constant expressions. | ||
179 | + # # | ||
180 | + # NamedInitializer: [name**, expr*] | ||
181 | + | ||
182 | + # PtrDecl: [quals, type*] | ||
183 | + | ||
184 | + # Return: [expr*] | ||
185 | + | ||
186 | + # # name: struct tag name | ||
187 | + # # decls: declaration of members | ||
188 | + # # | ||
189 | + # Struct: [name, decls**] | ||
190 | + | ||
191 | + # # type: . or -> | ||
192 | + # # name.field or name->field | ||
193 | + # # | ||
194 | + # StructRef: [name*, type, field*] | ||
195 | + | ||
196 | + # Switch: [cond*, stmt*] | ||
197 | + | ||
198 | + # # cond ? iftrue : iffalse | ||
199 | + # # | ||
200 | + # TernaryOp: [cond*, iftrue*, iffalse*] | ||
201 | + | ||
202 | + # Typename: [name, quals, type*] | ||
203 | + | ||
204 | + # UnaryOp: [op, expr*] | ||
205 | + | ||
206 | + # # name: union tag name | ||
207 | + # # decls: declaration of members | ||
208 | + # # | ||
209 | + # Union: [name, decls**] | ||
210 | + | ||
211 | + # While: [cond*, stmt*] | ||
212 | + | ||
213 | + # Pragma: [string] | ||
214 | + | ||
215 | +def parse (path, *cpp_args) : | ||
216 | + ast = pycparser.parse_file(path, use_cpp=True, cpp_args=list(cpp_args)) | ||
217 | + return ast2ast()(ast) | ||
218 | + | ||
219 | +if __name__ == "__main__" : | ||
220 | + tree = parse(",test.c", "-DTTC") |
-
Please register or login to post a comment