@@ -77,6 +77,9 @@ impl TokensForOperand<String> {
77
77
78
78
// FIXME(eddyb) keep a `&'static spec::Spec` if that can even speed up anything.
79
79
struct OperandPrinter < IMMS : Iterator < Item = spv:: Imm > , ID , IDS : Iterator < Item = ID > > {
80
+ // FIXME(eddyb) use a field like this to interpret `Opcode`/`OperandKind`, too.
81
+ wk : & ' static spv:: spec:: WellKnown ,
82
+
80
83
/// Input immediate operands to print from (may be grouped e.g. into literals).
81
84
imms : iter:: Peekable < IMMS > ,
82
85
@@ -123,7 +126,41 @@ impl<IMMS: Iterator<Item = spv::Imm>, ID, IDS: Iterator<Item = ID>> OperandPrint
123
126
let def = kind. def ( ) ;
124
127
assert ! ( matches!( def, spec:: OperandKindDef :: Literal { .. } ) ) ;
125
128
126
- let literal_token = if kind == spec:: Spec :: get ( ) . well_known . LiteralString {
129
+ let literal_token = if kind == self . wk . LiteralSpecConstantOpInteger {
130
+ assert_eq ! ( words. len( ) , 1 ) ;
131
+ let ( _, inner_name, inner_def) = match u16:: try_from ( first_word)
132
+ . ok ( )
133
+ . and_then ( spec:: Opcode :: try_from_u16_with_name_and_def)
134
+ {
135
+ Some ( opcode_name_and_def) => opcode_name_and_def,
136
+ None => {
137
+ self . out . tokens . push ( Token :: Error ( format ! (
138
+ "/* {first_word} not a valid `OpSpecConstantOp` opcode */"
139
+ ) ) ) ;
140
+ return ;
141
+ }
142
+ } ;
143
+
144
+ // FIXME(eddyb) deduplicate this with `enumerant_params`.
145
+ self . out . tokens . push ( Token :: EnumerandName ( inner_name) ) ;
146
+
147
+ let mut first = true ;
148
+ for ( inner_mode, inner_name_and_kind) in inner_def. all_operands_with_names ( ) {
149
+ if inner_mode == spec:: OperandMode :: Optional && self . is_exhausted ( ) {
150
+ break ;
151
+ }
152
+
153
+ self . out . tokens . push ( Token :: Punctuation ( if first { "(" } else { ", " } ) ) ;
154
+ first = false ;
155
+
156
+ let ( inner_name, inner_kind) = inner_name_and_kind. name_and_kind ( ) ;
157
+ self . operand ( inner_name, inner_kind) ;
158
+ }
159
+ if !first {
160
+ self . out . tokens . push ( Token :: Punctuation ( ")" ) ) ;
161
+ }
162
+ return ;
163
+ } else if kind == self . wk . LiteralString {
127
164
// FIXME(eddyb) deduplicate with `spv::extract_literal_string`.
128
165
let bytes: SmallVec < [ u8 ; 64 ] > = words
129
166
. into_iter ( )
@@ -260,6 +297,7 @@ impl<IMMS: Iterator<Item = spv::Imm>, ID, IDS: Iterator<Item = ID>> OperandPrint
260
297
/// an enumerand with parameters (which consumes more immediates).
261
298
pub fn operand_from_imms < T > ( imms : impl IntoIterator < Item = spv:: Imm > ) -> TokensForOperand < T > {
262
299
let mut printer = OperandPrinter {
300
+ wk : & spec:: Spec :: get ( ) . well_known ,
263
301
imms : imms. into_iter ( ) . peekable ( ) ,
264
302
ids : iter:: empty ( ) . peekable ( ) ,
265
303
out : TokensForOperand :: default ( ) ,
@@ -282,6 +320,7 @@ pub fn inst_operands<ID>(
282
320
ids : impl IntoIterator < Item = ID > ,
283
321
) -> impl Iterator < Item = TokensForOperand < ID > > {
284
322
OperandPrinter {
323
+ wk : & spec:: Spec :: get ( ) . well_known ,
285
324
imms : imms. into_iter ( ) . peekable ( ) ,
286
325
ids : ids. into_iter ( ) . peekable ( ) ,
287
326
out : TokensForOperand :: default ( ) ,
0 commit comments