public
Description: Rubinius, the Ruby VM
Homepage: http://rubini.us
Clone URL: git://github.com/evanphx/rubinius.git
Search Repo:
Switch to RDoc-based opcode documentation system
drbrain (author)
Mon Feb 11 17:31:04 -0800 2008
commit  0fd7f05ea1fdf4df3098f438ae4c3aab916d1ca9
tree    10784073b16daaa30c7bbc2bfecebfbffb7e5fc9
parent  6b6adb4dbfe802150cc786f003b5942b44e5e2b0
...
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
...
 
 
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
112
113
114
115
116
117
118
119
120
121
122
 
 
 
 
 
 
 
 
 
 
 
 
 
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
 
 
0
@@ -1,77 +1,200 @@
0
-require 'erb'
0
-require 'op_code_info'
0
+require 'rdoc/rdoc'
0
+require 'rdoc/generator'
0
+require 'rdoc/markup/to_html_hyperlink'
0
+require 'kernel/core/iseq'
0
 
0
+OP_CODE_TEMPLATE = <<-EOF
0
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
0
+<html>
0
+<head>
0
+<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
0
+<title>Rubinius Virtual Machine OpCode: %s</title>
0
+<link rel="stylesheet" href="../styles.css" type="text/css" />
0
+</head>
0
+<body>
0
+<div id="%s">
0
+%s
0
+</div>
0
+</body>
0
+</html>
0
+EOF
0
 
0
-module OpCode
0
- class HTMLEmitter
0
- include ERB::Util
0
+TOC_TEMPLATE = <<-EOF
0
+<html>
0
+<head>
0
+<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
0
+<title>Rubinius Virtual Machine OpCodes</title>
0
+<link rel="stylesheet" href="styles.css" type="text/css" />
0
+</head>
0
 
0
- def create_index_html(op_codes, template)
0
- File.open("toc.html", 'w') do |f|
0
- html = template.result(binding)
0
- f.puts html
0
- end
0
+<body>
0
+<ul id="chapters">
0
+<li><a href="intro.html" target="op_code">Intro</a></li>
0
+<li><a href="shotgun.html" target="op_code">Shotgun</a></li>
0
+<li><a href="rubinius_vs_mri.html" target="op_code">Rubinius vs MRI</a></li>
0
+<li><a href="concurrency.html" target="op_code">Concurrency</a></li>
0
+<li><a href="vm_interfaces.html" target="op_code">Interfacing to Rubinius</a></li>
0
+<li><a href="rbc_files.html" target="op_code">Rubinius Compiled Files</a></li>
0
+</ul>
0
+
0
+<h3>OpCodes</h3>
0
+
0
+<ul id="op_codes" class="toc_subsection">
0
+%s
0
+</ul>
0
+</body>
0
+<html>
0
+EOF
0
+
0
+class ToRubiniusOpCode < RDoc::Markup::ToHtmlHyperlink
0
+
0
+ def initialize(*args)
0
+ super
0
+
0
+ @markup.add_special(/<\/?code>/, :CODE)
0
+
0
+ @level = nil
0
+ @name = nil
0
+ @stack = nil
0
+ end
0
+
0
+ def accept_list_end(am, fragment)
0
+ if @level and fragment.level > @level
0
+ @stack << fragment
0
+ return
0
+ elsif fragment.level == @level then
0
+ @stack << fragment
0
+ make_stack am, @name, @stack
0
+ @stack = nil
0
+ @level = nil
0
+ else
0
+ super
0
     end
0
+ end
0
 
0
- def create_opcode_html(op_code, template)
0
- # Create documentation page for this op code
0
- file_name = "op_codes/#{op_code.mnemonic.to_s}.html"
0
- File.open(file_name, 'w') do |f|
0
- html = template.result(binding)
0
- f.puts html
0
- end
0
+ def accept_list_item(am, fragment)
0
+ if @level and fragment.level >= @level then
0
+ @stack << fragment
0
+ return
0
+ elsif fragment.param =~ /^Stack/ then
0
+ @stack = []
0
+ @name = fragment.param
0
+ @level = fragment.level + 1
0
     end
0
 
