Class: CappRuby::RubyBuilder
- Inherits:
-
Vienna::RubyParser
- Object
- Vienna::RubyParser
- CappRuby::RubyBuilder
- Defined in:
- lib/cappruby/ruby_builder.rb
Defined Under Namespace
Classes: CappIseq
Instance Method Summary collapse
-
#gen_call_should_use_colon?(c) ⇒ Boolean
similar to def, but for calls (not objj style calls..).
-
#gen_def_should_use_colon?(a) ⇒ Boolean
method returns true if our normal method should add a colon onto the selector name (i.e. it takes either exactly 1 param, or it takes a single default param.. this might be the case, we just add a defailt value to the selector:).
- #generate_array(ary, context) ⇒ Object
- #generate_assign(stmt, context) ⇒ Object
- #generate_call(call, context) ⇒ Object
- #generate_class(cls, context) ⇒ Object
- #generate_constant(cnst, context) ⇒ Object
- #generate_def(stmt, context) ⇒ Object
- #generate_function_call(call, context) ⇒ Object
- #generate_identifier(id, context) ⇒ Object
- #generate_numeric(num, context) ⇒ Object
- #generate_op_asgn(stmt, context) ⇒ Object
- #generate_self(stmt, context) ⇒ Object
- #generate_string(str, context) ⇒ Object
- #generate_symbol(sym, context) ⇒ Object
- #generate_tree(tree) ⇒ Object
- #generate_xstring(stmt, context) ⇒ Object
-
#generate_yield(stmt, context) ⇒ Object
Generate a yield stmt.
-
#initialize(source, project, build_name) ⇒ RubyBuilder
constructor
A new instance of RubyBuilder.
- #iseq_stack_pop ⇒ Object
- #iseq_stack_push(type) ⇒ Object
Constructor Details
#initialize(source, project, build_name) ⇒ RubyBuilder
Returns a new instance of RubyBuilder.
31 32 33 |
# File 'lib/cappruby/ruby_builder.rb', line 31 def initialize(source, project, build_name) super end |
Instance Method Details
#gen_call_should_use_colon?(c) ⇒ Boolean
similar to def, but for calls (not objj style calls..)
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/cappruby/ruby_builder.rb', line 408 def gen_call_should_use_colon?(c) # basically, if a "special" method using ruby only things, then dont use # a colon return false if c[:meth].match(/(\<|\!|\?\>\=\!)/) args_len = 0 if c[:call_args] and c[:call_args][:args] args_len = args_len + c[:call_args][:args].length end if c[:call_args] and c[:call_args][:assocs] args_len = args_len + 1 end # essentially, true if only one arg.. (args_len == 1) ? true : false end |
#gen_def_should_use_colon?(a) ⇒ Boolean
method returns true if our normal method should add a colon onto the selector name (i.e. it takes either exactly 1 param, or it takes a single default param.. this might be the case, we just add a defailt value to the selector:)
277 278 279 280 281 282 283 284 285 286 |
# File 'lib/cappruby/ruby_builder.rb', line 277 def gen_def_should_use_colon?(a) # one normal arg, nothing else (block is irrelevant) if a.arg_size==1 && a.opt_size== 0 && a.rest_size == 0 && a.post_size == 0 true elsif a.arg_size==0 && a.opt_size==1 && a.rest_size==0 && a.post_size == 0 true else false end end |
#generate_array(ary, context) ⇒ Object
454 455 456 457 458 459 460 461 462 463 464 |
# File 'lib/cappruby/ruby_builder.rb', line 454 def generate_array ary, context write "[" if ary[:args] ary[:args].each do |a| write "," unless ary[:args].first == a generate_stmt a, :full_stmt => false, :last_stmt => false end end write "]" end |
#generate_assign(stmt, context) ⇒ Object
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
# File 'lib/cappruby/ruby_builder.rb', line 472 def generate_assign stmt, context write "return " if context[:last_stmt] and context[:full_stmt] # LHS is an identifier (local) if stmt[:lhs].node == :identifier # check to see if it already exists, i.e. reusing old name local = @iseq_current.lookup_local stmt[:lhs][:name] unless local # cannot find local, so we must make it local = @iseq_current.push_local_name stmt[:lhs][:name] end write "#{local} = " # RHS generate_stmt stmt[:rhs], :full_stmt => false, :last_stmt => false else abort "unknown assign type: #{stmt[:lhs].node}" end write ";" if context[:full_stmt] end |
#generate_call(call, context) ⇒ Object
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 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 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
# File 'lib/cappruby/ruby_builder.rb', line 288 def generate_call call, context # capture "function calls" if call[:meth].match(/^[A-Z](.*)$/) return generate_function_call call, context end # capture objj write "return " if context[:last_stmt] and context[:full_stmt] write %{cr_send(} # receiver if call[:recv] call_bit = 0 generate_stmt call[:recv], :full_stmt => false, :last_stmt => false else call_bit = 8 # self as recv write "_a" end write "," # method id - we should look for adding a selector here.. sel_colon = gen_call_should_use_colon?(call) ? ":" : "" write %{"#{call[:meth]}#{sel_colon}"} write "," # arguments write "[" unless call[:call_args].nil? or call[:call_args][:args].nil? call[:call_args][:args].each do |arg| write "," unless call[:call_args][:args].last == arg generate_stmt arg, :full_stmt => false end end # assocs if call[:call_args] and call[:call_args][:assocs] write "," unless call[:call_args].nil? or call[:call_args][:args].nil? write "cr_newhash(" call[:call_args][:assocs].each do |assoc| write "," unless call[:call_args][:assocs].first == assoc generate_stmt assoc[:key], :full_stmt => false, :last_stmt => false write "," generate_stmt assoc[:value], :full_stmt => false, :last_stmt => false end write ")" end write "]" write "," # block if call[:brace_block] current_iseq = @iseq_current block_iseq = iseq_stack_push(ISEQ_TYPE_BLOCK) block_iseq.parent_iseq = current_iseq # block arg names if call[:brace_block][:params] call[:brace_block][:params].each do |p| block_iseq.push_arg_name p[:value] end end # block stmts if call[:brace_block][:stmt] call[:brace_block][:stmt].each do |a| generate_stmt a, :full_stmt => true, :last_stmt => call[:brace_block][:stmt].last == a end end iseq_stack_pop write block_iseq.to_s else write "nil" end write "," # op flag write "#{call_bit})" write ";" if context[:full_stmt] end |
#generate_class(cls, context) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/cappruby/ruby_builder.rb', line 205 def generate_class(cls, context) write "return " if context[:last_stmt] and context[:full_stmt] current_iseq = @iseq_current class_iseq = iseq_stack_push ISEQ_TYPE_CLASS class_iseq.parent_iseq = current_iseq # do each body stmt, but for now, assume nonoe cls.bodystmt.each do |b| generate_stmt b, :full_stmt => true, :last_stmt => b == cls.bodystmt.last end if cls.bodystmt.length == 0 write "return nil;" end iseq_stack_pop write %{cr_defineclass(nil,nil,"#{cls.klass_name}",#{class_iseq},0)} write ";" if context[:full_stmt] end |
#generate_constant(cnst, context) ⇒ Object
446 447 448 |
# File 'lib/cappruby/ruby_builder.rb', line 446 def generate_constant cnst, context write %{cr_getconstant(_a,"#{cnst[:name]}")} end |
#generate_def(stmt, context) ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/cappruby/ruby_builder.rb', line 228 def generate_def stmt, context # work out if its an objj style method call.. write "return " if context[:last_stmt] and context[:full_stmt] is_singleton = stmt[:singleton] ? 1 : 0 current_iseq = @iseq_current def_iseq = iseq_stack_push(ISEQ_TYPE_METHOD) def_iseq.parent_iseq = current_iseq # arg names if stmt[:arglist].arg stmt[:arglist].arg.each { |a| @iseq_current.push_arg_name a[:value] } end # body stmts stmt[:bodystmt].each do |b| generate_stmt b, :full_stmt => true, :last_stmt => b == stmt[:bodystmt].last end iseq_stack_pop # definemethod write "cr_definemethod(" # base (singleton?) if stmt[:singleton] generate_stmt stmt[:singleton], :full_stmt => false, :last_stmt => false else # self write "_a" end # method returns true if our normal method should add a colon onto the # selector name (i.e. it takes either exactly 1 param, or it takes a # single default param.. this might be the case, we just add a defailt # value to the selector:) sel_colon = gen_def_should_use_colon?(stmt[:arglist]) ? ":" : "" write %{,"#{stmt[:fname]}#{sel_colon}",#{def_iseq},#{is_singleton})} write ";" if context[:full_stmt] end |
#generate_function_call(call, context) ⇒ Object
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/cappruby/ruby_builder.rb', line 374 def generate_function_call call, context write "return " if context[:last_stmt] and context[:full_stmt] write "cr_functioncall(\"" write call[:meth] write "\",[" unless call[:call_args].nil? or call[:call_args][:args].nil? call[:call_args][:args].each do |arg| write "," unless call[:call_args][:args].first == arg generate_stmt arg, :full_stmt => false end end write "])" write ";" if context[:full_stmt] end |
#generate_identifier(id, context) ⇒ Object
393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/cappruby/ruby_builder.rb', line 393 def generate_identifier id, context write "return " if context[:last_stmt] and context[:full_stmt] local = @iseq_current.lookup_local id[:name] if local write local else # cannot find local, so we assume it is a function call... write %{cr_send(_a,"#{id[:name]}",[],nil,8)} end write ";" if context[:full_stmt] end |
#generate_numeric(num, context) ⇒ Object
450 451 452 |
# File 'lib/cappruby/ruby_builder.rb', line 450 def generate_numeric num, context write num[:value] end |
#generate_op_asgn(stmt, context) ⇒ Object
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
# File 'lib/cappruby/ruby_builder.rb', line 494 def generate_op_asgn(stmt, context) write "return " if context[:full_stmt] and context[:last_stmt] if stmt[:lhs].node == :ivar write %{(function(asgn)\{if(asgn!==nil && asgn!==undefined)\{} write %{return asgn;\}else\{} write "rb_ivar_set(_a, '#{stmt[:lhs][:name]}'," generate_stmt stmt[:rhs], :full_stmt => false, :last_stmt => false write ")" write %{\}\})(rb_ivar_get(_a,"#{stmt[:lhs][:name]}"))} else abort "bad op_asgn lhs: #{stmt[:lhs].node}" end write ";" if context[:full_stmt] end |
#generate_self(stmt, context) ⇒ Object
426 427 428 |
# File 'lib/cappruby/ruby_builder.rb', line 426 def generate_self stmt, context write "_a" end |
#generate_string(str, context) ⇒ Object
438 439 440 |
# File 'lib/cappruby/ruby_builder.rb', line 438 def generate_string str, context write %{"#{str[:value][0][:value]}"} end |
#generate_symbol(sym, context) ⇒ Object
442 443 444 |
# File 'lib/cappruby/ruby_builder.rb', line 442 def generate_symbol sym, context write %{ID2SYM("#{sym[:name]}")} end |
#generate_tree(tree) ⇒ Object
197 198 199 200 201 202 203 |
# File 'lib/cappruby/ruby_builder.rb', line 197 def generate_tree(tree) top_iseq = iseq_stack_push ISEQ_TYPE_TOP tree.each do |stmt| generate_stmt stmt, :full_stmt => true, :last_stmt => tree.last == stmt end iseq_stack_pop end |
#generate_xstring(stmt, context) ⇒ Object
466 467 468 469 470 |
# File 'lib/cappruby/ruby_builder.rb', line 466 def generate_xstring stmt, context write "return " if context[:last_stmt] and context[:full_stmt] write stmt[:value][0][:value] write ";" if context[:full_stmt] end |
#generate_yield(stmt, context) ⇒ Object
Generate a yield stmt. This makes sure the current iseq is a method, as only methods can “yield”.. also, sets the current iseq to “get block”. We know the method uses a block, so we need to make sure we can get it, and put it into a local var.
434 435 436 |
# File 'lib/cappruby/ruby_builder.rb', line 434 def generate_yield stmt, context write "\"block\"" end |
#iseq_stack_pop ⇒ Object
188 189 190 191 192 193 194 195 |
# File 'lib/cappruby/ruby_builder.rb', line 188 def iseq_stack_pop iseq = @iseq_stack.last @iseq_stack.pop @iseq_current = @iseq_stack.last # finalize (var locals etc) iseq.finalize iseq.to_s end |