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_HASH_RANGE_VALUE_SUM, StdLib::AVG_HASH_VALUE_SUM, StdLib::AVG_RANGE_SUM, StdLib::AVG_RANGE_SUM_OF_TYPE, StdLib::AVG_SUM_OF_TYPE, StdLib::DATES, StdLib::FOREACH_IN, StdLib::HASH_RANGE_VALUES, StdLib::HASH_RANGE_VALUE_SUM, StdLib::HASH_VALUES, StdLib::HASH_VALUE_SUM, 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.



561
562
563
# File 'lib/trxl/trxl.rb', line 561

def initialize
  @parser = TrxlParser.new
end

Class Method Details

.stdlib(function = nil) ⇒ Object



549
550
551
552
553
554
555
556
557
# File 'lib/trxl/trxl.rb', line 549

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



598
599
600
601
602
603
604
605
# File 'lib/trxl/trxl.rb', line 598

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



567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
# File 'lib/trxl/trxl.rb', line 567

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