Class: StyleScript::OpNode

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

Overview

Simple Arithmetic and logical operations. Performs some conversion from StyleScript operations into their JavaScript equivalents.

Constant Summary collapse

CONVERSIONS =
{
  :==     => "===",
  :'!='   => "!==",
  :and    => '&&',
  :or     => '||',
  :is     => '===',
  :isnt   => "!==",
  :not    => '!'
}
CHAINABLE =
[:<, :>, :>=, :<=, :===, :'!===']
ASSIGNMENT =
[:'||=', :'&&=', :'?=']
PREFIX_OPERATORS =
[:typeof, :delete]

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(operator, first, second = nil, flip = false) ⇒ OpNode

Returns a new instance of OpNode.



595
596
597
598
# File 'lib/style_script/nodes.rb', line 595

def initialize(operator, first, second=nil, flip=false)
  @first, @second, @flip = first, second, flip
  @operator = CONVERSIONS[operator.to_sym] || operator
end

Instance Attribute Details

#operatorObject (readonly)

Returns the value of attribute operator.



579
580
581
# File 'lib/style_script/nodes.rb', line 579

def operator
  @operator
end

#secondObject

Returns the value of attribute second.



580
581
582
# File 'lib/style_script/nodes.rb', line 580

def second
  @second
end

Instance Method Details

#chainable?Boolean

Returns:

  • (Boolean)


604
605
606
# File 'lib/style_script/nodes.rb', line 604

def chainable?
  CHAINABLE.include?(operator.to_sym)
end

#compile_assignment(o) ⇒ Object



624
625
626
627
628
629
630
# File 'lib/style_script/nodes.rb', line 624

def compile_assignment(o)
  first, second = @first.compile(o), @second.compile(o)
  o[:scope].find(first) if @first.unwrap.is_a?(Value)
  sym = @operator[0..1]
  return "#{first} = #{ExistenceNode.compile_test(o, @first)} ? #{first} : #{second}" if @operator == '?='
  "#{first} = #{first} #{sym} #{second}"
end

#compile_chain(o) ⇒ Object

Mimic Python’s chained comparisons. See: docs.python.org/reference/expressions.html#notin



618
619
620
621
622
# File 'lib/style_script/nodes.rb', line 618

def compile_chain(o)
  shared = @first.unwrap.second
  @first.second, shared = *shared.compile_reference(o) if shared.is_a?(CallNode)
  "(#{@first.compile(o)}) && (#{shared.compile(o)} #{@operator} #{@second.compile(o)})"
end

#compile_existence(o) ⇒ Object



632
633
634
635
# File 'lib/style_script/nodes.rb', line 632

def compile_existence(o)
  first, second = @first.compile(o), @second.compile(o)
  "#{ExistenceNode.compile_test(o, @first)} ? #{first} : #{second}"
end

#compile_node(o) ⇒ Object



608
609
610
611
612
613
614
# File 'lib/style_script/nodes.rb', line 608

def compile_node(o)
  return write(compile_chain(o)) if chainable? && @first.unwrap.is_a?(OpNode) && @first.unwrap.chainable?
  return write(compile_assignment(o)) if ASSIGNMENT.include?(@operator.to_sym)
  return write(compile_unary(o)) if unary?
  return write(compile_existence(o)) if @operator == '?'
  write("#{@first.compile(o)} #{@operator} #{@second.compile(o)}")
end

#compile_unary(o) ⇒ Object



637
638
639
640
641
642
# File 'lib/style_script/nodes.rb', line 637

def compile_unary(o)
  space = PREFIX_OPERATORS.include?(@operator.to_sym) ? ' ' : ''
  parts = [@operator.to_s, space, @first.compile(o)]
  parts.reverse! if @flip
  parts.join('')
end

#unary?Boolean

Returns:

  • (Boolean)


600
601
602
# File 'lib/style_script/nodes.rb', line 600

def unary?
  @second.nil?
end