Convert a `RvInstruction` stream to a typed `AsmToken` stream. Tokens that cannot be parsed are emitted as `AsmToken::Comment` with the raw text so nothing is silently lost -- the caller can choose to error on those.
(tokens: &[RvInstruction])
| 42 | pub fn parse(tokens: &[RvInstruction]) -> Vec<AsmToken> { |
| 43 | let mut out = Vec::with_capacity(tokens.len()); |
| 44 | for tok in tokens { |
| 45 | match tok { |
| 46 | RvInstruction::Real(inst) => out.push(AsmToken::Real(inst.clone())), |
| 47 | RvInstruction::Pseudo(p) => match p { |
| 48 | // Keep symbol-bearing pseudos unresolved so pass-2 can |
| 49 | // either resolve them immediately or emit relocation records. |
| 50 | PseudoInstruction::Call { symbol } => out.push(AsmToken::Call { |
| 51 | symbol: symbol.clone(), |
| 52 | }), |
| 53 | PseudoInstruction::Tail { symbol } => out.push(AsmToken::Tail { |
| 54 | symbol: symbol.clone(), |
| 55 | }), |
| 56 | PseudoInstruction::La { rd, symbol } => out.push(AsmToken::La { |
| 57 | rd: *rd, |
| 58 | symbol: symbol.clone(), |
| 59 | }), |
| 60 | _ => { |
| 61 | for real in p.expand() { |
| 62 | out.push(AsmToken::Real(real)); |
| 63 | } |
| 64 | } |
| 65 | }, |
| 66 | RvInstruction::Label(name) => out.push(AsmToken::Label(name.clone())), |
| 67 | RvInstruction::Comment(_) => out.push(AsmToken::Comment), |
| 68 | RvInstruction::SourceLoc { file, line } => out.push(AsmToken::Loc { |
| 69 | file: file.clone(), |
| 70 | line: *line, |
| 71 | }), |
| 72 | RvInstruction::Directive(raw) => { |
| 73 | parse_directive_or_instruction(raw, &mut out); |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | out |
| 78 | } |
| 79 |