Class: Rucc::Node
- Inherits:
-
Object
- Object
- Rucc::Node
- Extended by:
- Conv
- Defined in:
- lib/rucc/node.rb,
lib/rucc/node/conv.rb
Overview
AST node
Defined Under Namespace
Modules: Conv
Instance Attribute Summary collapse
-
#args ⇒ Object
readonly
Returns the value of attribute args.
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#cond ⇒ Object
readonly
Returns the value of attribute cond.
-
#declinit ⇒ Object
readonly
Returns the value of attribute declinit.
-
#declvar ⇒ Object
readonly
Returns the value of attribute declvar.
-
#els ⇒ Object
readonly
Returns the value of attribute els.
-
#field ⇒ Object
readonly
Returns the value of attribute field.
-
#fieldtype ⇒ Object
readonly
Returns the value of attribute fieldtype.
-
#flabel ⇒ Object
Returns the value of attribute flabel.
-
#fname ⇒ Object
readonly
Returns the value of attribute fname.
-
#fptr ⇒ Object
readonly
Returns the value of attribute fptr.
-
#ftype ⇒ Object
readonly
Returns the value of attribute ftype.
-
#fval ⇒ Object
readonly
Returns the value of attribute fval.
-
#glabel ⇒ Object
readonly
Returns the value of attribute glabel.
-
#initoff ⇒ Object
readonly
Returns the value of attribute initoff.
-
#initval ⇒ Object
readonly
Returns the value of attribute initval.
-
#ival ⇒ Object
readonly
Returns the value of attribute ival.
-
#kind ⇒ Object
readonly
Returns the value of attribute kind.
-
#label ⇒ Object
readonly
Returns the value of attribute label.
-
#left ⇒ Object
readonly
Returns the value of attribute left.
-
#localvars ⇒ Object
readonly
Returns the value of attribute localvars.
-
#loff ⇒ Object
Returns the value of attribute loff.
-
#lvarinit ⇒ Object
Returns the value of attribute lvarinit.
-
#newlabel ⇒ Object
Returns the value of attribute newlabel.
-
#operand ⇒ Object
readonly
Returns the value of attribute operand.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
-
#retval ⇒ Object
readonly
Returns the value of attribute retval.
-
#right ⇒ Object
readonly
Returns the value of attribute right.
-
#slabel ⇒ Object
Returns the value of attribute slabel.
-
#stmts ⇒ Object
readonly
Returns the value of attribute stmts.
-
#struct ⇒ Object
readonly
Returns the value of attribute struct.
-
#sval ⇒ Object
readonly
Returns the value of attribute sval.
-
#thn ⇒ Object
readonly
Returns the value of attribute thn.
-
#totype ⇒ Object
readonly
Returns the value of attribute totype.
-
#ty ⇒ Object
Returns the value of attribute ty.
-
#varname ⇒ Object
readonly
Returns the value of attribute varname.
Class Method Summary collapse
- .ast_binop(ty, kind, left, right) ⇒ Node
- .ast_compound_stmt(stmts) ⇒ Node
- .ast_computed_goto(expr) ⇒ Node
- .ast_conv(totype, val) ⇒ Node
- .ast_decl(var, init) ⇒ Object
- .ast_dest(label) ⇒ Node
- .ast_floattype(ty, val) ⇒ Node
- .ast_func(ty, fname, params, body, localvars) ⇒ Node
- .ast_funcall(ftype, fname, args) ⇒ Node
- .ast_funcdesg(ty, fname) ⇒ Object
- .ast_funcptr_call(fptr, args) ⇒ Node
- .ast_goto(label) ⇒ Node
- .ast_gvar(ty, name, globalenv) ⇒ Object
- .ast_if(cond, thn, els) ⇒ Node
- .ast_init(val, totype, off) ⇒ Node
- .ast_inttype(ty, val) ⇒ Object
- .ast_jump(label) ⇒ Node
- .ast_label(label) ⇒ Node
- .ast_label_addr(label) ⇒ Object
- .ast_lvar(ty, name, localenv, localvars) ⇒ Node
- .ast_return(retval) ⇒ Object
- .ast_static_lvar(ty, name, localenv, glabel) ⇒ String
- .ast_string(enc, str) ⇒ Object
- .ast_struct_ref(ty, struct, name) ⇒ Node
- .ast_ternary(ty, cond, thn, els) ⇒ Node
- .ast_typedef(ty, name, env) ⇒ Node
- .ast_uop(kind, ty, operand) ⇒ Object
- .binop(op, lhs, rhs) ⇒ Node
- .node_or_nil_to_s(node) ⇒ Object
- .valid_pointer_binop?(op) ⇒ Boolean
- .wrap(t, node) ⇒ Node
Instance Method Summary collapse
-
#initialize(kind, ty: nil, ival: nil, fval: nil, flabel: nil, varname: nil, loff: nil, lvarinit: nil, glabel: nil, left: nil, right: nil, operand: nil, fname: nil, args: nil, ftype: nil, fptr: nil, params: nil, localvars: nil, body: nil, sval: nil, slabel: nil, declvar: nil, declinit: nil, initval: nil, initoff: nil, totype: nil, cond: nil, thn: nil, els: nil, label: nil, newlabel: nil, retval: nil, stmts: nil, struct: nil, field: nil, fieldtype: nil) ⇒ Node
constructor
A new instance of Node.
- #to_s ⇒ String
Methods included from Conv
Constructor Details
#initialize(kind, ty: nil, ival: nil, fval: nil, flabel: nil, varname: nil, loff: nil, lvarinit: nil, glabel: nil, left: nil, right: nil, operand: nil, fname: nil, args: nil, ftype: nil, fptr: nil, params: nil, localvars: nil, body: nil, sval: nil, slabel: nil, declvar: nil, declinit: nil, initval: nil, initoff: nil, totype: nil, cond: nil, thn: nil, els: nil, label: nil, newlabel: nil, retval: nil, stmts: nil, struct: nil, field: nil, fieldtype: nil) ⇒ Node
Returns a new instance of Node.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/rucc/node.rb', line 36 def initialize(kind, ty: nil, ival: nil, # Integer fval: nil, flabel: nil, # Float or double varname: nil, # Local/global variable loff: nil, lvarinit: nil, # Local variable glabel: nil, # Global variable left: nil, right: nil, # Binary operator operand: nil, # Unary operator fname: nil, # Function call or function declaration args: nil, ftype: nil, # Function call fptr: nil, # Function pointer or function designator params: nil, localvars: nil, body: nil, # Function declaration sval: nil, slabel: nil, # String declvar: nil, declinit: nil, # Declaration initval: nil, initoff: nil, totype: nil, # Initializer cond: nil, thn: nil, els: nil, # If statement or ternary operator label: nil, newlabel: nil, # Goto and label retval: nil, # Return statement stmts: nil, # Compound statement struct: nil, field: nil, fieldtype: nil # Struct reference ) @kind = kind @ty = ty @ival = ival # Integer @fval = fval; @flabel = flabel # Float or double @varname = varname # Local/global variable @loff = loff; @lvarinit = lvarinit # Local variable @glabel = glabel # Global variable @left = left; @right = right # Binary operator @operand = operand # Unary operator @fname = fname # Function call or function declaration @args = args; @ftype = ftype # Function call @fptr = fptr # Function pointer or function designator @params = params; @localvars = localvars; @body = body # Function declaration @sval = sval; @slabel = slabel # String @declvar = declvar; @declinit = declinit # Declaration @initval = initval; @initoff = initoff; @totype = totype # Initializer @cond = cond; @thn = thn; @els = els # If statement or ternary operator @label = label; @newlabel = newlabel # Goto and label @retval = retval # Return statement @stmts = stmts # Compound statement @struct = struct; @field = field; @fieldtype = fieldtype # Struct reference end |
Instance Attribute Details
#args ⇒ Object (readonly)
Returns the value of attribute args.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def args @args end |
#body ⇒ Object (readonly)
Returns the value of attribute body.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def body @body end |
#cond ⇒ Object (readonly)
Returns the value of attribute cond.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def cond @cond end |
#declinit ⇒ Object (readonly)
Returns the value of attribute declinit.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def declinit @declinit end |
#declvar ⇒ Object (readonly)
Returns the value of attribute declvar.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def declvar @declvar end |
#els ⇒ Object (readonly)
Returns the value of attribute els.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def els @els end |
#field ⇒ Object (readonly)
Returns the value of attribute field.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def field @field end |
#fieldtype ⇒ Object (readonly)
Returns the value of attribute fieldtype.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def fieldtype @fieldtype end |
#flabel ⇒ Object
Returns the value of attribute flabel.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def flabel @flabel end |
#fname ⇒ Object (readonly)
Returns the value of attribute fname.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def fname @fname end |
#fptr ⇒ Object (readonly)
Returns the value of attribute fptr.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def fptr @fptr end |
#ftype ⇒ Object (readonly)
Returns the value of attribute ftype.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def ftype @ftype end |
#fval ⇒ Object (readonly)
Returns the value of attribute fval.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def fval @fval end |
#glabel ⇒ Object (readonly)
Returns the value of attribute glabel.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def glabel @glabel end |
#initoff ⇒ Object (readonly)
Returns the value of attribute initoff.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def initoff @initoff end |
#initval ⇒ Object (readonly)
Returns the value of attribute initval.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def initval @initval end |
#ival ⇒ Object (readonly)
Returns the value of attribute ival.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def ival @ival end |
#kind ⇒ Object (readonly)
Returns the value of attribute kind.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def kind @kind end |
#label ⇒ Object (readonly)
Returns the value of attribute label.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def label @label end |
#left ⇒ Object (readonly)
Returns the value of attribute left.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def left @left end |
#localvars ⇒ Object (readonly)
Returns the value of attribute localvars.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def localvars @localvars end |
#loff ⇒ Object
Returns the value of attribute loff.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def loff @loff end |
#lvarinit ⇒ Object
Returns the value of attribute lvarinit.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def lvarinit @lvarinit end |
#newlabel ⇒ Object
Returns the value of attribute newlabel.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def newlabel @newlabel end |
#operand ⇒ Object (readonly)
Returns the value of attribute operand.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def operand @operand end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def params @params end |
#retval ⇒ Object (readonly)
Returns the value of attribute retval.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def retval @retval end |
#right ⇒ Object (readonly)
Returns the value of attribute right.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def right @right end |
#slabel ⇒ Object
Returns the value of attribute slabel.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def slabel @slabel end |
#stmts ⇒ Object (readonly)
Returns the value of attribute stmts.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def stmts @stmts end |
#struct ⇒ Object (readonly)
Returns the value of attribute struct.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def struct @struct end |
#sval ⇒ Object (readonly)
Returns the value of attribute sval.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def sval @sval end |
#thn ⇒ Object (readonly)
Returns the value of attribute thn.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def thn @thn end |
#totype ⇒ Object (readonly)
Returns the value of attribute totype.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def totype @totype end |
#ty ⇒ Object
Returns the value of attribute ty.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def ty @ty end |
#varname ⇒ Object (readonly)
Returns the value of attribute varname.
80 81 82 |
# File 'lib/rucc/node.rb', line 80 def varname @varname end |
Class Method Details
.ast_binop(ty, kind, left, right) ⇒ Node
303 304 305 306 307 308 |
# File 'lib/rucc/node.rb', line 303 def ast_binop(ty, kind, left, right) Node.new(kind, ty: ty, left: left, right: right) end |
.ast_compound_stmt(stmts) ⇒ Node
465 466 467 |
# File 'lib/rucc/node.rb', line 465 def ast_compound_stmt(stmts) Node.new(AST::COMPOUND_STMT, stmts: stmts) end |
.ast_computed_goto(expr) ⇒ Node
424 425 426 427 |
# File 'lib/rucc/node.rb', line 424 def ast_computed_goto(expr) Node.new(AST::COMPUTED_GOTO, operand: expr) end |
.ast_conv(totype, val) ⇒ Node
438 439 440 441 442 |
# File 'lib/rucc/node.rb', line 438 def ast_conv(totype, val) Node.new(AST::CONV, ty: totype, operand: val) end |
.ast_decl(var, init) ⇒ Object
446 447 448 449 450 |
# File 'lib/rucc/node.rb', line 446 def ast_decl(var, init) Node.new(AST::DECL, declvar: var, declinit: init) end |
.ast_dest(label) ⇒ Node
394 395 396 397 398 |
# File 'lib/rucc/node.rb', line 394 def ast_dest(label) Node.new(AST::LABEL, label: label, newlabel: label) end |
.ast_floattype(ty, val) ⇒ Node
214 215 216 217 218 |
# File 'lib/rucc/node.rb', line 214 def ast_floattype(ty, val) Node.new(AST::LITERAL, ty: ty, fval: val) end |
.ast_func(ty, fname, params, body, localvars) ⇒ Node
248 249 250 251 252 253 254 255 |
# File 'lib/rucc/node.rb', line 248 def ast_func(ty, fname, params, body, localvars) Node.new(AST::FUNC, ty: ty, fname: fname, params: params, localvars: localvars, body: body) end |
.ast_funcall(ftype, fname, args) ⇒ Node
281 282 283 284 285 286 287 |
# File 'lib/rucc/node.rb', line 281 def ast_funcall(ftype, fname, args) Node.new(AST::FUNCALL, ty: ftype.rettype, fname: fname, args: args, ftype: ftype) end |
.ast_funcdesg(ty, fname) ⇒ Object
271 272 273 274 275 |
# File 'lib/rucc/node.rb', line 271 def ast_funcdesg(ty, fname) Node.new(AST::FUNCDESG, ty: ty, fname: fname) end |
.ast_funcptr_call(fptr, args) ⇒ Node
260 261 262 263 264 265 266 267 |
# File 'lib/rucc/node.rb', line 260 def ast_funcptr_call(fptr, args) Util.assert!{ fptr.ty.kind == Kind::PTR } Util.assert!{ fptr.ty.ptr.kind == Kind::FUNC } Node.new(AST::FUNCPTR_CALL, ty: fptr.ty.ptr.rettype, fptr: fptr, args: args) end |
.ast_goto(label) ⇒ Node
417 418 419 420 |
# File 'lib/rucc/node.rb', line 417 def ast_goto(label) Node.new(AST::GOTO, label: label) end |
.ast_gvar(ty, name, globalenv) ⇒ Object
508 509 510 511 512 |
# File 'lib/rucc/node.rb', line 508 def ast_gvar(ty, name, globalenv) r = Node.new(AST::GVAR, ty: ty, varname: name, glabel: name) globalenv[name] = r r end |
.ast_if(cond, thn, els) ⇒ Node
366 367 368 369 370 371 |
# File 'lib/rucc/node.rb', line 366 def ast_if(cond, thn, els) Node.new(AST::IF, cond: cond, thn: thn, els: els) end |
.ast_init(val, totype, off) ⇒ Node
456 457 458 459 460 461 |
# File 'lib/rucc/node.rb', line 456 def ast_init(val, totype, off) Node.new(AST::INIT, initval: val, initoff: off, totype: totype) end |
.ast_inttype(ty, val) ⇒ Object
206 207 208 209 |
# File 'lib/rucc/node.rb', line 206 def ast_inttype(ty, val) Util.assert!{ val.is_a?(Integer) } Node.new(AST::LITERAL, ty: ty, ival: val) end |
.ast_jump(label) ⇒ Node
409 410 411 412 413 |
# File 'lib/rucc/node.rb', line 409 def ast_jump(label) Node.new(AST::GOTO, label: label, newlabel: label) end |
.ast_label(label) ⇒ Node
388 389 390 |
# File 'lib/rucc/node.rb', line 388 def ast_label(label) Node.new(AST::LABEL, label: label) end |
.ast_label_addr(label) ⇒ Object
401 402 403 404 405 |
# File 'lib/rucc/node.rb', line 401 def ast_label_addr(label) Node.new(OP::LABEL_ADDR, ty: Type.make_ptr_type(Type::VOID), label: label) end |
.ast_lvar(ty, name, localenv, localvars) ⇒ Node
494 495 496 497 498 499 500 501 502 503 |
# File 'lib/rucc/node.rb', line 494 def ast_lvar(ty, name, localenv, localvars) r = Node.new(AST::LVAR, ty: ty, varname: name) if localenv localenv[name] = r end if localvars localvars.push(r) end r end |
.ast_return(retval) ⇒ Object
430 431 432 433 |
# File 'lib/rucc/node.rb', line 430 def ast_return(retval) Node.new(AST::RETURN, retval: retval) end |
.ast_static_lvar(ty, name, localenv, glabel) ⇒ String
519 520 521 522 523 524 525 526 527 |
# File 'lib/rucc/node.rb', line 519 def ast_static_lvar(ty, name, localenv, glabel) r = Node.new(AST::GVAR, ty: ty, varname: name, glabel: glabel) Util.assert!{ localenv } localenv[name] = r r end |
.ast_string(enc, str) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/rucc/node.rb', line 221 def ast_string(enc, str) case enc when ENC::NONE, ENC::UTF8 ty = Type.make_array_type(Type::CHAR, str.bytes.size + 1) body = str when ENC::CHAR16 b = UTF.to_utf16(str) ty = Type.make_array_type(Type::USHORT, (b.bytes.size / Type::USHORT.size) + 1) body = b + "\0" # NOTE: Add only \0 (\0\0 - \0) when ENC::CHAR32, ENC::WCHAR b = UTF.to_utf32(str) ty = Type.make_array_type(Type::UINT, (b.bytes.size / Type::UINT.size) + 1) body = b + "\0\0\0" # NOTE: Add only \0\0\0 (\0\0\0\0 - \0) else raise "Invalid encoding" end Node.new(AST::LITERAL, ty: ty, sval: body) end |
.ast_struct_ref(ty, struct, name) ⇒ Node
482 483 484 485 486 487 |
# File 'lib/rucc/node.rb', line 482 def ast_struct_ref(ty, struct, name) Node.new(AST::STRUCT_REF, ty: ty, struct: struct, field: name) end |
.ast_ternary(ty, cond, thn, els) ⇒ Node
378 379 380 381 382 383 384 |
# File 'lib/rucc/node.rb', line 378 def ast_ternary(ty, cond, thn, els) Node.new(AST::TERNARY, ty: ty, cond: cond, thn: thn, els: els) end |
.ast_typedef(ty, name, env) ⇒ Node
472 473 474 475 476 |
# File 'lib/rucc/node.rb', line 472 def ast_typedef(ty, name, env) r = Node.new(AST::TYPEDEF, ty: ty) env[name] = r r end |
.ast_uop(kind, ty, operand) ⇒ Object
292 293 294 295 296 |
# File 'lib/rucc/node.rb', line 292 def ast_uop(kind, ty, operand) Node.new(kind, ty: ty, operand: operand) end |
.binop(op, lhs, rhs) ⇒ Node
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/rucc/node.rb', line 314 def binop(op, lhs, rhs) if (lhs.ty.kind == Kind::PTR) && (rhs.ty.kind == Kind::PTR) if !valid_pointer_binop?(op) raise "internal pointer arith" end # C11 6.5.6.9: Pointer subtractions have type ptrdiff_t. if (op == '-'.freeze) return Node.ast_binop(Type::LONG, op, lhs, rhs) end # C11 6.5.8.6, 6.5.9.3: Pointer comparisons have type int. return Node.ast_binop(Type::INT, op, lhs, rhs); end # NOTE: Set pointer node as left if lhs.ty.kind == Kind::PTR return Node.ast_binop(lhs.ty, op, lhs, rhs) end if rhs.ty.kind == Kind::PTR return Node.ast_binop(rhs.ty, op, rhs, lhs) end Util.assert!{ Type.is_arithtype(lhs.ty) } Util.assert!{ Type.is_arithtype(rhs.ty) } r = Type.usual_arith_conv(lhs.ty, rhs.ty) Node.ast_binop(r, op, wrap(r, lhs), wrap(r, rhs)) end |
.node_or_nil_to_s(node) ⇒ Object
199 200 201 202 |
# File 'lib/rucc/node.rb', line 199 def node_or_nil_to_s(node) return '(nil)' if node.nil? node.to_s end |
Instance Method Details
#to_s ⇒ String
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/rucc/node.rb', line 103 def to_s case kind when AST::LITERAL case ty.kind when Kind::CHAR if ival == "\n" then return "'\\n'" # '\n' elsif ival == "\\" then return "'\\\\'" # '\\' elsif ival == "\0" then return "'\\0'" # '\0' else return "'#{ival.chr}'" # cf. 'a' end when Kind::INT return ival.to_s when Kind::FLOAT, Kind::DOUBLE, Kind::LDOUBLE return fval.to_s when Kind::LONG, Kind::LLONG return "#{ival}L" when Kind::ARRAY # Consider string literal return "\"#{Util.quote_cstring(sval)}\"" else raise "internal error" end when AST::LABEL return "#{label}:" when AST::LVAR s = "lv=#{varname}" if lvarinit s << "(#{lvarinit})" end return s when AST::GVAR return "gv=#{varname}" when AST::FUNCALL, AST::FUNCPTR_CALL return "(#{ty})#{kind == AST::FUNCALL ? fname : Node.node_or_nil_to_s(node)}(#{args.map { |arg| Node.node_or_nil_to_s(arg) }.join(",")})" when AST::FUNCDESG return "(funcdesg #{fname})" when AST::FUNC return "(#{ty})#{fname}(#{params.map { |param| "#{param.ty} #{Node.node_or_nil_to_s(param)}" }.join(",")})#{Node.node_or_nil_to_s(body)}" when AST::GOTO return "goto(#{label})" when AST::DECL s = "(decl #{declvar.ty} #{declvar.varname}" if declinit s << " #{declinit.join(" ")}" end s << ")" return s when AST::INIT return "#{initval}@#{initoff}" when AST::CONV return "(conv #{operand}=>#{ty})" when AST::IF s = "(if #{Node.node_or_nil_to_s(cond)} #{Node.node_or_nil_to_s(thn)}" if els s << " #{els}" end s << ")" return s when AST::TERNARY return "(? #{Node.node_or_nil_to_s(cond)} #{Node.node_or_nil_to_s(thn)} #{Node.node_or_nil_to_s(els)})" when AST::RETURN return "(return #{retval})" when AST::COMPOUND_STMT return "{#{stmts.map { |stmt| "#{stmt};" }.join}}" when AST::STRUCT_REF return "#{struct}.#{field}" when AST::ADDR then return "(addr #{operand})" when AST::DEREF then return "(deref #{operand})" when OP::SAL then return "(<< #{left} #{right})" when OP::SAR, OP::SHR then return "(>> #{left} #{right})" when OP::GE then return "(>= #{left} #{right})" when OP::LE then return "(<= #{left} #{right})" when OP::NE then return "(!= #{left} #{right})" when OP::PRE_INC then return "(pre++ #{operand})" when OP::PRE_DEC then return "(pre-- #{operand})" when OP::POST_INC then return "(post++ #{operand})" when OP::POST_DEC then return "(post-- #{operand})" when OP::LOGAND then return "(and #{left} #{right})" when OP::LOGOR then return "(or #{left} #{right})" when '!' then return "(! #{operand})" when '&' then return "(& #{left} #{right})" when '|' then return "(| #{left} #{right})" when OP::CAST return "((#{operand.ty})=>(#{ty}) #{operand})" when OP::LABEL_ADDR return "&&#{label}" when OP::EQ return "(== #{left} #{right})" else return "(#{kind} #{left} #{right})" end raise "Must not reach here!" end |