Source code for cnorm.passes.to_c

from pyrser import meta
from pyrser import fmt
from pyrser.passes import to_yml
from cnorm import nodes


# DECL

@meta.add_method(nodes.CType)
[docs]def ctype_to_c(self, func_var_name=""): # our global declarator declarator = fmt.sep("", []) # typename or full decl if func_var_name != "": declarator.lsdata.append(func_var_name) # intern prototype if hasattr(self, 'params'): # param list pf = fmt.sep(", ", []) for p in self.params: if p.ctype is not None: if isinstance(p.ctype, nodes.CType): pf.lsdata.append(p.ctype.ctype_to_c(p._name)) if hasattr(self, '_ellipsis'): pf.lsdata.append('...') if len(pf.lsdata) > 0: declarator.lsdata.append(fmt.block('(', ')', pf)) else: declarator.lsdata.append('()') # for externalize the last qualifier qualextern = None # final output decl_ls = fmt.sep(" ", []) if self.link() is not None: # add all qualifiers if len(declarator.lsdata) > 0: qual_list = declarator else: qual_list = fmt.sep(" ", []) unqual_list = self.link() # qualification of declaration while unqual_list is not None: if isinstance(unqual_list, nodes.ParenType): # surround previous defs by () qual_list = fmt.sep("", [fmt.block("(", ")", [qual_list])]) # () provide param for function pointers if len(unqual_list.params) > 0: pf = fmt.sep(", ", []) for p in unqual_list.params: pf.lsdata.append(p.ctype.ctype_to_c(p._name)) if hasattr(unqual_list, '_ellipsis'): pf.lsdata.append('...') qual_list.lsdata.append(fmt.block('(', ')', pf)) if isinstance(unqual_list, nodes.PointerType): qual_list.lsdata.insert(0, "*") if isinstance(unqual_list, nodes.AttrType): qual_list.lsdata.insert(0, unqual_list._attr + " ") if isinstance(unqual_list, nodes.QualType): if unqual_list._qualifier != nodes.Qualifiers.AUTO: if unqual_list.link() is None: qualextern = unqual_list else: qual_list.lsdata.insert( 0, nodes.Qualifiers.rmap[ unqual_list._qualifier ].lower() + " " ) if isinstance(unqual_list, nodes.ArrayType): # collect all consecutive array consec_ary = [] consec_ary.append(unqual_list) unqual_list = unqual_list.link() while ((unqual_list is not None and isinstance(unqual_list, nodes.ArrayType))): consec_ary.append(unqual_list) unqual_list = unqual_list.link() reordered = [] for ary in consec_ary: if ary.expr is not None: ary_expr = None if hasattr(ary.expr, 'to_c'): ary_expr = ary.expr.to_c() reordered.insert(0, fmt.block("[", "]", [ary_expr])) else: reordered.insert(0, "[]") qual_list.lsdata.extend(reordered) # rewind one for last sentence unqual_list = consec_ary[-1] unqual_list = unqual_list.link() # add qualified declarator decl_ls.lsdata.append(qual_list) elif len(declarator.lsdata) > 0: # no qualifiers just the name decl_ls.lsdata.append(declarator) # for enum if hasattr(self, 'enums'): enums = fmt.sep(",\n", []) for enum in self.enums: if enum.expr is not None and hasattr(enum.expr, 'to_c'): enums.lsdata.append( fmt.sep( " = ", [enum.ident, enum.expr.to_c()] )) else: enums.lsdata.append(enum.ident) decl_ls.lsdata.insert(0, fmt.tab(fmt.block("{\n", "}", enums))) # for struct if hasattr(self, 'fields'): fields = [] for field in self.fields: fields.append(field.to_c()) decl_ls.lsdata.insert(0, fmt.tab(fmt.block("{\n", "}", fields))) # just the type name if hasattr(self, 'identifier'): decl_ls.lsdata.insert(0, self.identifier) # attributes composed if hasattr(self, '_attr_composed'): decl_ls.lsdata.insert(0, fmt.sep(" ", self._attr_composed)) # specifier if self._specifier != nodes.Specifiers.AUTO: if self._specifier == nodes.Specifiers.LONGLONG: decl_ls.lsdata.insert(0, "long long") else: decl_ls.lsdata.insert( 0, nodes.Specifiers.rmap[ self._specifier ].lower() ) # sign if hasattr(self, '_sign') and self._sign != nodes.Signs.AUTO: decl_ls.lsdata.insert(0, nodes.Signs.rmap[self._sign].lower()) # qualifier externalized if qualextern is not None: decl_ls.lsdata.insert( 0, nodes.Qualifiers.rmap[ qualextern._qualifier ].lower() ) # End by storage if self._storage != nodes.Storages.AUTO: decl_ls.lsdata.insert(0, nodes.Storages.rmap[self._storage].lower()) return decl_ls
[docs]def decl_to_c(self): decl_ls = self.ctype.ctype_to_c(self._name) # add bitfield if hasattr(self, '_colon_expr'): decl_ls.lsdata.append(":") decl_ls.lsdata.append(self._colon_expr.to_c()) # attributes decl if hasattr(self, '_attr_decl'): decl_ls.lsdata.extend(self._attr_decl) # add initializers if hasattr(self, '_assign_expr'): decl_ls.lsdata.append("=") decl_ls.lsdata.append(self._assign_expr.to_c()) return decl_ls
@meta.add_method(nodes.Decl) def to_c(self): if ((hasattr(self, 'body') and self.body is not None and hasattr(self.body, 'to_c'))): return fmt.sep( "\n", [ self.ctype.ctype_to_c(self._name), self.body.to_c() ] ) else: return fmt.end(';\n', decl_to_c(self)) # STATEMENT @meta.add_method(nodes.For) def to_c(self): init_body = '' if type(self.init) is nodes.Decl: init_body = decl_to_c(self.init) elif self.init is not None and hasattr(self.init, 'expr'): init_body = self.init.expr.to_c() cond_body = '' if self.condition is not None and hasattr(self.condition, 'expr'): cond_body = self.condition.expr.to_c() inc_body = '' if self.increment is not None and hasattr(self.increment, 'to_c'): inc_body = self.increment.to_c() lsfor = [ fmt.sep( " ", [ "for", fmt.block( '(', ')\n', [ fmt.sep( "; ", [ init_body, cond_body, inc_body ] ) ] ) ] ), fmt.tab(self.body.to_c()) ] return fmt.end("", lsfor) @meta.add_method(nodes.If) def to_c(self): thenbody = ';\n' if self.thencond is not None and hasattr(self.thencond, 'to_c'): thenbody = fmt.tab(self.thencond.to_c()) lsif = [ fmt.sep(" ", ["if", fmt.block('(', ')\n', [self.condition.to_c()])]), thenbody ] if self.elsecond is not None and hasattr(self.elsecond, 'to_c'): lsif.append("else\n") lsif.append(fmt.tab(self.elsecond.to_c())) return fmt.end("", lsif) @meta.add_method(nodes.While) def to_c(self): body = ';\n' if self.body is not None and hasattr(self.body, 'to_c'): body = fmt.tab(self.body.to_c()) lswh = [ fmt.sep( " ", [ "while", fmt.block('(', ')\n', [self.condition.to_c()]) ]), body ] return fmt.sep("", lswh) @meta.add_method(nodes.Do) def to_c(self): body = ';\n' if self.body is not None and hasattr(self.body, 'to_c'): body = fmt.tab(self.body.to_c()) lsdo = [ fmt.sep("\n", ["do", body]), fmt.sep( " ", [ "while", fmt.block('(', ');\n', [self.condition.to_c()]) ] ) ] return fmt.sep("", lsdo) @meta.add_method(nodes.Switch) def to_c(self): body = ';\n' if self.body is not None and hasattr(self.body, 'to_c'): body = fmt.tab(self.body.to_c()) lswh = [ fmt.sep( " ", [ "switch", fmt.block('(', ')\n', [self.condition.to_c()]) ] ), body ] return fmt.sep("", lswh) @meta.add_method(nodes.Label) def to_c(self): return fmt.end(":\n", [self.value]) @meta.add_method(nodes.LoopControl) def to_c(self): return fmt.end(";\n", [self.value]) @meta.add_method(nodes.Branch) def to_c(self): body = ';\n' if self.expr is not None and hasattr(self.expr, 'to_c'): body = self.expr.to_c() return fmt.end(";\n", [fmt.sep(" ", [self.value, body])]) @meta.add_method(nodes.Case) def to_c(self): return fmt.end(":\n", [fmt.sep(" ", [self.value, self.expr.to_c()])]) @meta.add_method(nodes.ExprStmt) def to_c(self): return fmt.end(";\n", [self.expr.to_c()]) @meta.add_method(nodes.BlockStmt) def to_c(self): lsbody = [] for e in self.body: if e is not None and hasattr(e, 'to_c'): lsbody.append(e.to_c()) return fmt.block("{\n", "}\n", fmt.tab(lsbody)) @meta.add_method(nodes.BlockExpr) def to_c(self): lsbody = [] for e in self.body: if e is not None and hasattr(e, 'to_c'): lsbody.append(e.to_c()) return fmt.block("({\n", "})", fmt.tab(lsbody)) @meta.add_method(nodes.RootBlockStmt) def to_c(self): lsbody = [] for e in self.body: lsbody.append(e.to_c()) return fmt.sep("", lsbody) # EXPRESSION @meta.add_method(nodes.Func) def to_c(self): lsparams = [] # TODO: add forward declarations for p in self.params: lsparams.append(p.to_c()) return fmt.sep( "", [ self.call_expr.to_c(), fmt.block( '(', ')', [fmt.sep(', ', lsparams)] ) ] ) @meta.add_method(nodes.BlockInit) def to_c(self): lsbody = [] i = 0 for it in self.body: subbody = it.to_c() if hasattr(it, 'designation'): subbody = fmt.sep("", [it.designation, subbody]) if isinstance(subbody, fmt.block): lsbody.append(fmt.tab(["\n", subbody])) else: lsbody.append(subbody) i += 1 if i > 8: lsbody[-1] = "\n" + str(lsbody[-1]) i = 0 return fmt.block("{ ", " }", fmt.tab(fmt.sep(', ', lsbody))) @meta.add_method(nodes.Ternary) def to_c(self): condexpr = None if self.params[0] is not None and hasattr(self.params[0], 'to_c'): condexpr = self.params[0].to_c() thenexpr = None if self.params[1] is not None and hasattr(self.params[1], 'to_c'): thenexpr = self.params[1].to_c() content = fmt.sep("", [condexpr, ' ? ', thenexpr]) if len(self.params) > 2: elseexpr = None if self.params[2] is not None and hasattr(self.params[2], 'to_c'): elseexpr = self.params[2].to_c() content.lsdata.append(' : ') content.lsdata.append(elseexpr) return content @meta.add_method(nodes.Binary) def to_c(self): lsparams = [] for p in self.params: lsparams.append(p.to_c()) if type(self.call_expr) is nodes.Raw and self.call_expr.value == ",": return fmt.sep(str(self.call_expr.to_c()) + ' ', lsparams) return fmt.sep(' ' + str(self.call_expr.to_c()) + ' ', lsparams) @meta.add_method(nodes.Cast) def to_c(self): return fmt.sep( " ", [ fmt.block( "(", ")", self.params[0].ctype_to_c() # type ), self.params[1].to_c() # expr ] ) @meta.add_method(nodes.Unary) def to_c(self): return fmt.sep("", [self.call_expr.to_c(), self.params[0].to_c()]) @meta.add_method(nodes.Sizeof) def to_c(self): if isinstance(self.params[0], nodes.CType): return fmt.sep( " ", [ self.call_expr.to_c(), # sizeof/typeof ... fmt.block("(", ")", self.params[0].ctype_to_c()) # type/expr ] ) else: return fmt.sep(" ", [self.call_expr.to_c(), self.params[0].to_c()]) @meta.add_method(nodes.Dot) def to_c(self): return fmt.sep(".", [self.call_expr.to_c(), self.params[0].to_c()]) @meta.add_method(nodes.Arrow) def to_c(self): return fmt.sep("->", [self.call_expr.to_c(), self.params[0].to_c()]) @meta.add_method(nodes.Paren) def to_c(self): return fmt.block('(', ')', [self.params[0].to_c()]) @meta.add_method(nodes.Array) def to_c(self): return fmt.sep( "", [ self.call_expr.to_c(), # expr fmt.block('[', ']', [self.params[0].to_c()]) # index ] ) @meta.add_method(nodes.Post) def to_c(self): return fmt.sep("", [self.params[0].to_c(), self.call_expr.to_c()]) @meta.add_method(nodes.Terminal)
[docs]def to_c(self): return self.value