Class: NScript::ForNode

Inherits:
Node
  • Object
show all
Defined in:
lib/nscript/parser/nodes.rb

Constant Summary

Constants inherited from Node

Node::TAB

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Node

#children, children, #compile, #compile_closure, #contains?, #idt, statement, #statement?, statement_only, #statement_only?, top_sensitive, #top_sensitive?, #unwrap, #write

Constructor Details

#initialize(body, source, name, index = nil) ⇒ ForNode

Returns a new instance of ForNode.



723
724
725
726
727
728
729
730
# File 'lib/nscript/parser/nodes.rb', line 723

def initialize(body, source, name, index=nil)
  @body, @name, @index = body, name, index
  @source = source[:source]
  @filter = source[:filter]
  @step   = source[:step]
  @object = !!source[:object]
  @name, @index = @index, @name if @object
end

Instance Attribute Details

#indexObject (readonly)

Returns the value of attribute index.



720
721
722
# File 'lib/nscript/parser/nodes.rb', line 720

def index
  @index
end

#nameObject (readonly)

Returns the value of attribute name.



720
721
722
# File 'lib/nscript/parser/nodes.rb', line 720

def name
  @name
end

#stepObject (readonly)

Returns the value of attribute step.



720
721
722
# File 'lib/nscript/parser/nodes.rb', line 720

def step
  @step
end

Instance Method Details

#compile_node(o) ⇒ Object



732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
# File 'lib/nscript/parser/nodes.rb', line 732

def compile_node(o)
  top_level     = o.delete(:top) && !o[:return]
  range         = @source.is_a?(ValueNode) && @source.base.is_a?(RangeNode) && @source.properties.empty?
  source        = range ? @source.base : @source
  scope         = o[:scope]
  name_found    = @name  && scope.find(@name)
  index_found   = @index && scope.find(@index)
  body_dent     = idt(1)
  rvar          = scope.free_variable unless top_level
  svar          = scope.free_variable
  ivar          = range ? name : @index ? @index : scope.free_variable
  var_part      = ''
  body          = Expressions.wrap(@body)
  if range
    index_var   = scope.free_variable
    source_part = source.compile_variables(o)
    for_part    = "#{index_var}=0, #{source.compile(o.merge(:index => ivar, :step => @step))}, #{index_var}++"
  else
    index_var   = nil
    source_part = "#{svar} = #{@source.compile(o)};\n#{idt}"
    step_part   = @step ? "#{ivar} += #{@step.compile(o)}" : "#{ivar}++"
    for_part    = @object ? "#{ivar} in #{svar}" : "#{ivar} = 0; #{ivar} < #{svar}.length; #{step_part}"
    var_part    = "#{body_dent}#{@name} = #{svar}[#{ivar}];\n" if @name
    # body.unshift(AssignNode.new(@name, ValueNode.new(svar, [IndexNode.new(ivar)]))) if @name
  end
  set_result    = rvar ? "#{idt}#{rvar} = []; " : idt
  return_result = rvar || ''
  body = ClosureNode.wrap(body, true) if top_level && contains? {|n| n.is_a? CodeNode }
  body = PushNode.wrap(rvar, body) unless top_level
  if o[:return]
    return_result = "return #{return_result}" if o[:return]
    o.delete(:return)
    body = IfNode.new(@filter, body, nil, :statement => true) if @filter
  elsif @filter
    body = Expressions.wrap(IfNode.new(@filter, body))
  end
  if @object
    o[:scope].assign("__hasProp", "Object.prototype.hasOwnProperty", true)
    body = Expressions.wrap(IfNode.new(
      CallNode.new(
        ValueNode.new(LiteralNode.wrap("__hasProp"), [AccessorNode.new(Value.new('call'))]),
        [LiteralNode.wrap(svar), LiteralNode.wrap(ivar)]
      ),
      Expressions.wrap(body), nil, {:statement => true}
    ))
  end

  return_result = "\n#{idt}#{return_result};" unless top_level
  body = body.compile(o.merge(:indent => body_dent, :top => true))
  vars = range ? @name : "#{@name}, #{ivar}"
  return write(set_result + source_part + "for (#{for_part}) {\n#{var_part}#{body}\n#{idt}}\n#{idt}#{return_result}")
end