Class: StyleScript::ForNode
Overview
The replacement for the for loop is an array comprehension (that compiles) into a for loop. Also acts as an expression, able to return the result of the comprehenion. Unlike Python array comprehensions, it’s able to pass the current index of the loop as a second parameter.
Constant Summary
Constants inherited from Node
Instance Attribute Summary collapse
-
#index ⇒ Object
readonly
Returns the value of attribute index.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#step ⇒ Object
readonly
Returns the value of attribute step.
Instance Method Summary collapse
- #compile_node(o) ⇒ Object
-
#initialize(body, source, name, index = nil) ⇒ ForNode
constructor
A new instance of ForNode.
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.
852 853 854 855 856 857 858 859 |
# File 'lib/style_script/nodes.rb', line 852 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
#index ⇒ Object (readonly)
Returns the value of attribute index.
849 850 851 |
# File 'lib/style_script/nodes.rb', line 849 def index @index end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
849 850 851 |
# File 'lib/style_script/nodes.rb', line 849 def name @name end |
#step ⇒ Object (readonly)
Returns the value of attribute step.
849 850 851 |
# File 'lib/style_script/nodes.rb', line 849 def step @step end |
Instance Method Details
#compile_node(o) ⇒ Object
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 |
# File 'lib/style_script/nodes.rb', line 861 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 |