forked from rubinius/rubinius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
melbourne.rb
111 lines (89 loc) · 2.49 KB
/
melbourne.rb
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
103
104
105
106
107
108
109
110
111
require Rubinius::PARSER_EXT_PATH
require Rubinius::PARSER_PATH + "/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
attr_accessor :references
attr_reader :pre_exe
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
@pre_exe = []
# There can be multiple reported, we need to track them all.
@syntax_errors = []
end
attr_reader :syntax_errors
def add_pre_exe(node)
@pre_exe << node if node
end
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
alias_method :file_to_ast, :file_to_ast_18
alias_method :string_to_ast, :string_to_ast_18
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
class Melbourne19 < Melbourne
alias_method :file_to_ast, :file_to_ast_19
alias_method :string_to_ast, :string_to_ast_19
end
class Melbourne20 < Melbourne19
end
end