Include generated Opcode enum in the immediates module.
Generate nice doc comments for the Opcode enum variants that 'cargo doc' will pick up. Include a `Display` trait implementation that prints the lower snake-case version of the opcode name.
This commit is contained in:
@@ -17,13 +17,31 @@ def collect_instr_groups(targets):
|
||||
def gen_opcodes(groups, out_dir):
|
||||
"""Generate opcode enumerations."""
|
||||
fmt = srcgen.Formatter()
|
||||
fmt.line('enum Opcode {')
|
||||
fmt.indent_push()
|
||||
for g in groups:
|
||||
for i in g.instructions:
|
||||
fmt.line(i.camel_name + ',')
|
||||
fmt.indent_pop()
|
||||
fmt.line('}')
|
||||
|
||||
fmt.doc_comment('An instruction opcode.')
|
||||
fmt.doc_comment('')
|
||||
fmt.doc_comment('All instructions from all supported targets are present.')
|
||||
fmt.line('#[derive(Copy, Clone, PartialEq, Eq, Debug)]')
|
||||
instrs = []
|
||||
with fmt.indented('pub enum Opcode {', '}'):
|
||||
for g in groups:
|
||||
for i in g.instructions:
|
||||
instrs.append(i)
|
||||
# Build a doc comment.
|
||||
prefix = ', '.join(o.name for o in i.outs)
|
||||
if prefix:
|
||||
prefix = prefix + ' = '
|
||||
suffix = ', '.join(o.name for o in i.ins)
|
||||
fmt.doc_comment('`{}{} {}`.'.format(prefix, i.name, suffix))
|
||||
# Enum variant itself.
|
||||
fmt.line(i.camel_name + ',')
|
||||
|
||||
with fmt.indented('impl Display for Opcode {', '}'):
|
||||
with fmt.indented('fn fmt(&self, f: &mut Formatter) -> fmt::Result {', '}'):
|
||||
with fmt.indented('f.write_str(match *self {', '})'):
|
||||
for i in instrs:
|
||||
fmt.format('Opcode::{} => "{}",', i.camel_name, i.name)
|
||||
|
||||
fmt.update_file('opcodes.rs', out_dir)
|
||||
|
||||
def generate(targets, out_dir):
|
||||
|
||||
@@ -25,15 +25,15 @@ class Formatter(object):
|
||||
>>> f.indent_push()
|
||||
>>> f.comment('Nested comment')
|
||||
>>> f.indent_pop()
|
||||
>>> f.line('Back again')
|
||||
>>> f.format('Back {} again', 'home')
|
||||
>>> f.writelines()
|
||||
Hello line 1
|
||||
// Nested comment
|
||||
Back again
|
||||
// Nested comment
|
||||
Back home again
|
||||
|
||||
"""
|
||||
|
||||
shiftwidth = 2
|
||||
shiftwidth = 4
|
||||
|
||||
def __init__(self):
|
||||
self.indent = ''
|
||||
@@ -64,10 +64,49 @@ class Formatter(object):
|
||||
with open(filename, 'w') as f:
|
||||
self.writelines(f)
|
||||
|
||||
class _IndentedScope(object):
|
||||
def __init__(self, fmt, after):
|
||||
self.fmt = fmt
|
||||
self.after = after
|
||||
|
||||
def __enter__(self):
|
||||
self.fmt.indent_push();
|
||||
|
||||
def __exit__(self, t, v, tb):
|
||||
self.fmt.indent_pop()
|
||||
if self.after:
|
||||
self.fmt.line(self.after)
|
||||
|
||||
def indented(self, before=None, after=None):
|
||||
"""
|
||||
Return a scope object for use with a `with` statement:
|
||||
|
||||
>>> f = Formatter()
|
||||
>>> with f.indented('prefix {', '} suffix'):
|
||||
... f.line('hello')
|
||||
>>> f.writelines()
|
||||
prefix {
|
||||
hello
|
||||
} suffix
|
||||
|
||||
The optional `before` and `after` parameters are surrounding lines
|
||||
which are *not* indented.
|
||||
"""
|
||||
if before:
|
||||
self.line(before)
|
||||
return self._IndentedScope(self, after)
|
||||
|
||||
def format(self, fmt, *args):
|
||||
self.line(fmt.format(*args))
|
||||
|
||||
def comment(self, s):
|
||||
"""Add a comment line."""
|
||||
self.line('// ' + s)
|
||||
|
||||
def doc_comment(self, s):
|
||||
"""Add a documentation comment line."""
|
||||
self.line('/// ' + s)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
||||
Reference in New Issue
Block a user