@@ -77,6 +77,9 @@ impl TokensForOperand<String> {
7777
7878// FIXME(eddyb) keep a `&'static spec::Spec` if that can even speed up anything.
7979struct 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+
8083 /// Input immediate operands to print from (may be grouped e.g. into literals).
8184 imms : iter:: Peekable < IMMS > ,
8285
@@ -123,7 +126,41 @@ impl<IMMS: Iterator<Item = spv::Imm>, ID, IDS: Iterator<Item = ID>> OperandPrint
123126 let def = kind. def ( ) ;
124127 assert ! ( matches!( def, spec:: OperandKindDef :: Literal { .. } ) ) ;
125128
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 {
127164 // FIXME(eddyb) deduplicate with `spv::extract_literal_string`.
128165 let bytes: SmallVec < [ u8 ; 64 ] > = words
129166 . into_iter ( )
@@ -260,6 +297,7 @@ impl<IMMS: Iterator<Item = spv::Imm>, ID, IDS: Iterator<Item = ID>> OperandPrint
260297/// an enumerand with parameters (which consumes more immediates).
261298pub fn operand_from_imms < T > ( imms : impl IntoIterator < Item = spv:: Imm > ) -> TokensForOperand < T > {
262299 let mut printer = OperandPrinter {
300+ wk : & spec:: Spec :: get ( ) . well_known ,
263301 imms : imms. into_iter ( ) . peekable ( ) ,
264302 ids : iter:: empty ( ) . peekable ( ) ,
265303 out : TokensForOperand :: default ( ) ,
@@ -282,6 +320,7 @@ pub fn inst_operands<ID>(
282320 ids : impl IntoIterator < Item = ID > ,
283321) -> impl Iterator < Item = TokensForOperand < ID > > {
284322 OperandPrinter {
323+ wk : & spec:: Spec :: get ( ) . well_known ,
285324 imms : imms. into_iter ( ) . peekable ( ) ,
286325 ids : ids. into_iter ( ) . peekable ( ) ,
287326 out : TokensForOperand :: default ( ) ,
0 commit comments