00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 """
00032 @package C AST Builder
00033
00034 PythonからCのツリーを作るためのインターフェース
00035
00036 このインターフェースを使って、expr, stmt, translation_unitを作ったあと、
00037 それぞれ、Builder.build_expr, Builder.build_stmt, Builder.translation_unitを呼ぶと、
00038 CTRUMP ASTが得られる
00039
00040 このインターフェースが直接CTRUMP ASTを作らない理由は、
00041 色々とPython用に融通を利かせたかったため
00042 (例えば、CTRUMP ASTの中にPythonのリストを持たせるのは難しいなど)
00043
00044 以下、このインターフェースで作られるASTをPython AST、
00045 CTRUMPの内部構造のASTをCTRUMP ASTと表現する
00046
00047
00048 <h3> 型から宣言を取得する方法 </h3>
00049 (Pointer to Int 型から int * という宣言を取得したい等)
00050
00051 build_declarator_and_typespecを呼べば texpr で変数宣言するための、
00052
00053 declarator と typespecが得られる。
00054 <code>
00055 def build_declarator_and_typespec(builder, texpr, var_sym,
00056 qual_flags=0, gccattr_flags=0, aligned=ctrump.ALIGN_UNSPECIFIED,
00057 emit_struct_definition = False):
00058 ''':return:(flags, gccattr_flags, alignd, declarator, type_spec)'''
00059 </code>
00060
00061 build_declarator_and_typespec は5個の値を含むタプルを返す
00062 それぞれ、
00063 flags - decl-specifier に付くqualifier
00064 gccattr_flags - declaration に付くGCC attribute
00065 aligned - declaration に付くGCC attribute
00066 declarator - 引数に渡したvar_symを宣言する宣言子を含む宣言子
00067 typespec - type-specifier
00068 になっている。
00069 あとは、これらを組み合わせればdeclarationを構築できる
00070 (複雑なのはCのせいであって、作者の責任ではない。)
00071
00072 """
00073
00074 import ctrump
00075
00076 def gcd(x,y):
00077 while y != 0:
00078 r = x%y
00079 x = y
00080 y = r
00081
00082 if x < 0:
00083 return -x
00084 return x
00085
00086 def lcm(x,y):
00087 return (x*y)/gcd(x,y)
00088
00089 def align_lcm(x,y):
00090 if x == 0 or x == ctrump.ALIGN_UNSPECIFIED:
00091 return y
00092 if y == 0 or y == ctrump.ALIGN_UNSPECIFIED:
00093 return x
00094 return lcm(x,y)
00095
00096 def flatten(dest,l):
00097 for i in l:
00098 if type(i) == list:
00099 flatten(dest, i)
00100 elif i != None:
00101 dest.append(i)
00102
00103 class Scope:
00104 """変数スコープ
00105 (まだきちんとした管理がされていないのでスコープを抜けてもクリアされない)
00106
00107 このオブジェクトに対して、辞書引きを行うと、その名前で宣言された変数が取得される。
00108
00109 s = b.scope
00110 b.decl(b.int_, "foobar")
00111 s["foobar"] # <= foobar 変数を取得
00112 s.foobar # 上に同じ
00113 """
00114 def __init__(self, g):
00115 self.__dict__['_scope_e'] = g;
00116 self.__dict__['_scope_decls'] = {}
00117
00118 def __getattr__(self, name):
00119 return getattr(self, '_scope_decls')[str(name)]
00120 def __getitem__(self, name):
00121 return getattr(self, '_scope_decls')[str(name)]
00122
00123 def __setitem__(self, name, val):
00124 scope_decls = getattr(self, '_scope_decls')
00125 scope_decls[str(name)] = val
00126
00127 def __setattr__(self, name, val):
00128 e = getattr(self,'_scope_e')
00129 e.stmt(e.assign(self.__scope_decls[str(name)], val))
00130
00131 def ptr_to_spec_decl(builder, pointer_to, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition):
00132 """ポインタ型をポインタの宣言子に変換する"""
00133 b = builder.b
00134 (fl,gfl,al,child_decl,unqual_typespec) = build_declarator_and_typespec(builder, pointer_to, var_sym,
00135 emit_struct_definition = emit_struct_definition)
00136 ptr_decl = b.declarator_node_pointer(code = ctrump.DECLARATOR_POINTER,
00137 decl = child_decl,
00138 qual_flags = qual_flags,
00139 flags = gccattr_flags,
00140 aligned = aligned)
00141 return (fl, gfl, al, ptr_decl, unqual_typespec)
00142
00143
00144 def struct_texpr_to_typespec(builder, texpr, emit_struct_definition = False):
00145 """構造体型をtype-specifierに変換する"""
00146 type_name = texpr.name
00147 fields = texpr.fields
00148 aligned = texpr.aligned
00149 gccflags = texpr.flags
00150 b = builder.b
00151
00152 decls = []
00153 for i in fields:
00154 (spec, name, struct_decl) = builder.type_name_pair_to_struct_decl(i.type,i.name)
00155 decl = b.struct_decl_decl(code=ctrump.STRUCT_DECL_FIELDS,
00156 decls=[struct_decl], flags=0, aligned=ctrump.ALIGN_UNSPECIFIED,
00157 stor_class=ctrump.STOR_CLASS_FIELD,
00158 type_spec=spec, qual_flags=0, func_spec=ctrump.FUNC_SPEC_UNSPECIFIED,
00159 num_decls=1)
00160 decls.append(decl)
00161
00162 builder.struct_scope[type_name] = True
00163
00164
00165 if emit_struct_definition:
00166 if texpr.code == ctrump.TYPE_STRUCT:
00167 code = ctrump.TYPESPEC_STRUCT_DEFINITION
00168 return b.typespec_struct_definition(code = code,
00169 name = type_name,
00170 record_type = texpr,
00171 decls = decls,
00172 num_field = len(decls),
00173 aligned = aligned,
00174 flags = gccflags,
00175 num_decl = len(decls))
00176 else:
00177 code = ctrump.TYPESPEC_UNION_DEFINITION
00178 return b.typespec_union_definition(code = code,
00179 name = type_name,
00180 record_type = texpr,
00181 decls = decls,
00182 num_field = len(decls),
00183 aligned = aligned,
00184 flags = gccflags,
00185 num_decl = len(decls))
00186 else:
00187 if texpr.code == ctrump.TYPE_STRUCT:
00188 return b.typespec_struct_name(code = ctrump.TYPESPEC_STRUCT_NAME,
00189 texpr = texpr,
00190 name = texpr.name)
00191 else:
00192 return b.typespec_union_name(code = ctrump.TYPESPEC_UNION_NAME,
00193 texpr = texpr,
00194 name = texpr.name)
00195
00196
00197 def build_declarator_and_typespec(builder, texpr, var_sym,
00198 qual_flags=0, gccattr_flags=0, aligned=ctrump.ALIGN_UNSPECIFIED,
00199 emit_struct_definition = False):
00200 ''':return:(flags, gccattr_flags, alignd, declarator, type_spec)'''
00201 b = builder.b
00202
00203 def texpr_term(spec):
00204 if var_sym:
00205 declarator = b.declarator_node_identifier(code=ctrump.DECLARATOR_IDENTIFIER,
00206 identifier=builder.get_symbol(var_sym))
00207 else:
00208 declarator = b.declarator_node(code=ctrump.DECLARATOR_EMPTY)
00209 return (qual_flags, gccattr_flags, aligned,
00210 declarator,spec)
00211
00212 if type(texpr) == ctrump.texprType:
00213 if texpr.code == ctrump.TYPE_BUILTIN:
00214 type_spec = b.typespec_builtin(code=ctrump.TYPESPEC_BUILTIN, texpr=texpr)
00215 return texpr_term(type_spec)
00216 elif texpr.code == ctrump.TYPE_QUALIFIED:
00217 cur_flags = texpr.qual_flags|qual_flags
00218 cur_align = align_lcm(aligned, texpr.aligned)
00219 cur_gflags = texpr.flags
00220
00221 return build_declarator_and_typespec(builder, texpr.unqualified_type, var_sym, cur_flags, cur_gflags, cur_align)
00222 elif texpr.code == ctrump.TYPE_POINTER:
00223 return ptr_to_spec_decl(builder, texpr.pointer_to, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition)
00224 elif texpr.code == ctrump.TYPE_STRUCT or texpr.code == ctrump.TYPE_UNION:
00225 if texpr.name:
00226 name = texpr.name
00227 if ((name in builder.struct_scope) or
00228 (not texpr.is_completed)):
00229
00230 if texpr.code == ctrump.TYPE_STRUCT:
00231 struct_spec = b.typespec_struct_name(code = ctrump.TYPESPEC_STRUCT_NAME,
00232 texpr = texpr,
00233 name = texpr.name)
00234 else:
00235 struct_spec = b.typespec_union_name(code = ctrump.TYPESPEC_UNION_NAME,
00236 texpr = texpr,
00237 name = texpr.name)
00238
00239 else:
00240 struct_spec = struct_texpr_to_typespec(builder, texpr)
00241 return texpr_term(struct_spec)
00242 else:
00243 raise Exception("build anonymous struct spec")
00244 elif texpr.code == ctrump.TYPE_TYPEDEF_NAME:
00245 type_spec = b.typespec_typedef_name(code=ctrump.TYPESPEC_TYPEDEF_NAME,
00246 texpr=texpr,
00247 name=texpr.def_name)
00248 return texpr_term(type_spec);
00249 elif texpr.code == ctrump.TYPE_ARRAY:
00250 (fl, gfl, al, elem_decl, unqual_typespec) = build_declarator_and_typespec(builder, texpr.array_of,var_sym,
00251 qual_flags, gccattr_flags, aligned)
00252 array_decl = b.declarator_node_array(code = ctrump.DECLARATOR_ARRAY,
00253 decl = elem_decl,
00254 qual_flags = fl,
00255 size = builder.build_expr(texpr.size))
00256 return (fl, gfl, al, array_decl, unqual_typespec)
00257 else:
00258 raise Exception("invalid texpr `%s'"%texpr)
00259 else:
00260 return texpr.build_declarator_and_typespec(builder, var_sym, qual_flags, gccattr_flags, aligned,
00261 emit_struct_definition = emit_struct_definition)
00262
00263 class TypeSpec(object):
00264 '''型指定子
00265
00266 build_typespec()でCTRUMP ASTのtypespecを取得できる
00267 build_declarator_and_typespec()でCTRUMP ASTのdeclarator と typespecが取得できる
00268 build_type_expr() でこのTypeSpecが示すCTRUMP ASTの型情報を取得できる
00269 '''
00270 def build_typespec(self, builder):
00271 ':return:AST of typespec'
00272 raise NotImplementedError(self.build_typespec)
00273
00274 def build_declarator_and_typespec(self, builder, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition):
00275 ':return:(flags, gccattr_flags, alignd, declarator, type_spec)'
00276 spec = self.build_typespec(builder, emit_struct_definition)
00277 b = builder.b
00278 if var_sym:
00279 declarator = b.declarator_node_identifier(code=ctrump.DECLARATOR_IDENTIFIER,
00280 identifier=builder.get_symbol(var_sym))
00281 else:
00282 declarator = b.declarator_node(code=ctrump.DECLARATOR_EMPTY)
00283
00284 return (qual_flags, gccattr_flags, aligned, declarator, spec)
00285
00286 def build_type_expr(self,b):
00287 return b.build_type_expr(self.type_expr)
00288
00289
00290 class PointerToSpec(TypeSpec):
00291 '''ポインタ型指定子'''
00292 def __init__(self, pointer_to):
00293 super(PointerToSpec,self).__init__()
00294 self.pointer_to = pointer_to
00295
00296 def build_declarator_and_typespec(self, builder, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition):
00297 return ptr_to_spec_decl(builder, self.pointer_to, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition)
00298
00299 def build_type_expr(self, builder):
00300 b = builder.b
00301 return b.pointer_type(builder.build_type_expr(self.pointer_to))
00302
00303 class ArrayTypeSpec(TypeSpec):
00304 '''配列型指定子'''
00305 def __init__(self, array_of, size):
00306 super(ArrayTypeSpec,self).__init__(self)
00307 self.array_of = array_of
00308 self.size = size
00309
00310 def build_type_expr(self,builder):
00311 b = builder.b
00312 return b.array_type(builder.build_type_expr(self.array_of),
00313 self.size)
00314
00315 def build_declarator_and_typespec(self, builder, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition):
00316 b = builder.b
00317 (fl,gfl,al,array_of_decl,unqual_typespec) = build_declarator_and_typespec(builder, self.array_of, var_sym,
00318 qual_flags, gccattr_flags, aligned,
00319 emit_struct_definition)
00320 declarator = b.declarator_node_array(code = ctrump.DECLARATOR_ARRAY,
00321 decl = array_of_decl,
00322 qual_flags = 0,
00323 size = builder.build_expr(self.size))
00324 return (fl,gfl,al,declarator,unqual_typespec)
00325
00326 class QualTypeSpec(TypeSpec):
00327 '''修飾型指定子'''
00328 def __init__(self, t, qual_flags, gcc_aligned, gcc_flags):
00329 super(QualTypeSpec,self).__init__()
00330 self.t = t
00331 self.qual_flags = qual_flags
00332 self.gcc_aligned = gcc_aligned
00333 self.gcc_flags = gcc_flags
00334
00335 def build_type_expr(self,builder):
00336 b = builder.b
00337 return b.qualified_type(builder.build_type_expr(self.t),
00338 self.qual_flags,
00339 self.gcc_aligned,
00340 self.gcc_flags)
00341
00342 def build_declarator_and_typespec(self, builder, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition):
00343 b = builder.b
00344 (fl,gfl,al,declarator,unqual_typespec) = build_declarator_and_typespec(builder, self.t, var_sym,
00345 qual_flags, gccattr_flags, aligned, emit_struct_definition)
00346 return (fl|self.qual_flags,self.gcc_flags|gfl,align_lcm(self.gcc_aligned,al),declarator,unqual_typespec)
00347
00348
00349 class StructTypeSpec(TypeSpec):
00350 '''構造体型指定子'''
00351 STRUCT=0
00352 UNION=1
00353
00354 def __init__(self, tn, te, decls, code, attr_flags, attr_align):
00355 self.type_name = tn
00356 self.type_expr = te
00357 self.code = code
00358 self.decls = decls
00359 self.attr_flags = attr_flags
00360 self.attr_align = attr_align
00361
00362 def build_typespec(self,builder, emit_struct_definition):
00363 b = builder.b
00364 d = self.decls
00365
00366 if (self.type_name != None) and emit_struct_definition:
00367 if self.code == self.STRUCT:
00368 return b.typespec_struct_definition(code=ctrump.TYPESPEC_STRUCT_DEFINITION,
00369 name=builder.get_symbol(self.type_name),
00370 record_type=self.type_expr,
00371 decls=d,
00372 num_field=len(d),
00373 num_decl=len(d),
00374 flags=self.attr_flags,
00375 aligned=self.attr_align)
00376 elif self.code == self.UNION:
00377 return b.typespec_union_definition(code=ctrump.TYPESPEC_UNION_DEFINITION,
00378 name=builder.get_symbol(self.type_name),
00379 record_type=self.type_expr,
00380 decls=d,
00381 num_field=len(d),
00382 num_decl=len(d),
00383 flags=self.attr_flags,
00384 aligned=self.attr_align)
00385 else:
00386 if self.code == self.STRUCT:
00387 return b.typespec_struct_name(code=ctrump.TYPESPEC_STRUCT_NAME,
00388 texpr=self.type_expr,
00389 name=builder.get_symbol(self.type_name))
00390 elif self.code == self.UNION:
00391 return b.typespec_union_name(code=ctrump.TYPESPEC_UNION_NAME,
00392 texpr=self.type_expr,
00393 name=builder.get_symbol(self.type_name))
00394
00395
00396 raise Exception('%d'%self.code)
00397
00398 class IncompleteStructTypeSpec(TypeSpec):
00399 '''不完全構造体型指定子'''
00400
00401 STRUCT=0
00402 UNION=1
00403
00404 def __init__(self, name, code):
00405 self.name = name
00406 self.code = code
00407
00408 def build_typespec(self,builder, emit_struct_definition):
00409 b = builder.b
00410 name = builder.get_symbol(self.name)
00411 if self.code == self.STRUCT:
00412 self.type_expr = builder.b.incomplete_struct(ctrump.TYPE_STRUCT, name)
00413 return b.typespec_struct_name(code = ctrump.TYPESPEC_STRUCT_NAME,
00414 texpr = self.type_expr,
00415 name = name)
00416 else:
00417 self.type_expr = builder.b.incomplete_struct(ctrump.TYPE_STRUCT, name)
00418 return b.typespec_union_name(code = ctrump.TYPESPEC_UNION_NAME,
00419 texpr = self.type_expr,
00420 name = name)
00421
00422
00423 raise Exception('%d'%self.code)
00424
00425
00426 class TypedefNameSpec(TypeSpec):
00427 '''typedef された名前型指定子'''
00428
00429 def __init__(self, type_name, type_expr):
00430 self.type_name = type_name
00431 self.type_expr = type_expr
00432
00433 def build_typespec(self,builder, emit_struct_definition):
00434 b = builder.b
00435 texpr = builder.build_type_expr(self.type_expr)
00436 return b.typespec_typedef_name(code=ctrump.TYPESPEC_TYPEDEF_NAME,
00437 texpr=texpr,
00438 name=self.type_name)
00439
00440 class FuncTypeSpec(TypeSpec):
00441 '''関数型指定子'''
00442
00443 def __init__(self, ret_type, arg_types, has_unspecified_arg=False):
00444 self.ret_type = ret_type
00445 self.arg_types = arg_types
00446 self.has_unspecified_arg = has_unspecified_arg
00447
00448 def build_type_expr(self, builder):
00449 b = builder.b
00450 arg_texpr = [builder.build_type_expr(ts) for (ts,name) in self.arg_types]
00451 return b.func_type(builder.build_type_expr(self.ret_type),
00452 arg_texpr,
00453 self.has_unspecified_arg)
00454
00455 def build_declarator_and_typespec(self, builder, var_sym, qual_flags, gccattr_flags, aligned, emit_struct_definition):
00456 b = builder.b
00457 (fl,gfl,al,ret_declarator,ret_unqual_typespec) = build_declarator_and_typespec(builder, self.ret_type,
00458 var_sym, qual_flags,
00459 gccattr_flags, aligned, emit_struct_definition)
00460 arg_declarators = []
00461
00462 for (typespec,name) in self.arg_types:
00463 (fl,gfl,al,declarator_node,unqual_typespec) = build_declarator_and_typespec(builder, typespec,
00464 name, 0, 0, ctrump.ALIGN_UNSPECIFIED,
00465 emit_struct_definition)
00466 declarator = b.declarator(nodes = declarator_node,
00467 flags = gfl,
00468 aligned = al)
00469
00470 param = b.declarator_param(decl = declarator,
00471 flags = fl,
00472 aligned = ctrump.ALIGN_UNSPECIFIED,
00473 stor_class = ctrump.STOR_CLASS_ARGMENT,
00474 type_spec = unqual_typespec,
00475 qual_flags = 0,
00476 func_spec = ctrump.FUNC_SPEC_UNSPECIFIED)
00477
00478 arg_declarators.append(param)
00479
00480 declarator = b.declarator_node_param_typelist(code = ctrump.DECLARATOR_PARAM_TYPELIST,
00481 decl = ret_declarator,
00482 has_unspecified_arg = self.has_unspecified_arg,
00483 args = arg_declarators,
00484 num_args = len(arg_declarators))
00485
00486 return (fl,gfl,al,declarator,ret_unqual_typespec)
00487
00488 class ExprBase(object):
00489 '''式オブジェクト
00490
00491 Python式を書けばPython ASTの式が構築できるオブジェクト
00492
00493 builder = Builder()
00494 a = builder.literal(3)
00495 b = builder.literal(4)
00496
00497 c = a+b
00498
00499 とすると、変数'c'は "3+4" を表現するPython ASTになる
00500
00501 大体の場合にうまくいくように見えるが、いくつか注意点がある
00502
00503 1. 左辺値にPython ASTを持ってくること
00504
00505 メソッドが呼ばれるのは左辺値なので、
00506
00507 builder = Builder()
00508 a = builder.literal(3)
00509 b = 4
00510
00511 c = a+b
00512
00513 これはうまくいくが、
00514
00515 builder = Builder()
00516 a = 3
00517 b = builder.literal(4)
00518
00519 c = a+b
00520
00521 これはうまくいかない
00522
00523
00524 2. 比較演算ができない
00525
00526 Python AST式オブジェクトに'=='を適用した場合、
00527 返すオブジェクトは、比較式を表現するオブジェクトであり、比較結果ではない
00528
00529 builder = Builder()
00530 a = builder.literal(4)
00531 b = builder.literal(100)
00532
00533 c = (a == b)
00534 if c:
00535 print 'xx'
00536
00537 c が指すオブジェクトは '4 == 100' というPython ASTであり、True, Falseではない
00538 (なので、条件は常に真である)
00539 '''
00540
00541 def __init__(self, builder):
00542 self.builder = builder
00543
00544 def __getitem__(self, subscript):
00545 return ArrRef(self,subscript,self.builder)
00546 def __add__(self,rhs):
00547 return Binary(self,rhs,Binary.ADD,self.builder)
00548 def __sub__(self,rhs):
00549 return Binary(self,rhs,Binary.SUB,self.builder)
00550 def __mul__(self,rhs):
00551 return Binary(self,rhs,Binary.MUL,self.builder)
00552 def __div__(self,rhs):
00553 return Binary(self,rhs,Binary.DIV,self.builder)
00554 def __xor__(self,rhs):
00555 return Binary(self,rhs,Binary.BXOR,self.builder)
00556 def __mod__(self,rhs):
00557 return Binary(self,rhs,Binary.MOD,self.builder)
00558 def __lt__(self,rhs):
00559 return Binary(self,rhs,Binary.LT,self.builder)
00560 def __gt__(self,rhs):
00561 return Binary(self,rhs,Binary.GT,self.builder)
00562 def __eq__(self,rhs):
00563 return Binary(self,rhs,Binary.EQ,self.builder)
00564 def __ne__(self,rhs):
00565 return Binary(self,rhs,Binary.NE,self.builder)
00566 def __lshift__(self,rhs):
00567 return Binary(self,rhs,Binary.LSHIFT,self.builder)
00568 def __rshift__(self,rhs):
00569 return Binary(self,rhs,Binary.RSHIFT,self.builder)
00570 def __and__(self, rhs):
00571 return Binary(self,rhs,Binary.BAND,self.builder)
00572
00573 def member(self, name, code=ctrump.EXPR_MEMBER_REF):
00574 builder = self.builder
00575 b = builder.b
00576 sym = builder.get_symbol(name)
00577 prec = ctrump.expr_prec(code)
00578 return MemberRef(code = code,
00579 obj_expr = self,
00580 member_name = sym,
00581 builder = builder)
00582
00583 def ptr_member(self, name):
00584 return self.member(name, ctrump.EXPR_PTR_MEMBER_REF)
00585
00586 def typing(self, builder):
00587
00588 return builder.int_
00589
00590 class Expr(ExprBase):
00591 '''CTRUMP ASTを表現するオブジェクト'''
00592 def __init__(self, expr, builder):
00593 super(Expr, self).__init__(builder)
00594 self.expr = expr
00595
00596 def build_expr(self, parent_prec):
00597 b = self.builder
00598 cur_prec = ctrump.expr_prec(self.expr.code)
00599 num_paren = 0
00600
00601 if (parent_prec > cur_prec):
00602 num_paren = 1
00603 return b.emit_paren(self.expr, num_paren)
00604
00605 class EmptyExpr(ExprBase):
00606 ''' '''
00607 def __init__(self, builder):
00608 super(EmptyExpr,self).__init__(builder)
00609
00610 def build_expr(self, parent_prec):
00611 b = self.builder.b
00612 return b.expr(code=ctrump.EXPR_EMPTY, type = self.builder.int_)
00613
00614 class Call(ExprBase):
00615 '''関数呼び出し'''
00616 def __init__(self, func, builder, *args):
00617 super(Call,self).__init__(builder)
00618 self.args = args
00619 self.func = func
00620
00621 def build_expr(self, parent_prec):
00622 builder = self.builder
00623 b = builder.b
00624 cur_prec = ctrump.expr_prec(ctrump.EXPR_CALL)
00625 num_paren = 0
00626 if parent_prec > cur_prec:
00627 num_paren = 1
00628
00629 func_expr = builder.build_expr(self.func, expr_prec=cur_prec)
00630 args = [builder.build_expr(x,0) for x in self.args]
00631 return builder.emit_paren(b.expr_call(code=ctrump.EXPR_CALL,
00632 type=self.typing(builder),
00633 func_expr=func_expr,
00634 args=args,
00635 num_args=len(args)),
00636 num_paren)
00637
00638 class IntegerLiteral(ExprBase):
00639 '''整数リテラル'''
00640 def __init__(self, val, builder):
00641 super(IntegerLiteral, self).__init__(builder)
00642 self.value = val
00643
00644 def build_expr(self, parent_prec):
00645 return self.builder.b.expr_sint_literal(value = self.value,
00646 code = ctrump.EXPR_SINT_LITERAL,
00647 type = self.builder.int_,
00648 literal = str(self.value))
00649
00650 class CastTo(ExprBase):
00651 '''キャスト'''
00652 def __init__(self, cast_to, expr, builder):
00653 self.cast_to = cast_to
00654 self.expr = expr
00655 self.builder = builder
00656
00657 def build_expr(self, parent_prec):
00658 cur_prec = ctrump.expr_prec(ctrump.EXPR_CAST)
00659 num_paren = 0
00660 if parent_prec > cur_prec:
00661 num_paren = 1
00662 builder = self.builder
00663 b = builder.b
00664 e = builder.build_expr(self.expr, expr_prec=cur_prec)
00665 (fl,gfl,al,ret_declarator,ret_typespec) = build_declarator_and_typespec(builder, self.cast_to, None)
00666
00667 declarator = b.declarator(nodes = ret_declarator,
00668 flags = gfl,
00669 aligned = al)
00670
00671 cast_texpr = builder.build_type_expr(self.cast_to)
00672
00673 return builder.emit_paren(b.expr_cast(type = cast_texpr,
00674 abstract_decl = declarator,
00675 aligned = ctrump.ALIGN_UNSPECIFIED,
00676 flags = 0,
00677 qual_flags = fl,
00678 stor_class = ctrump.STOR_CLASS_AUTO_UNSPECIFIED,
00679 type_spec = ret_typespec,
00680 func_spec = ctrump.FUNC_SPEC_UNSPECIFIED,
00681 code = ctrump.EXPR_CAST,
00682 expr = e,
00683 cast_to = cast_texpr),
00684 num_paren)
00685
00686 class Func(ExprBase):
00687 '''関数'''
00688 def __init__(self, func_expr, builder):
00689 super(Func,self).__init__(builder)
00690 self.func_expr = func_expr
00691 self.builder = builder
00692
00693 def __call__(self, *args):
00694 return Call(self, self.builder, *args)
00695
00696 def build_expr(self, parent_prec):
00697 return self.builder.build_expr(self.func_expr, parent_prec)
00698
00699 class Binary(ExprBase):
00700 '''二項演算'''
00701 ADD = ctrump.EXPR_BIN_ADD
00702 SUB = ctrump.EXPR_BIN_SUB
00703 MUL = ctrump.EXPR_BIN_MUL
00704 DIV = ctrump.EXPR_BIN_DIV
00705 MOD = ctrump.EXPR_BIN_MOD
00706 ASSIGN = ctrump.EXPR_BIN_ASSIGN
00707 GT = ctrump.EXPR_BIN_GT
00708 LT = ctrump.EXPR_BIN_LT
00709 EQ = ctrump.EXPR_BIN_EQ
00710 NE = ctrump.EXPR_BIN_NE
00711 LAND = ctrump.EXPR_BIN_LAND
00712 LOR = ctrump.EXPR_BIN_LOR
00713 BAND = ctrump.EXPR_BIN_BAND
00714 BOR = ctrump.EXPR_BIN_BOR
00715 BXOR = ctrump.EXPR_BIN_BXOR
00716 LSHIFT = ctrump.EXPR_BIN_LSHIFT
00717 RSHIFT = ctrump.EXPR_BIN_RSHIFT
00718
00719 LT = ctrump.EXPR_BIN_LT
00720 GT = ctrump.EXPR_BIN_GT
00721 LE = ctrump.EXPR_BIN_LE
00722 GE = ctrump.EXPR_BIN_GE
00723 EQ = ctrump.EXPR_BIN_EQ
00724 NE = ctrump.EXPR_BIN_NE
00725
00726 op2str_table = {}
00727 op2str_table[ADD] = '+'
00728 op2str_table[SUB] = '-'
00729 op2str_table[MUL] = '*'
00730 op2str_table[DIV] = '/'
00731 op2str_table[MOD] = '%'
00732 op2str_table[LAND] = '&&'
00733 op2str_table[LOR] = '||'
00734 op2str_table[BAND] = '&'
00735 op2str_table[BOR] = '|'
00736 op2str_table[BXOR] = '^'
00737
00738 op2str_table[ASSIGN] = '='
00739 op2str_table[GT] = '>'
00740 op2str_table[GE] = '>='
00741 op2str_table[LT] = '<'
00742 op2str_table[LE] = '<='
00743 op2str_table[NE] = '!='
00744 op2str_table[EQ] = '=='
00745
00746 def __init__(self,lhs,rhs,op,builder):
00747 super(Binary,self).__init__(builder)
00748 self.op = op
00749 self.lhs = lhs
00750 self.rhs = rhs
00751
00752 def __repr__(self):
00753 return '%s %s %s'%(self.lhs, self.op2str_table[self.op], self.rhs)
00754
00755 def build_expr(self, parent_prec):
00756 builder = self.builder
00757 cur_prec = ctrump.expr_prec(self.op)
00758 num_paren = 0
00759 if parent_prec > cur_prec:
00760 num_paren = 1
00761 b = builder.b
00762 return builder.emit_paren(b.expr_binary(code=self.op, type=self.typing(builder),
00763 lhs=builder.build_expr(self.lhs, cur_prec),
00764 rhs=builder.build_expr(self.rhs, cur_prec)),
00765 num_paren=num_paren)
00766
00767 class ArrRef(ExprBase):
00768 '''配列参照'''
00769 def __init__(self,array,subscript,builder):
00770 super(ArrRef,self).__init__(builder)
00771 self.op = ctrump.EXPR_ARRREF
00772 self.array = array
00773 self.subscript = subscript
00774
00775 def __repr__(self):
00776 return '%s[%s]'%(self.array, self.subscript)
00777
00778 def build_expr(self, parent_prec):
00779 builder = self.builder
00780 cur_prec = ctrump.expr_prec(self.op)
00781 num_paren = 0
00782 if parent_prec > cur_prec:
00783 num_paren = 1
00784 b = builder.b
00785 return builder.emit_paren(b.expr_arr_ref(code=self.op,
00786 array=builder.build_expr(self.array, cur_prec),
00787 type=self.typing(builder),
00788 subscript=builder.build_expr(self.subscript, 0)),
00789 num_paren=num_paren)
00790
00791
00792 class MemberRef(ExprBase):
00793 '''メンバ参照'''
00794 def __init__(self, code, obj_expr, member_name, builder):
00795 super(MemberRef,self).__init__(builder)
00796 self.code = code
00797 self.obj_expr = obj_expr
00798 self.member_name = member_name
00799
00800 def __repr__(self):
00801 return '%s.%s'%(self.obj_expr, self.member_name)
00802
00803 def build_expr(self, parent_prec):
00804 builder = self.builder
00805 cur_prec = ctrump.expr_prec(self.code)
00806 num_paren = 0
00807 if parent_prec > cur_prec:
00808 num_paren = 1
00809 b = builder.b
00810 return builder.emit_paren(b.expr_member_ref(code = self.code,
00811 type = self.typing(builder),
00812 obj_expr = builder.build_expr(self.obj_expr,cur_prec),
00813 member_name = self.member_name),
00814 num_paren)
00815
00816 class Var(ExprBase):
00817 '''変数'''
00818 def __init__(self,type,name,var_tree,stor_class,builder):
00819 super(Var,self).__init__(builder)
00820 self.type = type
00821 self.name = name
00822 self.var_tree = var_tree
00823 self.stor_class = stor_class
00824
00825 if self.stor_class == ctrump.STOR_CLASS_TYPEDEF:
00826 s = TypedefNameSpec(name, type)
00827 self.build_declarator_and_typespec = s.build_declarator_and_typespec
00828 self.build_type_expr = s.build_type_expr
00829
00830 def __repr__(self):
00831 return str(self.name)
00832
00833 def build_expr(self, parent_prec):
00834 builder = self.builder
00835 return builder.b.expr_varref(code=ctrump.EXPR_VARREF,
00836 type=builder.build_type_expr(self.type),
00837 pdg=None,
00838 var=self.var_tree)
00839
00840 def member(self, name, code=ctrump.EXPR_MEMBER_REF):
00841 builder = self.builder
00842 b = builder.b
00843 sym = builder.get_symbol(name)
00844 prec = ctrump.expr_prec(code)
00845 return MemberRef(code = code,
00846 obj_expr = self,
00847 member_name = sym,
00848 builder = builder)
00849
00850 class Unary(ExprBase):
00851 '''単項演算'''
00852 PRE_INC=ctrump.EXPR_UNA_PRE_INC
00853 POST_INC=ctrump.EXPR_UNA_POST_INC
00854 ADDR=ctrump.EXPR_UNA_ADDR
00855 SIZEOF=ctrump.EXPR_UNA_SIZEOF
00856 PTRREF=ctrump.EXPR_UNA_PTRREF
00857 BCMPL=ctrump.EXPR_UNA_BCMPL
00858
00859 def __init__(self,expr,op,builder):
00860 super(Unary,self).__init__(builder)
00861 self.expr = expr
00862 self.op = op
00863
00864 def __repr__(self):
00865 if self.op == Unary.PRE_INC:
00866 return '++%s'%(self.expr)
00867 elif self.op == Unary.POST_INC:
00868 return '%s++'%(self.expr)
00869 elif self.op == Unary.ADDR:
00870 return '&%s'%(self.expr)
00871 elif self.op == Unary.PTRREF:
00872 return '*%s'%(self.expr)
00873 else:
00874 return str(self.expr)
00875
00876 def build_expr(self,parent_prec):
00877 builder = self.builder
00878 cur_prec = ctrump.expr_prec(self.op)
00879 num_paren = 0
00880 if parent_prec > cur_prec:
00881 num_paren = 1
00882 b = builder.b
00883 expr=builder.build_expr(self.expr, cur_prec)
00884 if self.op == self.SIZEOF and expr.code != ctrump.EXPR_PAREN:
00885 expr = builder.emit_paren(expr, 1)
00886 return builder.emit_paren(b.expr_unary(code = self.op,
00887 type = self.typing(builder),
00888 expr = expr),
00889 num_paren=num_paren)
00890
00891 class Paren(ExprBase):
00892 '''括弧でくくられた式'''
00893 def __init__(self, expr, builder):
00894 super(Paren,self).__init__(builder)
00895 self.expr = expr
00896
00897 def build_expr(self,parent_prec):
00898 expr = self.builder.build_expr(self.expr)
00899 return self.builder.emit_paren(expr, 1)
00900
00901 def __repr__(self):
00902 return '(' + str(self.expr) + ')'
00903
00904 class SizeofType(ExprBase):
00905 '''sizeof(type)'''
00906 def __init__(self, texpr, builder):
00907 super(SizeofType,self).__init__(builder)
00908 self.texpr = texpr
00909 self.builder = builder
00910
00911 def build_expr(self, parent_prec):
00912 builder = self.builder
00913 cur_prec = ctrump.expr_prec(ctrump.EXPR_SIZEOF_TYPE)
00914 num_paren = 0
00915 if parent_prec > cur_prec:
00916 num_paren = 1
00917 b = builder.b
00918 texpr = builder.build_type_expr(self.texpr)
00919
00920 (fl,gfl,al,ret_declarator,ret_typespec) = build_declarator_and_typespec(builder, texpr, None)
00921
00922 declarator = b.declarator(nodes = ret_declarator,
00923 flags = gfl,
00924 aligned = al)
00925
00926 return builder.emit_paren(b.expr_sizeof_type(type = builder.int_,
00927 texpr = texpr,
00928 abstract_decl = declarator,
00929 aligned = ctrump.ALIGN_UNSPECIFIED,
00930 flags = 0,
00931 qual_flags = fl,
00932 stor_class = ctrump.STOR_CLASS_AUTO_UNSPECIFIED,
00933 type_spec = ret_typespec,
00934 func_spec = ctrump.FUNC_SPEC_UNSPECIFIED,
00935 code = ctrump.EXPR_SIZEOF_TYPE),
00936 num_paren)
00937
00938
00939 class StmtBase(object):
00940 '''文'''
00941 pass
00942
00943 class Stmt(StmtBase):
00944 '''CTRUMP ASTの文を表現するオブジェクト'''
00945 def __init__(self,stmt):
00946 super(Stmt,self).__init__()
00947 self.stmt = stmt
00948
00949 def __repr__(self):
00950 return str(self.stmt)
00951
00952 def build_stmt(self,builder):
00953 return self.stmt
00954
00955 class NewlineStmt(Stmt):
00956 '''改行'''
00957
00958 def __init__(self,stmt):
00959 super(NewlineStmt, self).__init__(stmt)
00960
00961 def build_extdecl(self,builder):
00962 return builder.b.extdecl(code=ctrump.EXT_NEWLINE)
00963
00964 class Decl(StmtBase):
00965 '''宣言'''
00966 def __init__(self,type,name,var,
00967 declarators, decl_with_init_list,
00968 gccattr_flags, aligned, stor_class, flags):
00969 super(Decl,self).__init__()
00970 self.type_spec = type
00971 self.name = name
00972 self.var = var
00973 self.declarators = declarators
00974 self.declarator_with_init_list = decl_with_init_list
00975 self.gccattr_flags = gccattr_flags
00976 self.aligned = aligned
00977 self.stor_class = stor_class
00978 self.flags = flags
00979
00980 def __repr__(self):
00981 return '%s %s;'%(self.type_spec, self.name)
00982
00983 def build_stmt(self, builder):
00984 b = builder.b
00985 return b.stmt_decl(code=ctrump.STMT_DECL,
00986 decls=self.declarator_with_init_list,
00987 num_decls=len(self.declarators),
00988 flags=self.gccattr_flags,
00989 aligned=self.aligned,
00990 stor_class=self.stor_class,
00991 type_spec=self.type_spec, qual_flags=self.flags,
00992 func_spec=ctrump.FUNC_SPEC_UNSPECIFIED)
00993
00994 def build_extdecl(self, builder):
00995 return builder.b.extdecl_obj_def(code = ctrump.EXT_OBJECT_DEFINITION,
00996 decls = self.declarator_with_init_list,
00997 num_decls = len(self.declarators),
00998 flags = self.gccattr_flags,
00999 aligned = self.aligned,
01000 stor_class = self.stor_class,
01001 type_spec = self.type_spec,
01002 qual_flags = self.flags,
01003 func_spec = ctrump.FUNC_SPEC_UNSPECIFIED)
01004
01005 class Compound(StmtBase):
01006 '''複文'''
01007 def __init__(self, body):
01008 super(Compound,self).__init__()
01009 self.body = body
01010 def __repr__(self):
01011 ret = '{\n'
01012 nl = ''
01013 for i in self.body:
01014 ret = ret + nl + str(i)
01015 nl = '\n'
01016 return ret + '\n}'
01017
01018 def build_stmt(self,builder):
01019 flat_body = []
01020 flatten(flat_body, self.body)
01021
01022 stmts = [builder.build_stmt(x) for x in flat_body]
01023 return builder.b.stmt_compound(code = ctrump.STMT_COMPOUND,
01024 items = stmts,
01025 num_item = len(stmts))
01026
01027 class For(StmtBase):
01028 '''for'''
01029 def __init__(self,init, cond, iter, body):
01030 super(For,self).__init__()
01031 self.init = init
01032 self.cond = cond
01033 self.iter = iter
01034 self.body = body
01035
01036 def __repr__(self):
01037 return 'for (%s; %s; %s) %s'%(self.init, self.cond, self.iter, self.body)
01038
01039 def build_stmt(self, builder):
01040 b = builder.b
01041 init_expr = builder.build_expr(self.init)
01042 cond_expr = builder.build_expr(self.cond)
01043 iter_expr = builder.build_expr(self.iter)
01044 body_stmt = builder.build_stmt(self.body)
01045
01046 return b.stmt_for_(code=ctrump.STMT_FOR, body=body_stmt,
01047 init=init_expr,
01048 cond=cond_expr,
01049 iter=iter_expr,
01050 loop_cfg=None)
01051
01052 class If(StmtBase):
01053 '''if'''
01054 def __init__(self, cond, then_body, else_body):
01055 super(If,self).__init__()
01056 self.cond = cond
01057 self.then_body = then_body
01058 self.else_body = else_body
01059
01060 def build_stmt(self, builder):
01061 b = builder.b
01062
01063 cond_expr = builder.build_expr(self.cond)
01064 then_stmt = builder.build_stmt(self.then_body)
01065
01066 if self.else_body:
01067 else_stmt = builder.build_stmt(self.else_body)
01068 return b.stmt_if_else(code = ctrump.STMT_IF_ELSE,
01069 cond = cond_expr,
01070 then_body = then_stmt,
01071 else_body = else_stmt)
01072 else:
01073 return b.stmt_if_(code = ctrump.STMT_IF,
01074 cond = cond_expr,
01075 body = then_stmt)
01076
01077 class FuncArgDecl:
01078 def __init__(self, type_name_list, builder):
01079 arg_typespec_list = []
01080 arg_declarator_list = []
01081 for (type,name) in type_name_list:
01082 arg_typespec_list.append(type)
01083 arg_declarator_list.append(builder.decl(type, name, stor_class=ctrump.STOR_CLASS_ARGMENT))
01084
01085 self.arg_typespec_list = arg_typespec_list
01086 self.arg_declarator_list = arg_declarator_list
01087
01088 class ReturnStmt(StmtBase):
01089 def __init__(self, expr=None):
01090 self.ret_expr = expr
01091
01092 def build_stmt(self, builder):
01093 b = builder.b
01094
01095 if self.ret_expr:
01096 return b.stmt_ret_expr(code = ctrump.STMT_RETURN_EXPR,
01097 retval = builder.build_expr(self.ret_expr))
01098 else:
01099 return b.stmt_return_(code = ctrump.STMT_RETURN)
01100
01101 class FuncDef(StmtBase):
01102 '''関数宣言'''
01103 def __init__(self, ret_type, name, arg_decls, body, has_unspecified_arg):
01104 self.ret_type = ret_type
01105 self.arg_decls = arg_decls
01106 self.body = body
01107 self.name = name
01108 self.has_unspecified_arg = has_unspecified_arg
01109
01110 def build_extdecl(self, builder):
01111 b = builder.b
01112
01113 (fl,gfl,al,ret_declarator,ret_typespec) = build_declarator_and_typespec(builder, self.ret_type, self.name)
01114
01115 param_declarators = []
01116
01117 for i in self.arg_decls.arg_declarator_list:
01118 param_decl = b.declarator_param(decl = i.declarators[0],
01119 flags = i.gccattr_flags,
01120 aligned = i.aligned,
01121 stor_class = ctrump.STOR_CLASS_ARGMENT,
01122 type_spec = i.type_spec,
01123 qual_flags = i.flags,
01124 func_spec = ctrump.FUNC_SPEC_UNSPECIFIED)
01125 param_declarators.append(param_decl)
01126
01127 declarator_node = b.declarator_node_param_typelist(code = ctrump.DECLARATOR_PARAM_TYPELIST,
01128 decl = ret_declarator,
01129 has_unspecified_arg = self.has_unspecified_arg,
01130 args = param_declarators,
01131 num_args = len(param_declarators))
01132 declarator = b.declarator(nodes = declarator_node,
01133 flags = gfl,
01134 aligned = al)
01135
01136 body = [builder.build_stmt(stmt) for stmt in self.body]
01137
01138 return builder.b.extdecl_func_def(code = ctrump.EXT_FUNCTION_DEFINITION,
01139 decl = declarator,
01140 num_item = len(body),
01141 items = body,
01142 oldstyle_decl_list = [],
01143 num_oldstyle_declaration = 0,
01144 flags = 0,
01145 aligned = ctrump.ALIGN_UNSPECIFIED,
01146 stor_class = ctrump.STOR_CLASS_EXTDEF,
01147 type_spec = ret_typespec,
01148 qual_flags = fl,
01149 func_spec = ctrump.FUNC_SPEC_UNSPECIFIED,
01150 cfg = None)
01151
01152
01153 class Include(StmtBase):
01154 def __init__(self, path, quote):
01155 self.path = path
01156 self.quote = quote
01157
01158 def build_extdecl(self, builder):
01159 b = builder.b
01160 return b.extdecl_include_path(code=ctrump.EXT_INCLUDE_PATH,
01161 is_quote=self.quote,
01162 path_str=self.path)
01163
01164
01165
01166 class Builder:
01167 '''Python AST構築器'''
01168 def __init__(self,env):
01169 self.scope = Scope(self)
01170 self.b = ctrump.BuilderType(env)
01171 self.env = env
01172 te = env.type_env
01173 self.t = te
01174 self.int_ = te.sint_type
01175 self.schar = te.schar_type
01176 self.uchar = te.uchar_type
01177 self.puchar = self.pointer_to(te.uchar_type)
01178 self.uint = te.uint_type
01179 self.ullong = te.ulonglong_type
01180 self.void = te.void_type
01181 self.NULL = 'NULL'
01182 self.structs = {}
01183 self.funcs = {}
01184 self.unspec_func_spec = FuncTypeSpec(self.int_, [], True)
01185 self.struct_scope = {}
01186
01187 def build_expr(self,obj,expr_prec=-1):
01188 b = self.b
01189
01190 if isinstance(obj,int):
01191 return b.expr_sint_literal(code=ctrump.EXPR_SINT_LITERAL,
01192 type=self.int_, value=obj,
01193 literal = str(obj))
01194 elif isinstance(obj,str):
01195 return self.emit_paren(b.expr_text(code=ctrump.EXPR_TEXT, type=self.int_, text=obj), 1)
01196 elif isinstance(obj,ExprBase):
01197 return obj.build_expr(expr_prec)
01198
01199 return obj
01200
01201 def build_stmt(self,stmt):
01202 b = self.b
01203 if isinstance(stmt, StmtBase):
01204 return stmt.build_stmt(self)
01205 if isinstance(stmt, list):
01206 c_stmts = []
01207 for i in stmt:
01208 c_stmts.append(self.build_stmt(i))
01209 return b.stmt_stmt_list(code = ctrump.STMT_LIST,
01210 num_stmt = len(c_stmts),
01211 stmts = c_stmts)
01212 if isinstance(stmt, ExprBase):
01213 return b.stmt_expr(code=ctrump.STMT_EXPR, expr=self.build_expr(stmt))
01214 return stmt
01215 raise Exception("fail convert to stmt `%s'"%(stmt))
01216
01217 def get_symbol(self, symstr):
01218 if isinstance(symstr, str):
01219 return self.b.symbol(symstr)
01220 elif isinstance(symstr, ctrump.symbolType):
01221 return symstr
01222 raise Exception(symstr)
01223
01224 def type_name_pair_to_decl(self,tspec,name,init=None, emit_struct_definition=False):
01225 ''':return: (type-spec, name_sym, decl-with-init, declarators)'''
01226
01227 b = self.b
01228
01229 (flags,gccattr_flags,aligned,declarator,type_spec) = build_declarator_and_typespec(self, tspec, name,
01230 emit_struct_definition = emit_struct_definition)
01231
01232 name_sym = self.get_symbol(name)
01233 declarator = b.declarator(nodes=declarator, flags=gccattr_flags, aligned=aligned)
01234 if init != None:
01235 initializer = b.initializer_expr(code=ctrump.INITIALIZER_EXPR, expr=self.build_expr(init))
01236 else:
01237 initializer = b.initializer(code=ctrump.INITIALIZER_EMPTY)
01238 decl_with_init = b.decl_with_init(decl=declarator, initializer=initializer, declared_var=None)
01239
01240 return (type_spec, name_sym, decl_with_init, declarator)
01241
01242 def type_name_pair_to_struct_decl(self,tspec,name,bitfield_expr=None):
01243 ''':return: (type-spec, name_sym, struct_decl)'''
01244 b = self.b
01245
01246 (flags,gccattr_flags,aligned,declarator,type_spec) = build_declarator_and_typespec(self, tspec, name)
01247
01248 name_sym = self.get_symbol(name)
01249 declarator = b.declarator(nodes=declarator, flags=gccattr_flags, aligned=aligned)
01250 struct_declarator = b.struct_declarator(decl=declarator, bitfield_expr=bitfield_expr)
01251
01252 return (type_spec, name_sym, struct_declarator)
01253
01254
01255 def struct(self, struct_name, decls, flags=0, attr_align=ctrump.ALIGN_UNSPECIFIED, struct_or_union=ctrump.TYPE_STRUCT):
01256 b = self.b
01257
01258 record_decls = []
01259
01260 for (t,n) in decls:
01261 (spec, name, struct_decl) = self.type_name_pair_to_struct_decl(t,n)
01262 decl = b.struct_decl_decl(code = ctrump.STRUCT_DECL_FIELDS,
01263 decls=[struct_decl], flags=0, aligned=ctrump.ALIGN_UNSPECIFIED,
01264 stor_class=ctrump.STOR_CLASS_FIELD,
01265 type_spec=spec, qual_flags=0, func_spec=ctrump.FUNC_SPEC_UNSPECIFIED,
01266 num_decls=1)
01267 record_decls.append(decl)
01268
01269 struct_name = self.get_symbol(struct_name)
01270 record_type = b.decls_to_struct_texpr(struct_name, record_decls, struct_or_union, flags, attr_align)
01271
01272 code = StructTypeSpec.STRUCT
01273 if struct_or_union == ctrump.TYPE_UNION:
01274 code = StructTypeSpec.UNION
01275
01276 return StructTypeSpec(struct_name, record_type, record_decls, code,
01277 flags, attr_align)
01278
01279 def union(self, struct_name, decls, flags=0, attr_align=ctrump.ALIGN_UNSPECIFIED):
01280 return self.struct(struct_name, decls, flags=flags, attr_align=attr_align, struct_or_union=ctrump.TYPE_UNION)
01281
01282 def array_of(self, array_of, size_expr):
01283 return ArrayTypeSpec(array_of, size_expr)
01284
01285 def qualified_type(self, type, qual_flags, gcc_aligned=ctrump.ALIGN_UNSPECIFIED, gcc_flags=0):
01286 return QualTypeSpec(type, qual_flags, gcc_aligned, gcc_flags)
01287
01288 def build_typed_var_and_init(self, typespec, name,
01289 stor_class=ctrump.STOR_CLASS_AUTO_UNSPECIFIED, init=None,
01290 emit_struct_definition = False):
01291 b = self.b
01292
01293 (type_spec, name_sym, dwi, declarator) = self.type_name_pair_to_decl(typespec,name,init, emit_struct_definition)
01294 texpr = self.build_type_expr(typespec)
01295 var = b.var(name=name_sym, stor_class=stor_class,
01296 addressed=0, var_aligned=ctrump.ALIGN_UNSPECIFIED,
01297 type=texpr)
01298
01299 var_obj = Var(typespec,name_sym,var,stor_class,self)
01300 return (var_obj, dwi, type_spec, declarator)
01301
01302 def build_typed_var(self, typespec, name,
01303 stor_class=ctrump.STOR_CLASS_AUTO_UNSPECIFIED, init=None):
01304 return self.build_typed_var_and_init(typespec, name,
01305 stor_class, init)[0]
01306
01307 def build_type_expr(self,texpr):
01308 if isinstance(texpr, ctrump.texprType):
01309 return texpr
01310 return texpr.build_type_expr(self)
01311
01312 def decl(self,type_spec_obj,name,align=ctrump.ALIGN_UNSPECIFIED,
01313 stor_class=ctrump.STOR_CLASS_AUTO_UNSPECIFIED,init=None,emit_struct_definition=False):
01314 b = self.b
01315
01316 if isinstance(type_spec_obj, str):
01317 type_spec_obj = self.typedefed_name(type_spec_obj)
01318
01319 (var_obj, dwi, type_spec, declarator) = self.build_typed_var_and_init(type_spec_obj, name, stor_class,
01320 init, emit_struct_definition)
01321 self.scope[name] = var_obj
01322
01323 return Decl(type = type_spec,
01324 name = name,
01325 var = var_obj,
01326 decl_with_init_list = [dwi],
01327 declarators = [declarator],
01328 gccattr_flags = 0,
01329 aligned = align,
01330 stor_class=stor_class,
01331 flags = 0)
01332
01333 def struct_decl(self, tspec):
01334 b = self.b
01335
01336 (flags,gccattr_flags,aligned,declarator,type_spec) = build_declarator_and_typespec(self, tspec, None,
01337 emit_struct_definition = True)
01338
01339 return Decl(type = type_spec,
01340 name = None,
01341 var = None,
01342 decl_with_init_list = [],
01343 declarators = [],
01344 gccattr_flags = gccattr_flags,
01345 aligned = aligned,
01346 flags = flags,
01347 stor_class = ctrump.STOR_CLASS_AUTO_UNSPECIFIED)
01348
01349
01350 def comp(self, *stmts):
01351 return Compound(stmts)
01352
01353 def assign(self, var, val):
01354 return Binary(var, val, Binary.ASSIGN, self)
01355
01356 def binary(self, code, lhs, rhs):
01357 return Binary(lhs, rhs, code, self)
01358
01359 def band(self, lhs, rhs):
01360 return Binary(lhs, rhs, Binary.BAND, self)
01361 def sub(self, lhs, rhs):
01362 return Binary(lhs, rhs, Binary.SUB, self)
01363 def div(self, lhs, rhs):
01364 return Binary(lhs, rhs, Binary.DIV, self)
01365
01366 def for_(self, init, cond, iter, body):
01367 return For(init, cond, iter, body)
01368
01369 def if_(self, cond, then_body, else_body = None):
01370 return If(cond, then_body, else_body)
01371
01372 def preinc(self, expr):
01373 return Unary(expr,Unary.PRE_INC, self)
01374 def postinc(self, expr):
01375 return Unary(expr,Unary.POST_INC, self)
01376
01377 def varref(self, var_tree):
01378 return Var(var_tree.type, var_tree.name, var_tree, var_tree.stor_class, self)
01379
01380 def incomplete_struct(self, name):
01381 return IncompleteStructTypeSpec(name, IncompleteStructTypeSpec.STRUCT)
01382 def incomplete_union(self, name):
01383 return IncompleteStructTypeSpec(name, IncompleteStructTypeSpec.UNION)
01384
01385
01386 def incomplete_typedefed_name(self, name):
01387 b = self.b
01388 if name in self.structs:
01389 return self.structs[name]
01390
01391 sym = self.get_symbol(name)
01392 texpr = b.incomplete_struct(ctrump.TYPE_STRUCT, None)
01393
01394 ret = TypedefNameSpec(type_name = sym,
01395 type_expr = texpr)
01396 self.structs[name] = ret
01397 return ret
01398
01399 def typedefed_name(self, name):
01400 if name in self.structs:
01401 return self.structs[name]
01402 sym = self.get_symbol(name)
01403 type = self.scope[name]
01404 texpr = self.build_type_expr(type.type)
01405 ret = TypedefNameSpec(type_name = sym,
01406 type_expr = texpr)
01407 self.structs[name] = ret
01408 return ret
01409
01410 def pointer_to(self, texpr):
01411 return PointerToSpec(texpr)
01412
01413 def func(self, name, typespec=None):
01414 if typespec == None:
01415 typespec = self.unspec_func_spec
01416 return Func(self.build_typed_var(typespec, name,
01417 stor_class=ctrump.STOR_CLASS_EXTDEF),
01418 self)
01419
01420 def addr(self, expr):
01421 return Unary(expr, Unary.ADDR, self)
01422
01423 def paren(self, expr):
01424 return Paren(expr, self)
01425
01426 def expr(self, expr):
01427 return Expr(expr,self)
01428
01429 def func_type(self, ret_type, args, has_unspecified_arg=False):
01430 return FuncTypeSpec(ret_type, args, has_unspecified_arg)
01431
01432 def func_def(self, ret_type, name, args_decls, body, has_unspecified_arg = False):
01433 flat_body = []
01434 flatten(flat_body, body)
01435 return FuncDef(ret_type, name, args_decls, flat_body, has_unspecified_arg)
01436
01437 def newline(self):
01438 return NewlineStmt(self.b.stmt(code=ctrump.STMT_NEWLINE))
01439
01440 def func_argdecl(self, type_name_list):
01441 return FuncArgDecl(type_name_list, self)
01442
01443 def cast(self, cast_to, expr):
01444 return CastTo(cast_to, expr, self)
01445
01446 def translation_unit(self, extdefs, filename):
01447 b = self.b
01448
01449 decls = []
01450 flat_extdefs = []
01451 flatten(flat_extdefs, extdefs)
01452
01453 for i in flat_extdefs:
01454 if isinstance(i, StmtBase):
01455 i = i.build_extdecl(self)
01456 decls.append(i)
01457
01458 return b.translation_unit(num_decl = len(flat_extdefs),
01459 decls = decls,
01460 filename = filename)
01461
01462
01463 def clear_scope(self):
01464 self.scope = Scope(self)
01465 self.structs = {}
01466 self.struct_scope = {}
01467 return self.scope
01468
01469 def sizeof(self, expr):
01470 return Unary(expr, Unary.SIZEOF, self)
01471
01472 def sizeof_type(self, texpr):
01473 return SizeofType(texpr, self)
01474
01475 def include(self, path, is_quote=False):
01476 return Include(path, is_quote)
01477
01478 def calc_type_size(self, abi, typespec):
01479 texpr = self.build_type_expr(typespec)
01480 return ctrump.calc_type_size(abi, texpr)
01481
01482 def typing(self, expr):
01483 if isinstance(expr, ExprBase):
01484 return expr.typing(self)
01485 else:
01486 return expr.type
01487
01488 def emit_paren(self, expr, num_paren):
01489 for i in range(0,num_paren):
01490 expr = self.b.expr_paren(code=ctrump.EXPR_PAREN, type=self.typing(expr), expr=expr)
01491 return expr
01492
01493 def ptr_ref(self, expr):
01494 return Unary(expr, Unary.PTRREF, self)
01495
01496 def bcmpl(self, expr):
01497 return Unary(expr, Unary.BCMPL, self)
01498
01499 def return_(self, expr = None):
01500 return ReturnStmt(expr)
01501
01502 def literal(self, val):
01503 if isinstance(val, int):
01504 return IntegerLiteral(val, self)
01505 else:
01506 raise("invalid literal %s"%val)
01507
01508 def empty_expr(self):
01509 return EmptyExpr(self)