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