Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 103 lines (82 sloc) 2.347 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
base = File.expand_path "../", __FILE__

unless Object.const_defined?(:RUBY_ENGINE) && RUBY_ENGINE == "rbx"
  ext_dir = "ruby"
  require base + "/mri_bridge"
else
  ext_dir = Object.const_get :RUBY_ENGINE
end

require base + "/ext/melbourne/#{ext_dir}/melbourne"
require base + "/melbourne/processor"

class String
  def to_ast(name="(eval)", line=1)
    Rubinius::Melbourne.parse_string self, name, line
  end

  def to_sexp(name="(eval)", line=1)
    to_ast(name, line).to_sexp
  end
end

class File
  def self.to_ast(name, line=1)
    Rubinius::Melbourne.parse_file name, line
  end

  def self.to_sexp(name, line=1)
    to_ast(name, line).to_sexp
  end
end

module Rubinius
  class Melbourne
    attr_accessor :transforms
    attr_accessor :magic_handler

    def self.parse_string(string, name="(eval)", line=1)
      new(name, line).parse_string string
    end

    def self.parse_file(name, line=1)
      new(name, line).parse_file
    end

    def initialize(name, line, transforms=[])
      @name = name
      @line = line
      @transforms = transforms
      @magic_handler = nil
      @data_offset = nil

      # There can be multiple reported, we need to track them all.
      @syntax_errors = []
    end

    attr_reader :syntax_errors

    def add_magic_comment(str)
      if @magic_handler
        @magic_handler.add_magic_comment str
      end
    end

    def process_data(offset)
      @data_offset = offset
    end

    def syntax_error
      raise @syntax_errors[0] unless @syntax_errors.empty?
    end

    def parse_string(string)
      syntax_error unless ast = string_to_ast(string, @name, @line)
      ast
    end

    def parse_file
      unless @name and File.exists? @name
        raise Errno::ENOENT, @name.inspect
      end

      syntax_error unless ast = file_to_ast(@name, @line)
      ast = AST::EndData.new @data_offset, ast if @data_offset
      ast
    end

    def process_transforms(line, receiver, name, arguments, privately=false)
      @transforms.each do |transform|
        next unless transform.transform_kind == :call

        if node = transform.match?(line, receiver, name, arguments, privately)
          unless node.kind_of? AST::Node
            node = transform.new line, receiver, name, arguments, privately
          end
          return node
        end
      end
      nil
    end
  end
end
Something went wrong with that request. Please try again.