0
- # Supports VERY simple formatting instructions in a description. At present,
0
- # _italics_ is converted to italics, and *bold text* is converted to bold.
0
- # Links are supported via "link":url, and line breaks are converted to <p>.
0
- def markup_html(str)
0
- html = str.gsub(/(^|\W)_(\S([^_]|(_\w))*)_/){|m| "#{$1}<i>#{$2}</i>" }.gsub(/\*((\w|\s)+?)\*/) {|m| "<b>#{$1}</b>"}
0
- html = html.gsub(/@((\w|\s)+?)@/) {|m| "<code>#{$1}</code>"}
0
- html = html.gsub(/"(.+?)":((\w|\/)+(\.\w+)?)/){|m| "<a href=\"#{$2}\">#{$1}</a>"}
0
- %Q{<p>#{html.gsub("\n","</p><p>")}</p>}
0
+ super
0
+ end
0
+
0
+ def accept_list_start(am, fragment)
0
+ if @level and fragment.level >= @level
0
+ @stack << fragment
0
+ else
0
+ super
0
     end
0
+ end
0
 
0
- # Outputs a representation of the stack
0
- def markup_stack(ary)
0
- html = "<table>"
0
- ary.each do |i|
0
- html << "<tr><td>"
0
- case i
0
- when Array
0
- html << "[#{html_escape i.join(', ')}]"
0
- when Hash
0
- html << "{"
0
- html << (i.map do |key,val|
0
- html_escape "#{key}=>#{val}"
0
- end.join(', '))
0
- html << "}"
0
- else
0
- html << html_escape(i)
0
- end
0
+ def make_stack(am, name, stack)
0
+ level = stack.first.level
0
+
0
+ stack.each do |fragment|
0
+ case fragment
0
+ when RDoc::Markup::ListStart then
0
+ @res << "<table class=\"stack\">\n"
0
+ #@res << "<caption>#{name}</caption>"
0
+ when RDoc::Markup::ListEnd then
0
+ @res << "</table>\n"
0
+ when RDoc::Markup::ListItem then
0
+ @res << "<tr><td>#{fragment.txt}</td></tr>\n"
0
+ else
0
+ raise "Unknown fragment #{fragment.inspect}"
0
       end
0
- html << "</td></tr></table>"
0
- html
0
     end
0
   end
0
+
0
+ ##
0
+ # This is a hack around a misfeature in RDoc for labeled list handling.
0
+
0
+ def handle_special_CODE(special)
0
+ ''
0
+ end
0
+
0
 end
0
 
0
-op_code_template = ERB.new(File.read('op_codes/op_code_template.html.erb'),nil,'<>')
0
-index_template = ERB.new(File.read('toc.html.erb'), nil, '<>')
0
-
0
-op_codes = []
0
-emitter = OpCode::HTMLEmitter.new
0
-OpCode::Info.op_codes.each do |op|
0
- begin
0
- op_code = OpCode::Info.new(op)
0
- op_codes << op_code
0
- emitter.create_opcode_html(op_code, op_code_template) if ARGV.empty? or ARGV.include? op.to_s
0
- rescue Exception => ex
0
- puts "An exception occurred while processing op code '#{op_code}'"
0
- raise ex
0
+options = RDoc::Options.new({})
0
+options.generator = nil
0
+options.files = ['shotgun/lib/instructions.rb']
0
+options.inline_source = true
0
+
0
+rdoc = RDoc::RDoc.new
0
+
0
+toplevels = rdoc.parse_files options
0
+
0
+files, classes = RDoc::Generator::Context.build_indicies toplevels, options
0
+
0
+formatter = ToRubiniusOpCode.new '', nil, true
0
+
0
+toc = []
0
+
0
+classes.each do |klass|
0
+ formatter.context = klass
0
+
0
+ klass.methods.each do |method|
0
+ str = method.context.comment
0
+
0
+ source = method.context.token_stream.find do |ts|
0
+ RubyToken::TkSTRING === ts
0
+ end
0
+
0
+ source = source.text[1..-2]
0
+
0
+ source = source.split("\\n").map do |line|
0
+ " #{line}"
0
+ end.join("\n").rstrip
0
+
0
+ if str =~ /^(?>\s*)[^\#]/ then
0
+ content = str
0
+ else
0
+ content = str.gsub(/^\s*(#+)/) { $1.tr '#', ' ' }
0
+ end
0
+
0
+ bytecode = InstructionSet[method.name.intern].bytecode rescue nil
0
+
0
+ next if bytecode.nil?
0
+
0
+ content = <<-EOF
0
+ = \\#{method.name}
0
+
0
+ [Byte code] 0x#{bytecode.to_s 16}
0
+#{content}
0
+ [Source]
0
+ <code>
0
+#{source}
0
+ </code>
0
+ EOF
0
+
0
+ html = OP_CODE_TEMPLATE % [
0
+ method.name,
0
+ method.name,
0
+ formatter.convert(content)
0
+ ]
0
+
0
+ file = File.join 'doc', 'vm', 'op_codes', "#{method.name}.html"
0
+ File.open file, 'w' do |fp|
0
+ fp.puts html
0
+ end
0
+
0
+ toc << method.name
0
   end
0
 end
0
 
0
+toc = toc.sort.map do |name|
0
+ "<li><a href=\"op_codes/#{name}.html\">#{name}</a></li>"
0
+end.join "\n"
0
+
0
+toc_path = File.join 'doc', 'vm', 'toc.html'
0
+toc_html = TOC_TEMPLATE % [toc]
0
+
0
+File.open toc_path, 'w' do |fp|
0
+ fp.puts toc_html
0
+end
0
 
0
-# Create index page
0
-emitter.create_index_html(op_codes, index_template)
...
3
4
5
6
 
7
8
9
 
 
 
 
10
11
12
...
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
...
61
62
63
64
65
 
 
 
 
...
3
4
5
 
6
7
8
9
10
11
12
13
14
15
16
...
24
25
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
28
29
30
31
 
32
33
34
35
36
37
38
39
 
40
41
42
 
43
44
45
46
...
48
49
50
 
 
51
52
53
54
0
@@ -3,10 +3,14 @@ body, table {
0
   font-size: 0.9em;
0
 }
0
 
0
-a, a:visited {
0
+:link, :visited {
0
   color: blue;
0
 }
0
 
0
+dt {
0
+ font-weight: bold;
0
+}
0
+
0
 ul#chapters {
0
   padding-left: 0px;
0
   font-size: 1em;
0
@@ -20,40 +24,23 @@ ul#chapters li, ul.toc_subsection li {
0
   list-style-type: none;
0
 }
0
 
0
-table.formatted {
0
- margin: 2px 0px;
0
- border-style: solid;
0
- border-color: silver;
0
- border-width: 1px;
0
- border-spacing: 1px;
0
- border-collapse: collapse;
0
-}
0
-
0
-table.formatted th { padding: 2px 5px; color: #FFFFFF; background-color: silver; }
0
-
0
-table.formatted td {
0
- padding: 5px 3px;
0
- border-style: solid;
0
- border-color: silver;
0
- border-width: 1px;
0
-}
0
-
0
-table#tags tr td:first-child { text-align: center; font-weight: bold; }
0
-
0
 .todo {
0
   color: red;
0
   font-style: italic;
0
 }
0
 
0
-.stack table table td {
0
+.stack {
0
+ border: 1px solid blue;
0
+}
0
+
0
+.stack td {
0
   width: 60px;
0
   border-width: 1px;
0
   border-style: solid;
0
- font-style: italic;
0
   text-align: center;
0
 }
0
 
0
-div.source pre {
0
+pre {
0
   color: darkblue;
0
   border-width: 1px;
0
   border-style: solid;
0
@@ -61,5 +48,7 @@ div.source pre {
0
   background-color: #ffffcc;
0
   padding: 5px;
0
 }
0
-ul#op_codes li i a:link { color: red; }
0
-ul#op_codes li i a:visited { color: red; }
0
+
0
+ul#op_codes li i :link { color: red; }
0
+ul#op_codes li i :visited { color: red; }
0
+
...
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
...
34
35
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
38
39
40
41
42
0
@@ -34,27 +34,9 @@ namespace "doc" do
0
       end
0
     end
0
 
0
- desc "Generate HTML in doc/vm from YAML and Textile sources"
0
- task "html"
0
-
0
- begin
0
- # Define tasks for each opcode html file on the corresponding YAML file
0
- require 'doc/vm/op_code_info'
0
- OpCode::Info.op_codes.each do |op|
0
- html = "doc/vm/op_codes/#{op}.html"
0
- yaml = "doc/vm/op_codes/#{op}.yaml"
0
- file html do
0
- cd 'doc/vm' do
0
- ruby "gen_op_code_html.rb #{op}"
0
- end
0
- end
0
- file html => yaml if File.exists?("doc/vm/op_codes/#{op}.yaml")
0
-
0
- task "html" => html
0
- end
0
-
0
- rescue LoadError
0
-
0
+ desc "Generate HTML in doc/vm"
0
+ task :html => :build do
0
+ rbx 'doc/vm/gen_op_code_html.rb'
0
     end
0
 
0
     # Define tasks for each section html file on the corresponding textile file

Comments

    No one has commented yet.