Class: Trxl::Calculator

Inherits:
Object
  • Object
show all
Extended by:
StdLib
Defined in:
lib/trxl/trxl.rb

Constant Summary

Constants included from StdLib

StdLib::AVG_RANGE_SUM_OF_TYPE, StdLib::AVG_SUM_OF_TYPE, StdLib::DATES, StdLib::FOREACH_IN, StdLib::INJECT, StdLib::IN_GROUPS_OF, StdLib::MAP, StdLib::MONTH_FROM_DATE, StdLib::RATIO, StdLib::REJECT, StdLib::SELECT, StdLib::SUM_OF_TYPE, StdLib::TOTAL_RANGE_SUM_OF_TYPE, StdLib::YEAR_FROM_DATE

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCalculator

Returns a new instance of Calculator.



515
516
517
# File 'lib/trxl/trxl.rb', line 515

def initialize
  @parser = TrxlParser.new
end

Class Method Details

.stdlib(function = nil) ⇒ Object



503
504
505
506
507
508
509
510
511
# File 'lib/trxl/trxl.rb', line 503

def stdlib(function = nil)
  if function
    Kernel.eval("Trxl::StdLib::#{function.to_s.upcase}").strip
  else
    Trxl::StdLib.constants.inject('') do |lib, const|
      lib << Kernel.eval("Trxl::StdLib::#{const}")
    end.strip
  end
end

Instance Method Details

#eval(expression, env = Environment.new, verbose = true, interpreter_mode = false) ⇒ Object

may raise eval an expression in calculations.treetop grammar eval an already parsed Treetop::Runtime::SyntaxNode



552
553
554
555
556
557
558
559
# File 'lib/trxl/trxl.rb', line 552

def eval(expression, env = Environment.new, verbose = true, interpreter_mode = false)
  if expression.is_a?(Treetop::Runtime::SyntaxNode)
    interpreter_mode ? [ expression.eval(env), env ] : expression.eval(env)
  else
    ast = parse(expression, verbose)
    interpreter_mode ? [ ast.eval(env), env ] : ast.eval(env)
  end
end

#parse(code, verbose = true) ⇒ Object

may raise overwrite treetop to provide more precise exceptions



521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
# File 'lib/trxl/trxl.rb', line 521

def parse(code, verbose = true)
  if ast = @parser.parse(code)
    ast
  else
    failure_idx = @parser.failure_index
    
    # extract code snippet where parse error happened
    start = ((idx = failure_idx - 12) < 0 ? 0 : idx)
    stop  = ((idx = failure_idx + 12) > code.size ? code.size : idx)
    local_code = code.slice(start..stop).to_s.gsub(/\n|\r/, "")
    
    msg =  "Parse Error at index #{failure_idx} (showing excerpt):\n"
    msg << "... #{local_code} ...\n"
    
    # mark the exact offset where the parse error happened
    offset = (start == 0) ? failure_idx + 4 : 16
    offset.times { msg << ' '}; msg << "^\n"
    
    if verbose
      # show the originial trxl program
      msg << "Original Code:\n#{code}\n\n"
      # add detailed treetop parser error messages
      msg << @parser.failure_reason
    end
    raise(Trxl::FatalParseError, msg)
  end
end