Class: StyleScript::Expressions

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

Overview

A collection of nodes, each one representing an expression.

Constant Summary collapse

TRAILING_WHITESPACE =
/\s+$/

Constants inherited from Node

Node::TAB

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Node

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

Constructor Details

#initialize(*nodes) ⇒ Expressions

Returns a new instance of Expressions.



101
102
103
# File 'lib/style_script/nodes.rb', line 101

def initialize(*nodes)
  @expressions = nodes.flatten
end

Instance Attribute Details

#functionObject

Returns the value of attribute function.



91
92
93
# File 'lib/style_script/nodes.rb', line 91

def function
  @function
end

Class Method Details

.wrap(*nodes) ⇒ Object

Wrap up a node as an Expressions, unless it already is.



96
97
98
99
# File 'lib/style_script/nodes.rb', line 96

def self.wrap(*nodes)
  return nodes[0] if nodes.length == 1 && nodes[0].is_a?(Expressions)
  Expressions.new(*nodes)
end

Instance Method Details

#<<(node) ⇒ Object

Tack an expression on to the end of this expression list.



106
107
108
109
# File 'lib/style_script/nodes.rb', line 106

def <<(node)
  @expressions << node
  self
end

#compile(o = {}) ⇒ Object



133
134
135
# File 'lib/style_script/nodes.rb', line 133

def compile(o={})
  o[:scope] ? super(o) : compile_root(o)
end

#compile_expression(node, o) ⇒ Object

Compiles a single expression within the expressions body.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/style_script/nodes.rb', line 165

def compile_expression(node, o)
  @indent = o[:indent]
  stmt    = node.statement?
  # We need to return the result if this is the last node in the expressions body.
  returns = o.delete(:return) && last?(node) && !node.statement_only?
  # Return the regular compile of the node, unless we need to return the result.
  return "#{stmt ? '' : idt}#{node.compile(o.merge(:top => true))}#{stmt ? '' : ';'}" unless returns
  # If it's a statement, the node knows how to return itself.
  return node.compile(o.merge(:return => true)) if node.statement?
  # If it's not part of a constructor, we can just return the value of the expression.
  return "#{idt}return #{node.compile(o)};" unless o[:scope].function && o[:scope].function.constructor?
  # It's the last line of a constructor, add a safety check.
  temp = o[:scope].free_variable
  "#{idt}#{temp} = #{node.compile(o)};\n#{idt}return #{o[:scope].function.name} === this.constructor ? this : #{temp};"
end

#compile_node(o = {}) ⇒ Object

Compile each expression in the Expressions body.



138
139
140
# File 'lib/style_script/nodes.rb', line 138

def compile_node(o={})
  write(@expressions.map {|n| compile_expression(n, o.dup) }.join("\n"))
end

#compile_root(o = {}) ⇒ Object

If this is the top-level Expressions, wrap everything in a safety closure.



143
144
145
146
147
148
149
150
# File 'lib/style_script/nodes.rb', line 143

def compile_root(o={})
  indent = o[:no_wrap] ? '' : TAB
  @indent = indent
  o.merge!(:indent => indent, :scope => Scope.new(nil, self, nil))
  code = o[:globals] ? compile_node(o) : compile_with_declarations(o)
  code.gsub!(TRAILING_WHITESPACE, '')
  write(o[:no_wrap] ? code : "// Generated by StyleScript v1.0.0\n(function(){\n#{code}\n})();")
end

#compile_with_declarations(o = {}) ⇒ Object

Compile the expressions body, with declarations of all inner variables pushed up to the top.



154
155
156
157
158
159
160
161
162
# File 'lib/style_script/nodes.rb', line 154

def compile_with_declarations(o={})
  code  = compile_node(o)
  args  = self.contains? {|n| n.is_a?(ValueNode) && n.arguments? }
  argv  = args && o[:scope].check('arguments') ? '' : 'var '
  code  = "#{idt}#{argv}arguments = Array.prototype.slice.call(arguments, 0);\n#{code}" if args
  code  = "#{idt}var #{o[:scope].compiled_assignments};\n#{code}" if o[:scope].assignments?(self)
  code  = "#{idt}var #{o[:scope].compiled_declarations};\n#{code}" if o[:scope].declarations?(self)
  write(code)
end

#empty?Boolean

Is this an empty block of code?

Returns:

  • (Boolean)


123
124
125
# File 'lib/style_script/nodes.rb', line 123

def empty?
  @expressions.empty?
end

#last?(node) ⇒ Boolean

Is the node last in this block of expressions?

Returns:

  • (Boolean)


128
129
130
131
# File 'lib/style_script/nodes.rb', line 128

def last?(node)
  @last_index ||= @expressions.last.is_a?(CommentNode) ? -2 : -1
  node == @expressions[@last_index]
end

#unshift(node) ⇒ Object

Tack an expression on to the beginning of this expression list.



112
113
114
115
# File 'lib/style_script/nodes.rb', line 112

def unshift(node)
  @expressions.unshift(node)
  self
end

#unwrapObject

If this Expressions consists of a single node, pull it back out.



118
119
120
# File 'lib/style_script/nodes.rb', line 118

def unwrap
  @expressions.length == 1 ? @expressions.first : self
end