Class: BinaryParser::Expression::RPN

Inherits:
Object
  • Object
show all
Defined in:
lib/binary_parser/general_class/expression.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*tokens) ⇒ RPN

Returns a new instance of RPN.



209
210
211
212
# File 'lib/binary_parser/general_class/expression.rb', line 209

def initialize(*tokens)
  check_tokens(tokens)
  @tokens = tokens
end

Instance Attribute Details

#tokensObject (readonly)

Returns the value of attribute tokens.



207
208
209
# File 'lib/binary_parser/general_class/expression.rb', line 207

def tokens
  @tokens
end

Instance Method Details

#+(other) ⇒ Object



218
219
220
# File 'lib/binary_parser/general_class/expression.rb', line 218

def +(other)
  RPN.new(*(self.tokens + other.tokens))
end

#check_tokens(tokens) ⇒ Object



214
215
216
# File 'lib/binary_parser/general_class/expression.rb', line 214

def check_tokens(tokens)
  tokens.all?{|token| token.is_a?(Expression::Token)}
end

#eval(&token_eval_proc) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/binary_parser/general_class/expression.rb', line 222

def eval(&token_eval_proc)
  stack = @tokens.inject([]) do |stack, token|
    if token.is_a?(Expression::Token::Operator)
      raise BadManipulationError, "Cannot calculate this RPN." if stack.length < 2
      stack + [token.operate(*[stack.pop, stack.pop].reverse)]
    elsif token.is_a?(Expression::Token::Immediate)
      stack + [token.value]
    elsif token.is_a?(Expression::Token::Variable)
      eval_value = token_eval_proc.call(token)
      unless eval_value.is_a?(Integer) || eval_value.is_a?(::BinaryParser::BuiltInTemplate::UInt)
        raise BadManipulationError, "Evaluation is faild. #{eval_value} is not Integer (or UInt) (#{eval_value.class})."
      end
      stack + [eval_value]
    end
  end
  raise BadManipulationError, "Cannot calculate this RPN." if stack.length != 1
  return stack.last
end