class Glaemscribe::API::Eval::Parser

Public Instance Methods

cast_constant(const) click to toggle source
# File lib/api/eval.rb, line 238
def cast_constant(const)
  if constant_is_int?(const)
    const.to_i
  elsif constant_is_float?(const)
    const.to_f
  elsif const[/^\'(.*)\'$/] || const[/^\"(.*)\"$/]
    $1
  elsif const == 'true'
    true
  elsif const == 'false'
    false
  elsif const == 'nil'
    nil
  elsif(@vars[const] != nil)
    @vars[const]
  else
    raise SyntaxError.new("Cannot understand constant '#{const}'.")
  end   
end
constant_is_float?(const) click to toggle source
# File lib/api/eval.rb, line 223
def constant_is_float?(const)
  Float(const) rescue false
end
constant_is_int?(const) click to toggle source
# File lib/api/eval.rb, line 227
def constant_is_int?(const)
  Integer(const) rescue false
end
constant_is_string?(const) click to toggle source
# File lib/api/eval.rb, line 231
def constant_is_string?(const)
  return false if const.length < 2
  f = const[0]
  l = const[-1]
  return ( f == l && (l == "'" || l == '"') )
end
explore_add() click to toggle source
# File lib/api/eval.rb, line 178
def explore_add
  v = explore_mult
  loop do
    case @lexer.advance().name
    when 'add_plus'     then v += explore_mult
    when 'add_minus'    then v -= explore_mult
    else break
    end
  end
  @lexer.uneat # Keep the unused token for the higher level
  v
end
explore_bool() click to toggle source
# File lib/api/eval.rb, line 138
def explore_bool
  v = explore_compare
  loop do
    case @lexer.advance().name
    when 'bool_or'
      if v
        explore_bool
      else
        v = explore_compare
      end
    when 'bool_and'
      if !v
        explore_bool 
      else
        v = explore_compare
      end
    else break
    end
  end      
  @lexer.uneat # Keep the unused token for the higher level
  v
end
explore_compare() click to toggle source
# File lib/api/eval.rb, line 161
def explore_compare
  v = explore_add
  loop do
    case @lexer.advance().name
    when 'cond_inf_eq'  then v = (v <= explore_add)
    when 'cond_inf'     then v = (v <  explore_add)
    when 'cond_sup_eq'  then v = (v >= explore_add)
    when 'cond_sup'     then v = (v >  explore_add)
    when 'cond_eq'      then v = (v == explore_add)
    when 'cond_not_eq'  then v = (v != explore_add)
    else break
    end
  end
  @lexer.uneat # Keep the unused token for the higher level
  v      
end
explore_mult() click to toggle source
# File lib/api/eval.rb, line 191
def explore_mult
  v = explore_primary
  loop do
    case @lexer.advance().name
    when 'mult_times'   then v *= explore_primary
    when 'mult_div'     then v /= explore_primary
    when 'mult_modulo'  then v %= explore_primary
    else break
    end
  end
  @lexer.uneat # Keep the unused token for the higher level
  v
end
explore_primary() click to toggle source
# File lib/api/eval.rb, line 205
def explore_primary
  token = @lexer.advance()
  case token.name
  when 'prim_const'
    v = cast_constant(token.value)
  when 'add_minus' # Allow the use of - as primary token for negative numbers
    v = -explore_primary
  when 'prim_not' # Allow the use of ! for booleans
    v = !explore_primary
  when 'prim_lparen'
    v           = parse_top_level
    rtoken      = @lexer.advance() 
    raise SyntaxError.new("Missing right parenthesis.") if(rtoken.name != 'prim_rparen') 
  else raise SyntaxError.new("Cannot understand: #{token.value}.")
  end
  v
end
parse(exp, vars) click to toggle source
# File lib/api/eval.rb, line 128
def parse(exp, vars)
  @lexer  = Lexer.new(exp)
  @vars   = {}; vars.each{ |k,v| @vars[k.to_s] = v } # Cast symbols
  parse_top_level
end
parse_top_level() click to toggle source
# File lib/api/eval.rb, line 134
def parse_top_level
  explore_bool
end