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.



590
591
592
# File 'lib/trxl/trxl.rb', line 590

def initialize
  @parser = TrxlParser.new
end

Class Method Details

.stdlib(function = nil) ⇒ Object



578
579
580
581
582
583
584
585
586
# File 'lib/trxl/trxl.rb', line 578

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



627
628
629
630
631
632
633
634
# File 'lib/trxl/trxl.rb', line 627

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



596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
# File 'lib/trxl/trxl.rb', line 596

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