Fix up Rubinius specific library specs.
[rbx.git] / lib / compiler / text.rb
blob4205ea05356bd94ba2c521e791bfd50321455448
1 require 'compiler/compiler'
3 class Compiler
5   ##
6   # An alternate generator that prints out bytecode for display.
8   class TextGenerator
10     @@method_id = 0
12     def initialize
13       @text = ""
14       @label = 0
15       @other_methods = {}
16       @ip = 0
17       @file = "(unknown)"
18       @line = 0
19     end
21     attr_reader :text, :ip, :file, :line
22     attr_accessor :redo, :retry, :break, :next
24     def advanced_since?(old)
25       old < @ip
26     end
28     def advance(count=1)
29       @ip += count
30     end
32     class Label
33       def initialize(gen, idx)
34         @gen = gen
35         @index = idx
36       end
38       attr_reader :index
40       def set!
41         @gen.set_label(@index)
42       end
44       def inspect
45         "l#{@index}"
46       end
47     end
49     def new_label
50       Label.new(self, @label += 1)
51     end
53     def set_label(idx)
54       @text << "l#{idx}:\n"
55     end
57     def add_text(text)
58       @text << text
59       @text << "\n"
60     end
62     def run(node)
63       node.bytecode(self)
64     end
66     def set_line(line, file)
67       @file, @line = file, line
68       @text << "#line #{line}\n"
69     end
71     def close
72       return if @other_methods.empty?
73       @other_methods.each_pair do |i,m|
74         @text << "\n:==== Method #{i} ====\n"
75         @text << m.generator.text
76         @text << "\n"
77       end
78     end
80     def method_missing(op, *args)
81       if args.empty?
82         @text << "#{op}\n"
83         advance
84       else
85         @text << "#{op} #{args.join(' ', :inspect)}\n"
86         advance 1 + args.size
87       end
88     end
90     def add(thing)
91       method_missing(thing)
92     end
94     def push(what)
95       @text << "push #{what}\n"
96       advance
97     end
99     def send(meth, count, priv=false)
100       @text << "send #{meth} #{count}"
101       if priv
102         @text << " true ; allow private\n"
103       else
104         @text << "\n"
105       end
106       advance
107     end
109     def dup
110       method_missing :dup
111     end
113     def equal
114       method_missing :equal
115     end
117     def push_literal(lit)
118       if lit.kind_of? MethodDescription
119         @text << "push_literal #<Method #{@@method_id}>\n"
121         @other_methods[@@method_id] = lit
122         @@method_id += 1
123         advance
124       else
125         method_missing :push_literal, lit
126       end
127     end
129     def as_primitive(name)
130       @text << "#primitive #{name}\n"
131     end
133     class EB
134       @@ids = 0
136       def initialize(gen)
137         @gen = gen
138         @idx = (@@ids += 1)
139       end
141       def start!
142         @gen.add_text "; exc#{@idx} start"
143       end
145       def handle!
146         @gen.add_text "; exc#{@idx} end"
147       end
148     end
150     def exceptions
151       ex = EB.new(self)
152       ex.start!
153       yield ex
154     end
156   end