az65/z80/
mod.rs

1use std::{
2    fmt::{self, Display, Formatter},
3    io::Read,
4};
5
6use crate::{
7    assembler::{ArchAssembler, Assembler, AssemblerError},
8    expr::ExprNode,
9    fileman::FileSystem,
10    lexer::{self, ArchTokens, SourceLoc, SymbolName, Token},
11    linker::Link,
12};
13
14#[cfg(test)]
15mod tests;
16
17macro_rules! asm_err {
18    ($loc:expr, $($arg:tt)*) => {
19        Err(($loc, AssemblerError(format!($($arg)*))))
20    };
21}
22
23#[derive(Debug, Copy, Clone, Eq, PartialEq)]
24pub enum OperationName {
25    Adc,
26    Add,
27    And,
28    Bit,
29    Call,
30    Ccf,
31    Cp,
32    Cpd,
33    Cpdr,
34    Cpi,
35    Cpir,
36    Cpl,
37    Daa,
38    Dec,
39    Di,
40    Djnz,
41    Ei,
42    Ex,
43    Exx,
44    Halt,
45    Im,
46    In,
47    Inc,
48    Ind,
49    Indr,
50    Ini,
51    Inir,
52    Jp,
53    Jr,
54    Ld,
55    Ldd,
56    Lddr,
57    Ldi,
58    Ldir,
59    Neg,
60    Nop,
61    Or,
62    Otdr,
63    Otir,
64    Out,
65    Outd,
66    Outi,
67    Pop,
68    Push,
69    Res,
70    Ret,
71    Reti,
72    Retn,
73    Rl,
74    Rla,
75    Rlc,
76    Rlca,
77    Rld,
78    Rr,
79    Rra,
80    Rrc,
81    Rrca,
82    Rrd,
83    Rst,
84    Sbc,
85    Scf,
86    Set,
87    Sla,
88    Sll,
89    Sra,
90    Srl,
91    Sub,
92    Xor,
93}
94
95impl lexer::OperationName for OperationName {
96    fn parse<S: AsRef<str>>(s: S) -> Option<Self> {
97        match s.as_ref() {
98            "adc" | "ADC" => Some(Self::Adc),
99            "add" | "ADD" => Some(Self::Add),
100            "and" | "AND" => Some(Self::And),
101            "bit" | "BIT" => Some(Self::Bit),
102            "call" | "CALL" => Some(Self::Call),
103            "ccf" | "CCF" => Some(Self::Ccf),
104            "cp" | "CP" => Some(Self::Cp),
105            "cpd" | "CPD" => Some(Self::Cpd),
106            "cpdr" | "CPDR" => Some(Self::Cpdr),
107            "cpi" | "CPI" => Some(Self::Cpi),
108            "cpir" | "CPIR" => Some(Self::Cpir),
109            "cpl" | "CPL" => Some(Self::Cpl),
110            "daa" | "DAA" => Some(Self::Daa),
111            "dec" | "DEC" => Some(Self::Dec),
112            "di" | "DI" => Some(Self::Di),
113            "djnz" | "DJNZ" => Some(Self::Djnz),
114            "ei" | "EI" => Some(Self::Ei),
115            "ex" | "EX" => Some(Self::Ex),
116            "exx" | "EXX" => Some(Self::Exx),
117            "halt" | "HALT" => Some(Self::Halt),
118            "im" | "IM" => Some(Self::Im),
119            "in" | "IN" => Some(Self::In),
120            "inc" | "INC" => Some(Self::Inc),
121            "ind" | "IND" => Some(Self::Ind),
122            "indr" | "INDR" => Some(Self::Indr),
123            "ini" | "INI" => Some(Self::Ini),
124            "inir" | "INIR" => Some(Self::Inir),
125            "jp" | "JP" => Some(Self::Jp),
126            "jr" | "JR" => Some(Self::Jr),
127            "ld" | "LD" => Some(Self::Ld),
128            "ldd" | "LDD" => Some(Self::Ldd),
129            "lddr" | "LDDR" => Some(Self::Lddr),
130            "ldi" | "LDI" => Some(Self::Ldi),
131            "ldir" | "LDIR" => Some(Self::Ldir),
132            "neg" | "NEG" => Some(Self::Neg),
133            "nop" | "NOP" => Some(Self::Nop),
134            "or" | "OR" => Some(Self::Or),
135            "otdr" | "OTDR" => Some(Self::Otdr),
136            "otir" | "OTIR" => Some(Self::Otir),
137            "out" | "OUT" => Some(Self::Out),
138            "outd" | "OUTD" => Some(Self::Outd),
139            "outi" | "OUTI" => Some(Self::Outi),
140            "pop" | "POP" => Some(Self::Pop),
141            "push" | "PUSH" => Some(Self::Push),
142            "res" | "RES" => Some(Self::Res),
143            "ret" | "RET" => Some(Self::Ret),
144            "reti" | "RETI" => Some(Self::Reti),
145            "retn" | "RETN" => Some(Self::Retn),
146            "rl" | "RL" => Some(Self::Rl),
147            "rla" | "RLA" => Some(Self::Rla),
148            "rlc" | "RLC" => Some(Self::Rlc),
149            "rlca" | "RLCA" => Some(Self::Rlca),
150            "rld" | "RLD" => Some(Self::Rld),
151            "rr" | "RR" => Some(Self::Rr),
152            "rra" | "RRA" => Some(Self::Rra),
153            "rrc" | "RRC" => Some(Self::Rrc),
154            "rrca" | "RRCA" => Some(Self::Rrca),
155            "rrd" | "RRD" => Some(Self::Rrd),
156            "rst" | "RST" => Some(Self::Rst),
157            "sbc" | "SBC" => Some(Self::Sbc),
158            "scf" | "SCF" => Some(Self::Scf),
159            "set" | "SET" => Some(Self::Set),
160            "sla" | "SLA" => Some(Self::Sla),
161            "sll" | "SLL" => Some(Self::Sll),
162            "sra" | "SRA" => Some(Self::Sra),
163            "srl" | "SRL" => Some(Self::Srl),
164            "sub" | "SUB" => Some(Self::Sub),
165            "xor" | "XOR" => Some(Self::Xor),
166            _ => None,
167        }
168    }
169}
170
171impl Display for OperationName {
172    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
173        write!(
174            f,
175            "{}",
176            match self {
177                Self::Adc => "adc",
178                Self::Add => "add",
179                Self::And => "and",
180                Self::Bit => "bit",
181                Self::Call => "call",
182                Self::Ccf => "ccf",
183                Self::Cp => "cp",
184                Self::Cpd => "cpd",
185                Self::Cpdr => "cpdr",
186                Self::Cpi => "cpi",
187                Self::Cpir => "cpir",
188                Self::Cpl => "cpl",
189                Self::Daa => "daa",
190                Self::Dec => "dec",
191                Self::Di => "di",
192                Self::Djnz => "djnz",
193                Self::Ei => "ei",
194                Self::Ex => "ex",
195                Self::Exx => "exx",
196                Self::Halt => "halt",
197                Self::Im => "im",
198                Self::In => "in",
199                Self::Inc => "inc",
200                Self::Ind => "ind",
201                Self::Indr => "indr",
202                Self::Ini => "ini",
203                Self::Inir => "inir",
204                Self::Jp => "jp",
205                Self::Jr => "jr",
206                Self::Ld => "ld",
207                Self::Ldd => "ldd",
208                Self::Lddr => "lddr",
209                Self::Ldi => "ldi",
210                Self::Ldir => "ldir",
211                Self::Neg => "neg",
212                Self::Nop => "nop",
213                Self::Or => "or",
214                Self::Otdr => "otdr",
215                Self::Otir => "otir",
216                Self::Out => "out",
217                Self::Outd => "outd",
218                Self::Outi => "outi",
219                Self::Pop => "pop",
220                Self::Push => "push",
221                Self::Res => "res",
222                Self::Ret => "ret",
223                Self::Reti => "reti",
224                Self::Retn => "retn",
225                Self::Rl => "rl",
226                Self::Rla => "rla",
227                Self::Rlc => "rlc",
228                Self::Rlca => "rlca",
229                Self::Rld => "rld",
230                Self::Rr => "rr",
231                Self::Rra => "rra",
232                Self::Rrc => "rrc",
233                Self::Rrca => "rrca",
234                Self::Rrd => "rrd",
235                Self::Rst => "rst",
236                Self::Sbc => "sbc",
237                Self::Scf => "scf",
238                Self::Set => "set",
239                Self::Sla => "sla",
240                Self::Sll => "sll",
241                Self::Sra => "sra",
242                Self::Srl => "srl",
243                Self::Sub => "sub",
244                Self::Xor => "xor",
245            }
246        )
247    }
248}
249
250#[derive(Debug, Copy, Clone, Eq, PartialEq)]
251pub enum RegisterName {
252    A,
253    B,
254    C,
255    D,
256    E,
257    H,
258    L,
259    AF,
260    BC,
261    DE,
262    HL,
263    IX,
264    IY,
265    IXL,
266    IXH,
267    IYL,
268    IYH,
269    PC,
270    SP,
271    AFPrime,
272    I,
273    R,
274}
275
276impl lexer::RegisterName for RegisterName {
277    fn parse<S: AsRef<str>>(s: S) -> Option<Self> {
278        match s.as_ref() {
279            "a" | "A" => Some(Self::A),
280            "b" | "B" => Some(Self::B),
281            "c" | "C" => Some(Self::C),
282            "d" | "D" => Some(Self::D),
283            "e" | "E" => Some(Self::E),
284            "h" | "H" => Some(Self::H),
285            "l" | "L" => Some(Self::L),
286            "af" | "AF" => Some(Self::AF),
287            "bc" | "BC" => Some(Self::BC),
288            "de" | "DE" => Some(Self::DE),
289            "hl" | "HL" => Some(Self::HL),
290            "ix" | "IX" => Some(Self::IX),
291            "iy" | "IY" => Some(Self::IY),
292            "ixl" | "IXL" => Some(Self::IXL),
293            "ixh" | "IXH" => Some(Self::IXH),
294            "iyl" | "IYL" => Some(Self::IYL),
295            "iyh" | "IYH" => Some(Self::IYH),
296            "pc" | "PC" => Some(Self::PC),
297            "sp" | "SP" => Some(Self::SP),
298            "af'" | "AF'" => Some(Self::AFPrime),
299            "i" | "I" => Some(Self::I),
300            "r" | "R" => Some(Self::R),
301            _ => None,
302        }
303    }
304}
305
306impl Display for RegisterName {
307    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
308        write!(
309            f,
310            "{}",
311            match self {
312                Self::A => "a",
313                Self::B => "b",
314                Self::C => "c",
315                Self::D => "d",
316                Self::E => "e",
317                Self::H => "h",
318                Self::L => "l",
319                Self::AF => "af",
320                Self::BC => "bc",
321                Self::DE => "de",
322                Self::HL => "hl",
323                Self::IX => "ix",
324                Self::IY => "iy",
325                Self::IXL => "ixl",
326                Self::IXH => "ixh",
327                Self::IYL => "iyl",
328                Self::IYH => "iyh",
329                Self::PC => "pc",
330                Self::SP => "sp",
331                Self::AFPrime => "af'",
332                Self::I => "i",
333                Self::R => "r",
334            }
335        )
336    }
337}
338
339#[derive(Debug, Copy, Clone, Eq, PartialEq)]
340pub enum FlagName {
341    Zero,
342    NotZero,
343    NotCarry,
344    ParityEven,
345    ParityOdd,
346    Positive,
347    Negative,
348}
349
350impl lexer::FlagName for FlagName {
351    fn parse<S: AsRef<str>>(s: S) -> Option<Self> {
352        match s.as_ref() {
353            "z" | "Z" => Some(Self::Zero),
354            "nz" | "NZ" => Some(Self::NotZero),
355            "nc" | "NC" => Some(Self::NotCarry),
356            "pe" | "PE" => Some(Self::ParityEven),
357            "po" | "PO" => Some(Self::ParityOdd),
358            "p" | "P" => Some(Self::Positive),
359            "m" | "M" => Some(Self::Negative),
360            _ => None,
361        }
362    }
363}
364
365impl Display for FlagName {
366    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
367        write!(
368            f,
369            "{}",
370            match self {
371                Self::Zero => "zero flag",
372                Self::NotZero => "not zero flag",
373                Self::NotCarry => "not carry flag",
374                Self::ParityEven => "parity even flag",
375                Self::ParityOdd => "parity odd flag",
376                Self::Positive => "positive flag",
377                Self::Negative => "negative/minus flag",
378            }
379        )
380    }
381}
382
383pub struct Z80;
384
385#[derive(Copy, Clone)]
386pub struct Z80Tokens;
387
388impl ArchTokens for Z80Tokens {
389    type RegisterName = RegisterName;
390    type FlagName = FlagName;
391    type OperationName = OperationName;
392}
393
394impl<S, R> ArchAssembler<S, R, Z80Tokens> for Z80
395where
396    S: FileSystem<Reader = R>,
397    R: Read,
398{
399    fn parse(
400        asm: &mut Assembler<S, R, Z80Tokens, Self>,
401        name: OperationName,
402    ) -> Result<(), (SourceLoc, AssemblerError)> {
403        match name {
404            OperationName::Adc => {
405                asm.next()?;
406                match asm.next()? {
407                    None => return asm.end_of_input_err(),
408                    Some(Token::Register {
409                        name: RegisterName::A,
410                        ..
411                    }) => {
412                        asm.expect_symbol(SymbolName::Comma)?;
413
414                        match asm.peek()? {
415                            None => return asm.end_of_input_err(),
416                            Some(Token::Register {
417                                name: RegisterName::A,
418                                ..
419                            }) => {
420                                asm.next()?;
421                                asm.data.push(0x8F);
422                            }
423
424                            Some(Token::Register {
425                                name: RegisterName::B,
426                                ..
427                            }) => {
428                                asm.next()?;
429                                asm.data.push(0x88);
430                            }
431
432                            Some(Token::Register {
433                                name: RegisterName::C,
434                                ..
435                            }) => {
436                                asm.next()?;
437                                asm.data.push(0x89);
438                            }
439
440                            Some(Token::Register {
441                                name: RegisterName::D,
442                                ..
443                            }) => {
444                                asm.next()?;
445                                asm.data.push(0x8A);
446                            }
447
448                            Some(Token::Register {
449                                name: RegisterName::E,
450                                ..
451                            }) => {
452                                asm.next()?;
453                                asm.data.push(0x8B);
454                            }
455
456                            Some(Token::Register {
457                                name: RegisterName::H,
458                                ..
459                            }) => {
460                                asm.next()?;
461                                asm.data.push(0x8C);
462                            }
463
464                            Some(Token::Register {
465                                name: RegisterName::L,
466                                ..
467                            }) => {
468                                asm.next()?;
469                                asm.data.push(0x8D);
470                            }
471
472                            Some(Token::Register {
473                                name: RegisterName::IXH,
474                                ..
475                            }) => {
476                                asm.next()?;
477                                asm.data.push(0xDD);
478                                asm.data.push(0x8C);
479                            }
480
481                            Some(Token::Register {
482                                name: RegisterName::IXL,
483                                ..
484                            }) => {
485                                asm.next()?;
486                                asm.data.push(0xDD);
487                                asm.data.push(0x8D);
488                            }
489
490                            Some(Token::Register {
491                                name: RegisterName::IYH,
492                                ..
493                            }) => {
494                                asm.next()?;
495                                asm.data.push(0xFD);
496                                asm.data.push(0x8C);
497                            }
498
499                            Some(Token::Register {
500                                name: RegisterName::IYL,
501                                ..
502                            }) => {
503                                asm.next()?;
504                                asm.data.push(0xFD);
505                                asm.data.push(0x8D);
506                            }
507
508                            Some(Token::Symbol {
509                                name: SymbolName::ParenOpen,
510                                ..
511                            }) => {
512                                asm.next()?;
513                                match asm.next()? {
514                                    None => return asm.end_of_input_err(),
515
516                                    Some(Token::Register {
517                                        name: RegisterName::HL,
518                                        ..
519                                    }) => {
520                                        asm.expect_symbol(SymbolName::ParenClose)?;
521                                        asm.data.push(0x8E);
522                                    }
523
524                                    Some(Token::Register {
525                                        name: RegisterName::IX,
526                                        ..
527                                    }) => {
528                                        asm.expect_symbol(SymbolName::Plus)?;
529                                        asm.data.push(0xDD);
530                                        asm.data.push(0x8E);
531                                        let (loc, expr) = asm.expr()?;
532                                        if let Some(value) =
533                                            expr.evaluate(&asm.symtab, &asm.str_interner)
534                                        {
535                                            if (value as u32) > (u8::MAX as u32) {
536                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
537                                            }
538                                            asm.data.push(value as u8);
539                                        } else {
540                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
541                                            asm.data.push(0);
542                                        }
543                                        asm.expect_symbol(SymbolName::ParenClose)?;
544                                    }
545
546                                    Some(Token::Register {
547                                        name: RegisterName::IY,
548                                        ..
549                                    }) => {
550                                        asm.expect_symbol(SymbolName::Plus)?;
551                                        asm.data.push(0xFD);
552                                        asm.data.push(0x8E);
553                                        let (loc, expr) = asm.expr()?;
554                                        if let Some(value) =
555                                            expr.evaluate(&asm.symtab, &asm.str_interner)
556                                        {
557                                            if (value as u32) > (u8::MAX as u32) {
558                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
559                                            }
560                                            asm.data.push(value as u8);
561                                        } else {
562                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
563                                            asm.data.push(0);
564                                        }
565                                        asm.expect_symbol(SymbolName::ParenClose)?;
566                                    }
567
568                                    Some(_) => {
569                                        asm.data.push(0xCE);
570                                        let (loc, expr) = asm.expr()?;
571                                        if let Some(value) =
572                                            expr.evaluate(&asm.symtab, &asm.str_interner)
573                                        {
574                                            if (value as u32) > (u8::MAX as u32) {
575                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
576                                            }
577                                            asm.data.push(value as u8);
578                                        } else {
579                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
580                                            asm.data.push(0);
581                                        }
582                                        asm.expect_symbol(SymbolName::ParenClose)?;
583                                    }
584                                }
585                            }
586
587                            Some(_) => {
588                                asm.data.push(0xCE);
589                                let (loc, expr) = asm.expr()?;
590                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
591                                    if (value as u32) > (u8::MAX as u32) {
592                                        return asm_err!(
593                                            loc,
594                                            "Expression result ({value}) will not fit in a byte"
595                                        );
596                                    }
597                                    asm.data.push(value as u8);
598                                } else {
599                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
600                                    asm.data.push(0);
601                                }
602                            }
603                        }
604                    }
605
606                    Some(Token::Register {
607                        name: RegisterName::HL,
608                        ..
609                    }) => {
610                        asm.expect_symbol(SymbolName::Comma)?;
611                        match asm.next()? {
612                            None => return asm.end_of_input_err(),
613                            Some(Token::Register {
614                                name: RegisterName::BC,
615                                ..
616                            }) => {
617                                asm.data.push(0xED);
618                                asm.data.push(0x4A);
619                            }
620
621                            Some(Token::Register {
622                                name: RegisterName::DE,
623                                ..
624                            }) => {
625                                asm.data.push(0xED);
626                                asm.data.push(0x5A);
627                            }
628
629                            Some(Token::Register {
630                                name: RegisterName::HL,
631                                ..
632                            }) => {
633                                asm.data.push(0xED);
634                                asm.data.push(0x6A);
635                            }
636
637                            Some(Token::Register {
638                                name: RegisterName::SP,
639                                ..
640                            }) => {
641                                asm.data.push(0xED);
642                                asm.data.push(0x7A);
643                            }
644
645                            Some(tok) => {
646                                return asm_err!(
647                                tok.loc(),
648                                "Unexpected {}, expected register \"bc\", \"de\", \"hl\" or \"sp\"",
649                                tok.as_display(&asm.str_interner)
650                            )
651                            }
652                        }
653                    }
654
655                    Some(tok) => {
656                        return asm_err!(
657                            tok.loc(),
658                            "Unexpected {}, expected register \"a\" or \"hl\"",
659                            tok.as_display(&asm.str_interner)
660                        )
661                    }
662                }
663            }
664
665            OperationName::Add => {
666                asm.next()?;
667                match asm.next()? {
668                    None => return asm.end_of_input_err(),
669                    Some(Token::Register {
670                        name: RegisterName::A,
671                        ..
672                    }) => {
673                        asm.expect_symbol(SymbolName::Comma)?;
674
675                        match asm.peek()? {
676                            None => return asm.end_of_input_err(),
677                            Some(Token::Register {
678                                name: RegisterName::A,
679                                ..
680                            }) => {
681                                asm.next()?;
682                                asm.data.push(0x87);
683                            }
684
685                            Some(Token::Register {
686                                name: RegisterName::B,
687                                ..
688                            }) => {
689                                asm.next()?;
690                                asm.data.push(0x80);
691                            }
692
693                            Some(Token::Register {
694                                name: RegisterName::C,
695                                ..
696                            }) => {
697                                asm.next()?;
698                                asm.data.push(0x81);
699                            }
700
701                            Some(Token::Register {
702                                name: RegisterName::D,
703                                ..
704                            }) => {
705                                asm.next()?;
706                                asm.data.push(0x82);
707                            }
708
709                            Some(Token::Register {
710                                name: RegisterName::E,
711                                ..
712                            }) => {
713                                asm.next()?;
714                                asm.data.push(0x83);
715                            }
716
717                            Some(Token::Register {
718                                name: RegisterName::H,
719                                ..
720                            }) => {
721                                asm.next()?;
722                                asm.data.push(0x84);
723                            }
724
725                            Some(Token::Register {
726                                name: RegisterName::L,
727                                ..
728                            }) => {
729                                asm.next()?;
730                                asm.data.push(0x85);
731                            }
732
733                            Some(Token::Register {
734                                name: RegisterName::IXH,
735                                ..
736                            }) => {
737                                asm.next()?;
738                                asm.data.push(0xDD);
739                                asm.data.push(0x84);
740                            }
741
742                            Some(Token::Register {
743                                name: RegisterName::IXL,
744                                ..
745                            }) => {
746                                asm.next()?;
747                                asm.data.push(0xDD);
748                                asm.data.push(0x85);
749                            }
750
751                            Some(Token::Register {
752                                name: RegisterName::IYH,
753                                ..
754                            }) => {
755                                asm.next()?;
756                                asm.data.push(0xFD);
757                                asm.data.push(0x84);
758                            }
759
760                            Some(Token::Register {
761                                name: RegisterName::IYL,
762                                ..
763                            }) => {
764                                asm.next()?;
765                                asm.data.push(0xFD);
766                                asm.data.push(0x85);
767                            }
768
769                            Some(Token::Symbol {
770                                name: SymbolName::ParenOpen,
771                                ..
772                            }) => {
773                                asm.next()?;
774                                match asm.next()? {
775                                    None => return asm.end_of_input_err(),
776                                    Some(Token::Register {
777                                        name: RegisterName::HL,
778                                        ..
779                                    }) => {
780                                        asm.data.push(0x86);
781                                        asm.expect_symbol(SymbolName::ParenClose)?;
782                                    }
783
784                                    Some(Token::Register {
785                                        name: RegisterName::IX,
786                                        ..
787                                    }) => {
788                                        asm.expect_symbol(SymbolName::Plus)?;
789                                        asm.data.push(0xDD);
790                                        asm.data.push(0x86);
791                                        let (loc, expr) = asm.expr()?;
792                                        if let Some(value) =
793                                            expr.evaluate(&asm.symtab, &asm.str_interner)
794                                        {
795                                            if (value as u32) > (u8::MAX as u32) {
796                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
797                                            }
798                                            asm.data.push(value as u8);
799                                        } else {
800                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
801                                            asm.data.push(0);
802                                        }
803                                        asm.expect_symbol(SymbolName::ParenClose)?;
804                                    }
805
806                                    Some(Token::Register {
807                                        name: RegisterName::IY,
808                                        ..
809                                    }) => {
810                                        asm.expect_symbol(SymbolName::Plus)?;
811                                        asm.data.push(0xFD);
812                                        asm.data.push(0x86);
813                                        let (loc, expr) = asm.expr()?;
814                                        if let Some(value) =
815                                            expr.evaluate(&asm.symtab, &asm.str_interner)
816                                        {
817                                            if (value as u32) > (u8::MAX as u32) {
818                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
819                                            }
820                                            asm.data.push(value as u8);
821                                        } else {
822                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
823                                            asm.data.push(0);
824                                        }
825                                        asm.expect_symbol(SymbolName::ParenClose)?;
826                                    }
827
828                                    Some(_) => {
829                                        asm.data.push(0xC6);
830                                        let (loc, expr) = asm.expr()?;
831                                        if let Some(value) =
832                                            expr.evaluate(&asm.symtab, &asm.str_interner)
833                                        {
834                                            if (value as u32) > (u8::MAX as u32) {
835                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
836                                            }
837                                            asm.data.push(value as u8);
838                                        } else {
839                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
840                                            asm.data.push(0);
841                                        }
842                                        asm.expect_symbol(SymbolName::ParenClose)?;
843                                    }
844                                }
845                            }
846
847                            Some(_) => {
848                                asm.data.push(0xC6);
849                                let (loc, expr) = asm.expr()?;
850                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
851                                    if (value as u32) > (u8::MAX as u32) {
852                                        return asm_err!(
853                                            loc,
854                                            "Expression result ({value}) will not fit in a byte"
855                                        );
856                                    }
857                                    asm.data.push(value as u8);
858                                } else {
859                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
860                                    asm.data.push(0);
861                                }
862                            }
863                        }
864                    }
865
866                    Some(Token::Register {
867                        name: RegisterName::HL,
868                        ..
869                    }) => {
870                        asm.expect_symbol(SymbolName::Comma)?;
871                        match asm.next()? {
872                            None => return asm.end_of_input_err(),
873                            Some(Token::Register {
874                                name: RegisterName::BC,
875                                ..
876                            }) => {
877                                asm.data.push(0x09);
878                            }
879
880                            Some(Token::Register {
881                                name: RegisterName::DE,
882                                ..
883                            }) => {
884                                asm.data.push(0x19);
885                            }
886
887                            Some(Token::Register {
888                                name: RegisterName::HL,
889                                ..
890                            }) => {
891                                asm.data.push(0x29);
892                            }
893
894                            Some(Token::Register {
895                                name: RegisterName::SP,
896                                ..
897                            }) => {
898                                asm.data.push(0x39);
899                            }
900
901                            Some(tok) => {
902                                return asm_err!(
903                                tok.loc(),
904                                "Unexpected {}, expected register \"bc\", \"de\", \"hl\" or \"sp\"",
905                                tok.as_display(&asm.str_interner)
906                            )
907                            }
908                        }
909                    }
910
911                    Some(Token::Register {
912                        name: RegisterName::IX,
913                        ..
914                    }) => {
915                        asm.expect_symbol(SymbolName::Comma)?;
916                        match asm.next()? {
917                            None => return asm.end_of_input_err(),
918                            Some(Token::Register {
919                                name: RegisterName::BC,
920                                ..
921                            }) => {
922                                asm.data.push(0xDD);
923                                asm.data.push(0x09);
924                            }
925
926                            Some(Token::Register {
927                                name: RegisterName::DE,
928                                ..
929                            }) => {
930                                asm.data.push(0xDD);
931                                asm.data.push(0x19);
932                            }
933
934                            Some(Token::Register {
935                                name: RegisterName::IX,
936                                ..
937                            }) => {
938                                asm.data.push(0xDD);
939                                asm.data.push(0x29);
940                            }
941
942                            Some(Token::Register {
943                                name: RegisterName::SP,
944                                ..
945                            }) => {
946                                asm.data.push(0xDD);
947                                asm.data.push(0x39);
948                            }
949
950                            Some(tok) => {
951                                return asm_err!(
952                                tok.loc(),
953                                "Unexpected {}, expected register \"bc\", \"de\", \"ix\" or \"sp\"",
954                                tok.as_display(&asm.str_interner)
955                            )
956                            }
957                        }
958                    }
959
960                    Some(Token::Register {
961                        name: RegisterName::IY,
962                        ..
963                    }) => {
964                        asm.expect_symbol(SymbolName::Comma)?;
965                        match asm.next()? {
966                            None => return asm.end_of_input_err(),
967                            Some(Token::Register {
968                                name: RegisterName::BC,
969                                ..
970                            }) => {
971                                asm.data.push(0xFD);
972                                asm.data.push(0x09);
973                            }
974
975                            Some(Token::Register {
976                                name: RegisterName::DE,
977                                ..
978                            }) => {
979                                asm.data.push(0xFD);
980                                asm.data.push(0x19);
981                            }
982
983                            Some(Token::Register {
984                                name: RegisterName::IY,
985                                ..
986                            }) => {
987                                asm.data.push(0xFD);
988                                asm.data.push(0x29);
989                            }
990
991                            Some(Token::Register {
992                                name: RegisterName::SP,
993                                ..
994                            }) => {
995                                asm.data.push(0xFD);
996                                asm.data.push(0x39);
997                            }
998
999                            Some(tok) => {
1000                                return asm_err!(
1001                                tok.loc(),
1002                                "Unexpected {}, expected register \"bc\", \"de\", \"iy\" or \"sp\"",
1003                                tok.as_display(&asm.str_interner)
1004                            )
1005                            }
1006                        }
1007                    }
1008
1009                    Some(tok) => {
1010                        return asm_err!(
1011                            tok.loc(),
1012                            "Unexpected {}, expected register \"a\" or \"hl\"",
1013                            tok.as_display(&asm.str_interner)
1014                        )
1015                    }
1016                }
1017            }
1018
1019            OperationName::And => {
1020                asm.next()?;
1021                match asm.peek()? {
1022                    None => return asm.end_of_input_err(),
1023                    Some(Token::Register {
1024                        name: RegisterName::A,
1025                        ..
1026                    }) => {
1027                        asm.next()?;
1028                        asm.data.push(0xA7);
1029                    }
1030
1031                    Some(Token::Register {
1032                        name: RegisterName::B,
1033                        ..
1034                    }) => {
1035                        asm.next()?;
1036                        asm.data.push(0xA0);
1037                    }
1038
1039                    Some(Token::Register {
1040                        name: RegisterName::C,
1041                        ..
1042                    }) => {
1043                        asm.next()?;
1044                        asm.data.push(0xA1);
1045                    }
1046
1047                    Some(Token::Register {
1048                        name: RegisterName::D,
1049                        ..
1050                    }) => {
1051                        asm.next()?;
1052                        asm.data.push(0xA2);
1053                    }
1054
1055                    Some(Token::Register {
1056                        name: RegisterName::E,
1057                        ..
1058                    }) => {
1059                        asm.next()?;
1060                        asm.data.push(0xA3);
1061                    }
1062
1063                    Some(Token::Register {
1064                        name: RegisterName::H,
1065                        ..
1066                    }) => {
1067                        asm.next()?;
1068                        asm.data.push(0xA4);
1069                    }
1070
1071                    Some(Token::Register {
1072                        name: RegisterName::L,
1073                        ..
1074                    }) => {
1075                        asm.next()?;
1076                        asm.data.push(0xA5);
1077                    }
1078
1079                    Some(Token::Register {
1080                        name: RegisterName::IXH,
1081                        ..
1082                    }) => {
1083                        asm.next()?;
1084                        asm.data.push(0xDD);
1085                        asm.data.push(0xA4);
1086                    }
1087
1088                    Some(Token::Register {
1089                        name: RegisterName::IXL,
1090                        ..
1091                    }) => {
1092                        asm.next()?;
1093                        asm.data.push(0xDD);
1094                        asm.data.push(0xA5);
1095                    }
1096
1097                    Some(Token::Register {
1098                        name: RegisterName::IYH,
1099                        ..
1100                    }) => {
1101                        asm.next()?;
1102                        asm.data.push(0xFD);
1103                        asm.data.push(0xA4);
1104                    }
1105
1106                    Some(Token::Register {
1107                        name: RegisterName::IYL,
1108                        ..
1109                    }) => {
1110                        asm.next()?;
1111                        asm.data.push(0xFD);
1112                        asm.data.push(0xA5);
1113                    }
1114
1115                    Some(Token::Symbol {
1116                        name: SymbolName::ParenOpen,
1117                        ..
1118                    }) => {
1119                        asm.next()?;
1120                        match asm.next()? {
1121                            None => return asm.end_of_input_err(),
1122                            Some(Token::Register {
1123                                name: RegisterName::HL,
1124                                ..
1125                            }) => {
1126                                asm.data.push(0xA6);
1127                                asm.expect_symbol(SymbolName::ParenClose)?;
1128                            }
1129
1130                            Some(Token::Register {
1131                                name: RegisterName::IX,
1132                                ..
1133                            }) => {
1134                                asm.expect_symbol(SymbolName::Plus)?;
1135                                asm.data.push(0xDD);
1136                                asm.data.push(0xA6);
1137                                let (loc, expr) = asm.expr()?;
1138                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1139                                    if (value as u32) > (u8::MAX as u32) {
1140                                        return asm_err!(
1141                                            loc,
1142                                            "Expression result ({value}) will not fit in a byte"
1143                                        );
1144                                    }
1145                                    asm.data.push(value as u8);
1146                                } else {
1147                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
1148                                    asm.data.push(0);
1149                                }
1150                                asm.expect_symbol(SymbolName::ParenClose)?;
1151                            }
1152
1153                            Some(Token::Register {
1154                                name: RegisterName::IY,
1155                                ..
1156                            }) => {
1157                                asm.expect_symbol(SymbolName::Plus)?;
1158                                asm.data.push(0xFD);
1159                                asm.data.push(0xA6);
1160                                let (loc, expr) = asm.expr()?;
1161                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1162                                    if (value as u32) > (u8::MAX as u32) {
1163                                        return asm_err!(
1164                                            loc,
1165                                            "Expression result ({value}) will not fit in a byte"
1166                                        );
1167                                    }
1168                                    asm.data.push(value as u8);
1169                                } else {
1170                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
1171                                    asm.data.push(0);
1172                                }
1173                                asm.expect_symbol(SymbolName::ParenClose)?;
1174                            }
1175
1176                            Some(tok) => {
1177                                return asm_err!(
1178                                    tok.loc(),
1179                                    "Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",
1180                                    tok.as_display(&asm.str_interner)
1181                                )
1182                            }
1183                        }
1184                    }
1185
1186                    Some(_) => {
1187                        asm.data.push(0xE6);
1188                        let (loc, expr) = asm.expr()?;
1189                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1190                            if (value as u32) > (u8::MAX as u32) {
1191                                return asm_err!(
1192                                    loc,
1193                                    "Expression result ({value}) will not fit in a byte"
1194                                );
1195                            }
1196                            asm.data.push(value as u8);
1197                        } else {
1198                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
1199                            asm.data.push(0);
1200                        }
1201                    }
1202                }
1203            }
1204
1205            OperationName::Bit => {
1206                asm.next()?;
1207                match asm.const_expr()? {
1208                    (loc, None) => return asm_err!(loc, "Bit index must be immediately solvable"),
1209                    (loc, Some(value)) => {
1210                        if !(0..=7).contains(&value) {
1211                            return asm_err!(loc, "Bit index ({value}) must be between 0 and 7");
1212                        }
1213
1214                        asm.expect_symbol(SymbolName::Comma)?;
1215
1216                        match asm.next()? {
1217                            Some(Token::Register {
1218                                name: RegisterName::A,
1219                                ..
1220                            }) => {
1221                                asm.data.push(0xCB);
1222                                asm.data.push(match value {
1223                                    0 => 0x47,
1224                                    1 => 0x4F,
1225                                    2 => 0x57,
1226                                    3 => 0x5F,
1227                                    4 => 0x67,
1228                                    5 => 0x6F,
1229                                    6 => 0x77,
1230                                    7 => 0x7F,
1231                                    _ => unreachable!(),
1232                                });
1233                            }
1234
1235                            Some(Token::Register {
1236                                name: RegisterName::B,
1237                                ..
1238                            }) => {
1239                                asm.data.push(0xCB);
1240                                asm.data.push(match value {
1241                                    0 => 0x40,
1242                                    1 => 0x48,
1243                                    2 => 0x50,
1244                                    3 => 0x58,
1245                                    4 => 0x60,
1246                                    5 => 0x68,
1247                                    6 => 0x70,
1248                                    7 => 0x78,
1249                                    _ => unreachable!(),
1250                                });
1251                            }
1252
1253                            Some(Token::Register {
1254                                name: RegisterName::C,
1255                                ..
1256                            }) => {
1257                                asm.data.push(0xCB);
1258                                asm.data.push(match value {
1259                                    0 => 0x41,
1260                                    1 => 0x49,
1261                                    2 => 0x51,
1262                                    3 => 0x59,
1263                                    4 => 0x61,
1264                                    5 => 0x69,
1265                                    6 => 0x71,
1266                                    7 => 0x79,
1267                                    _ => unreachable!(),
1268                                });
1269                            }
1270
1271                            Some(Token::Register {
1272                                name: RegisterName::D,
1273                                ..
1274                            }) => {
1275                                asm.data.push(0xCB);
1276                                asm.data.push(match value {
1277                                    0 => 0x42,
1278                                    1 => 0x4A,
1279                                    2 => 0x52,
1280                                    3 => 0x5A,
1281                                    4 => 0x62,
1282                                    5 => 0x6A,
1283                                    6 => 0x72,
1284                                    7 => 0x7A,
1285                                    _ => unreachable!(),
1286                                });
1287                            }
1288
1289                            Some(Token::Register {
1290                                name: RegisterName::E,
1291                                ..
1292                            }) => {
1293                                asm.data.push(0xCB);
1294                                asm.data.push(match value {
1295                                    0 => 0x43,
1296                                    1 => 0x4B,
1297                                    2 => 0x53,
1298                                    3 => 0x5B,
1299                                    4 => 0x63,
1300                                    5 => 0x6B,
1301                                    6 => 0x73,
1302                                    7 => 0x7B,
1303                                    _ => unreachable!(),
1304                                });
1305                            }
1306
1307                            Some(Token::Register {
1308                                name: RegisterName::H,
1309                                ..
1310                            }) => {
1311                                asm.data.push(0xCB);
1312                                asm.data.push(match value {
1313                                    0 => 0x44,
1314                                    1 => 0x4C,
1315                                    2 => 0x54,
1316                                    3 => 0x5C,
1317                                    4 => 0x64,
1318                                    5 => 0x6C,
1319                                    6 => 0x74,
1320                                    7 => 0x7C,
1321                                    _ => unreachable!(),
1322                                });
1323                            }
1324
1325                            Some(Token::Register {
1326                                name: RegisterName::L,
1327                                ..
1328                            }) => {
1329                                asm.data.push(0xCB);
1330                                asm.data.push(match value {
1331                                    0 => 0x45,
1332                                    1 => 0x4D,
1333                                    2 => 0x55,
1334                                    3 => 0x5D,
1335                                    4 => 0x65,
1336                                    5 => 0x6D,
1337                                    6 => 0x75,
1338                                    7 => 0x7D,
1339                                    _ => unreachable!(),
1340                                });
1341                            }
1342
1343                            Some(Token::Symbol {
1344                                name: SymbolName::ParenOpen,
1345                                ..
1346                            }) => {
1347                                match asm.next()? {
1348                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
1349                                        asm.data.push(0xCB);
1350                                        asm.data.push(match value {
1351                                            0 => 0x46,
1352                                            1 => 0x4E,
1353                                            2 => 0x56,
1354                                            3 => 0x5E,
1355                                            4 => 0x66,
1356                                            5 => 0x6E,
1357                                            6 => 0x76,
1358                                            7 => 0x7E,
1359                                            _ => unreachable!(),
1360                                        });
1361                                    }
1362
1363                                    Some(Token::Register { name: RegisterName::IX, .. }) => {
1364                                        asm.expect_symbol(SymbolName::Plus)?;
1365                                        asm.data.push(0xDD);
1366                                        asm.data.push(0xCB);
1367                                        let (loc, expr) = asm.expr()?;
1368                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1369                                            if (value as u32) > (u8::MAX as u32) {
1370                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
1371                                            }
1372                                            asm.data.push(value as u8);
1373                                        } else {
1374                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
1375                                            asm.data.push(0);
1376                                        }
1377                                        asm.data.push(match value {
1378                                            0 => 0x46,
1379                                            1 => 0x4E,
1380                                            2 => 0x56,
1381                                            3 => 0x5E,
1382                                            4 => 0x66,
1383                                            5 => 0x6E,
1384                                            6 => 0x76,
1385                                            7 => 0x7E,
1386                                            _ => unreachable!(),
1387                                        });
1388                                    }
1389
1390                                    Some(Token::Register { name: RegisterName::IY, .. }) => {
1391                                        asm.expect_symbol(SymbolName::Plus)?;
1392                                        asm.data.push(0xFD);
1393                                        asm.data.push(0xCB);
1394                                        let (loc, expr) = asm.expr()?;
1395                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1396                                            if (value as u32) > (u8::MAX as u32) {
1397                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
1398                                            }
1399                                            asm.data.push(value as u8);
1400                                        } else {
1401                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
1402                                            asm.data.push(0);
1403                                        }
1404                                        asm.data.push(match value {
1405                                            0 => 0x46,
1406                                            1 => 0x4E,
1407                                            2 => 0x56,
1408                                            3 => 0x5E,
1409                                            4 => 0x66,
1410                                            5 => 0x6E,
1411                                            6 => 0x76,
1412                                            7 => 0x7E,
1413                                            _ => unreachable!(),
1414                                        });
1415                                    }
1416
1417                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
1418                                    None => return asm.end_of_input_err(),
1419                                }
1420                                asm.expect_symbol(SymbolName::ParenClose)?;
1421                            }
1422
1423                            Some(tok) => {
1424                                return asm_err!(
1425                                    tok.loc(),
1426                                    "Unexpected {}, expected a register",
1427                                    tok.as_display(&asm.str_interner)
1428                                )
1429                            }
1430                            None => return asm.end_of_input_err(),
1431                        }
1432                    }
1433                }
1434            }
1435
1436            OperationName::Call => {
1437                asm.next()?;
1438                match asm.peek()? {
1439                    Some(Token::Flag {
1440                        name: FlagName::Zero,
1441                        ..
1442                    }) => {
1443                        asm.next()?;
1444                        asm.data.push(0xCC);
1445                        asm.expect_symbol(SymbolName::Comma)?;
1446                    }
1447                    Some(Token::Flag {
1448                        name: FlagName::NotZero,
1449                        ..
1450                    }) => {
1451                        asm.next()?;
1452                        asm.data.push(0xC4);
1453                        asm.expect_symbol(SymbolName::Comma)?;
1454                    }
1455                    Some(Token::Register {
1456                        name: RegisterName::C,
1457                        ..
1458                    }) => {
1459                        asm.next()?;
1460                        asm.data.push(0xDC);
1461                        asm.expect_symbol(SymbolName::Comma)?;
1462                    }
1463                    Some(Token::Flag {
1464                        name: FlagName::NotCarry,
1465                        ..
1466                    }) => {
1467                        asm.next()?;
1468                        asm.data.push(0xD4);
1469                        asm.expect_symbol(SymbolName::Comma)?;
1470                    }
1471                    Some(Token::Flag {
1472                        name: FlagName::ParityEven,
1473                        ..
1474                    }) => {
1475                        asm.next()?;
1476                        asm.data.push(0xEC);
1477                        asm.expect_symbol(SymbolName::Comma)?;
1478                    }
1479                    Some(Token::Flag {
1480                        name: FlagName::ParityOdd,
1481                        ..
1482                    }) => {
1483                        asm.next()?;
1484                        asm.data.push(0xE4);
1485                        asm.expect_symbol(SymbolName::Comma)?;
1486                    }
1487                    Some(Token::Flag {
1488                        name: FlagName::Positive,
1489                        ..
1490                    }) => {
1491                        asm.next()?;
1492                        asm.data.push(0xF4);
1493                        asm.expect_symbol(SymbolName::Comma)?;
1494                    }
1495                    Some(Token::Flag {
1496                        name: FlagName::Negative,
1497                        ..
1498                    }) => {
1499                        asm.next()?;
1500                        asm.data.push(0xFC);
1501                        asm.expect_symbol(SymbolName::Comma)?;
1502                    }
1503                    Some(_) => {
1504                        asm.data.push(0xCD);
1505                    }
1506                    None => return asm.end_of_input_err(),
1507                }
1508                let (loc, expr) = asm.expr()?;
1509                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1510                    if (value as u32) > (u16::MAX as u32) {
1511                        return asm_err!(loc, "Expression result ({value}) will not fit in a word");
1512                    }
1513                    asm.data.extend_from_slice(&(value as u16).to_le_bytes());
1514                } else {
1515                    asm.links.push(Link::word(loc, asm.data.len(), expr));
1516                    asm.data.push(0);
1517                    asm.data.push(0);
1518                }
1519            }
1520
1521            OperationName::Ccf => {
1522                asm.next()?;
1523                asm.data.push(0x3F);
1524            }
1525
1526            OperationName::Cp => {
1527                asm.next()?;
1528                match asm.peek()? {
1529                    None => return asm.end_of_input_err(),
1530                    Some(Token::Register {
1531                        name: RegisterName::A,
1532                        ..
1533                    }) => {
1534                        asm.next()?;
1535                        asm.data.push(0xBF);
1536                    }
1537
1538                    Some(Token::Register {
1539                        name: RegisterName::B,
1540                        ..
1541                    }) => {
1542                        asm.next()?;
1543                        asm.data.push(0xB8);
1544                    }
1545
1546                    Some(Token::Register {
1547                        name: RegisterName::C,
1548                        ..
1549                    }) => {
1550                        asm.next()?;
1551                        asm.data.push(0xB9);
1552                    }
1553
1554                    Some(Token::Register {
1555                        name: RegisterName::D,
1556                        ..
1557                    }) => {
1558                        asm.next()?;
1559                        asm.data.push(0xBA);
1560                    }
1561
1562                    Some(Token::Register {
1563                        name: RegisterName::E,
1564                        ..
1565                    }) => {
1566                        asm.next()?;
1567                        asm.data.push(0xBB);
1568                    }
1569
1570                    Some(Token::Register {
1571                        name: RegisterName::H,
1572                        ..
1573                    }) => {
1574                        asm.next()?;
1575                        asm.data.push(0xBC);
1576                    }
1577
1578                    Some(Token::Register {
1579                        name: RegisterName::L,
1580                        ..
1581                    }) => {
1582                        asm.next()?;
1583                        asm.data.push(0xBD);
1584                    }
1585
1586                    Some(Token::Register {
1587                        name: RegisterName::IXH,
1588                        ..
1589                    }) => {
1590                        asm.next()?;
1591                        asm.data.push(0xDD);
1592                        asm.data.push(0xBC);
1593                    }
1594
1595                    Some(Token::Register {
1596                        name: RegisterName::IXL,
1597                        ..
1598                    }) => {
1599                        asm.next()?;
1600                        asm.data.push(0xDD);
1601                        asm.data.push(0xBD);
1602                    }
1603
1604                    Some(Token::Register {
1605                        name: RegisterName::IYH,
1606                        ..
1607                    }) => {
1608                        asm.next()?;
1609                        asm.data.push(0xFD);
1610                        asm.data.push(0xBC);
1611                    }
1612
1613                    Some(Token::Register {
1614                        name: RegisterName::IYL,
1615                        ..
1616                    }) => {
1617                        asm.next()?;
1618                        asm.data.push(0xFD);
1619                        asm.data.push(0xBD);
1620                    }
1621
1622                    Some(Token::Symbol {
1623                        name: SymbolName::ParenOpen,
1624                        ..
1625                    }) => {
1626                        asm.next()?;
1627                        match asm.next()? {
1628                            None => return asm.end_of_input_err(),
1629                            Some(Token::Register {
1630                                name: RegisterName::HL,
1631                                ..
1632                            }) => {
1633                                asm.data.push(0xBE);
1634                                asm.expect_symbol(SymbolName::ParenClose)?;
1635                            }
1636
1637                            Some(Token::Register {
1638                                name: RegisterName::IX,
1639                                ..
1640                            }) => {
1641                                asm.expect_symbol(SymbolName::Plus)?;
1642                                asm.data.push(0xDD);
1643                                asm.data.push(0xBE);
1644                                let (loc, expr) = asm.expr()?;
1645                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1646                                    if (value as u32) > (u8::MAX as u32) {
1647                                        return asm_err!(
1648                                            loc,
1649                                            "Expression result ({value}) will not fit in a byte"
1650                                        );
1651                                    }
1652                                    asm.data.push(value as u8);
1653                                } else {
1654                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
1655                                    asm.data.push(0);
1656                                }
1657                                asm.expect_symbol(SymbolName::ParenClose)?;
1658                            }
1659
1660                            Some(Token::Register {
1661                                name: RegisterName::IY,
1662                                ..
1663                            }) => {
1664                                asm.expect_symbol(SymbolName::Plus)?;
1665                                asm.data.push(0xFD);
1666                                asm.data.push(0xBE);
1667                                let (loc, expr) = asm.expr()?;
1668                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1669                                    if (value as u32) > (u8::MAX as u32) {
1670                                        return asm_err!(
1671                                            loc,
1672                                            "Expression result ({value}) will not fit in a byte"
1673                                        );
1674                                    }
1675                                    asm.data.push(value as u8);
1676                                } else {
1677                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
1678                                    asm.data.push(0);
1679                                }
1680                                asm.expect_symbol(SymbolName::ParenClose)?;
1681                            }
1682
1683                            Some(_) => {
1684                                asm.data.push(0xFE);
1685                                let (loc, expr) = asm.expr()?;
1686                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1687                                    if (value as u32) > (u8::MAX as u32) {
1688                                        return asm_err!(
1689                                            loc,
1690                                            "Expression result ({value}) will not fit in a byte"
1691                                        );
1692                                    }
1693                                    asm.data.push(value as u8);
1694                                } else {
1695                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
1696                                    asm.data.push(0);
1697                                }
1698                                asm.expect_symbol(SymbolName::ParenClose)?;
1699                            }
1700                        }
1701                    }
1702
1703                    Some(_) => {
1704                        asm.data.push(0xFE);
1705                        let (loc, expr) = asm.expr()?;
1706                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1707                            if (value as u32) > (u8::MAX as u32) {
1708                                return asm_err!(
1709                                    loc,
1710                                    "Expression result ({value}) will not fit in a byte"
1711                                );
1712                            }
1713                            asm.data.push(value as u8);
1714                        } else {
1715                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
1716                            asm.data.push(0);
1717                        }
1718                    }
1719                }
1720            }
1721
1722            OperationName::Cpd => {
1723                asm.next()?;
1724                asm.data.push(0xED);
1725                asm.data.push(0xA9);
1726            }
1727
1728            OperationName::Cpdr => {
1729                asm.next()?;
1730                asm.data.push(0xED);
1731                asm.data.push(0xB9);
1732            }
1733
1734            OperationName::Cpi => {
1735                asm.next()?;
1736                asm.data.push(0xED);
1737                asm.data.push(0xA1);
1738            }
1739
1740            OperationName::Cpir => {
1741                asm.next()?;
1742                asm.data.push(0xED);
1743                asm.data.push(0xB1);
1744            }
1745
1746            OperationName::Cpl => {
1747                asm.next()?;
1748                asm.data.push(0x2F);
1749            }
1750
1751            OperationName::Daa => {
1752                asm.next()?;
1753                asm.data.push(0x27);
1754            }
1755
1756            OperationName::Dec => {
1757                asm.next()?;
1758                match asm.next()? {
1759                    Some(Token::Register {
1760                        name: RegisterName::A,
1761                        ..
1762                    }) => {
1763                        asm.data.push(0x3D);
1764                    }
1765
1766                    Some(Token::Register {
1767                        name: RegisterName::B,
1768                        ..
1769                    }) => {
1770                        asm.data.push(0x05);
1771                    }
1772
1773                    Some(Token::Register {
1774                        name: RegisterName::C,
1775                        ..
1776                    }) => {
1777                        asm.data.push(0x0D);
1778                    }
1779
1780                    Some(Token::Register {
1781                        name: RegisterName::D,
1782                        ..
1783                    }) => {
1784                        asm.data.push(0x15);
1785                    }
1786
1787                    Some(Token::Register {
1788                        name: RegisterName::E,
1789                        ..
1790                    }) => {
1791                        asm.data.push(0x1D);
1792                    }
1793
1794                    Some(Token::Register {
1795                        name: RegisterName::H,
1796                        ..
1797                    }) => {
1798                        asm.data.push(0x25);
1799                    }
1800
1801                    Some(Token::Register {
1802                        name: RegisterName::L,
1803                        ..
1804                    }) => {
1805                        asm.data.push(0x2D);
1806                    }
1807
1808                    Some(Token::Register {
1809                        name: RegisterName::IXH,
1810                        ..
1811                    }) => {
1812                        asm.data.push(0xDD);
1813                        asm.data.push(0x25);
1814                    }
1815
1816                    Some(Token::Register {
1817                        name: RegisterName::IXL,
1818                        ..
1819                    }) => {
1820                        asm.data.push(0xDD);
1821                        asm.data.push(0x2D);
1822                    }
1823
1824                    Some(Token::Register {
1825                        name: RegisterName::IYH,
1826                        ..
1827                    }) => {
1828                        asm.data.push(0xFD);
1829                        asm.data.push(0x25);
1830                    }
1831
1832                    Some(Token::Register {
1833                        name: RegisterName::IYL,
1834                        ..
1835                    }) => {
1836                        asm.data.push(0xFD);
1837                        asm.data.push(0x2D);
1838                    }
1839
1840                    Some(Token::Register {
1841                        name: RegisterName::BC,
1842                        ..
1843                    }) => {
1844                        asm.data.push(0x0B);
1845                    }
1846
1847                    Some(Token::Register {
1848                        name: RegisterName::DE,
1849                        ..
1850                    }) => {
1851                        asm.data.push(0x1B);
1852                    }
1853
1854                    Some(Token::Register {
1855                        name: RegisterName::HL,
1856                        ..
1857                    }) => {
1858                        asm.data.push(0x2B);
1859                    }
1860
1861                    Some(Token::Register {
1862                        name: RegisterName::SP,
1863                        ..
1864                    }) => {
1865                        asm.data.push(0x3B);
1866                    }
1867
1868                    Some(Token::Register {
1869                        name: RegisterName::IX,
1870                        ..
1871                    }) => {
1872                        asm.data.push(0xDD);
1873                        asm.data.push(0x2B);
1874                    }
1875
1876                    Some(Token::Register {
1877                        name: RegisterName::IY,
1878                        ..
1879                    }) => {
1880                        asm.data.push(0xFD);
1881                        asm.data.push(0x2B);
1882                    }
1883
1884                    Some(Token::Symbol {
1885                        name: SymbolName::ParenOpen,
1886                        ..
1887                    }) => match asm.next()? {
1888                        None => return asm.end_of_input_err(),
1889
1890                        Some(Token::Register {
1891                            name: RegisterName::HL,
1892                            ..
1893                        }) => {
1894                            asm.data.push(0x35);
1895                            asm.expect_symbol(SymbolName::ParenClose)?;
1896                        }
1897
1898                        Some(Token::Register {
1899                            name: RegisterName::IX,
1900                            ..
1901                        }) => {
1902                            asm.expect_symbol(SymbolName::Plus)?;
1903                            asm.data.push(0xDD);
1904                            asm.data.push(0x35);
1905                            let (loc, expr) = asm.expr()?;
1906                            if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1907                                if (value as u32) > (u8::MAX as u32) {
1908                                    return asm_err!(
1909                                        loc,
1910                                        "Expression result ({value}) will not fit in a byte"
1911                                    );
1912                                }
1913                                asm.data.push(value as u8);
1914                            } else {
1915                                asm.links.push(Link::byte(loc, asm.data.len(), expr));
1916                                asm.data.push(0);
1917                            }
1918                            asm.expect_symbol(SymbolName::ParenClose)?;
1919                        }
1920
1921                        Some(Token::Register {
1922                            name: RegisterName::IY,
1923                            ..
1924                        }) => {
1925                            asm.expect_symbol(SymbolName::Plus)?;
1926                            asm.data.push(0xFD);
1927                            asm.data.push(0x35);
1928                            let (loc, expr) = asm.expr()?;
1929                            if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1930                                if (value as u32) > (u8::MAX as u32) {
1931                                    return asm_err!(
1932                                        loc,
1933                                        "Expression result ({value}) will not fit in a byte"
1934                                    );
1935                                }
1936                                asm.data.push(value as u8);
1937                            } else {
1938                                asm.links.push(Link::byte(loc, asm.data.len(), expr));
1939                                asm.data.push(0);
1940                            }
1941                            asm.expect_symbol(SymbolName::ParenClose)?;
1942                        }
1943
1944                        Some(tok) => {
1945                            return asm_err!(
1946                                tok.loc(),
1947                                "Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",
1948                                tok.as_display(&asm.str_interner)
1949                            )
1950                        }
1951                    },
1952
1953                    Some(tok) => {
1954                        return asm_err!(
1955                            tok.loc(),
1956                            "Unexpected {}, expected a register",
1957                            tok.as_display(&asm.str_interner)
1958                        )
1959                    }
1960                    None => return asm.end_of_input_err(),
1961                }
1962            }
1963
1964            OperationName::Di => {
1965                asm.next()?;
1966                asm.data.push(0xF3);
1967            }
1968
1969            OperationName::Djnz => {
1970                asm.next()?;
1971                asm.data.push(0x10);
1972                let (loc, mut expr) = asm.expr()?;
1973                // Make the expression relative to @here
1974                expr.push(ExprNode::Value(asm.here.wrapping_add(2) as i32));
1975                expr.push(ExprNode::Sub);
1976                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
1977                    if (value < (i8::MIN as i32)) || (value > (i8::MAX as i32)) {
1978                        return asm_err!(loc, "Jump distance ({value}) will not fit in a byte");
1979                    }
1980                    asm.data.push(value as u8);
1981                } else {
1982                    asm.links.push(Link::signed_byte(loc, asm.data.len(), expr));
1983                    asm.data.push(0);
1984                }
1985            }
1986
1987            OperationName::Ei => {
1988                asm.next()?;
1989                asm.data.push(0xFB);
1990            }
1991
1992            OperationName::Ex => {
1993                asm.next()?;
1994                match asm.next()? {
1995                    None => return asm.end_of_input_err(),
1996
1997                    Some(Token::Register {
1998                        name: RegisterName::AF,
1999                        ..
2000                    }) => {
2001                        asm.expect_symbol(SymbolName::Comma)?;
2002                        asm.expect_register(RegisterName::AFPrime)?;
2003                        asm.data.push(0x08);
2004                    }
2005
2006                    Some(Token::Register {
2007                        name: RegisterName::DE,
2008                        ..
2009                    }) => {
2010                        asm.expect_symbol(SymbolName::Comma)?;
2011                        asm.expect_register(RegisterName::HL)?;
2012                        asm.data.push(0xEB);
2013                    }
2014
2015                    Some(Token::Symbol {
2016                        name: SymbolName::ParenOpen,
2017                        ..
2018                    }) => {
2019                        asm.expect_register(RegisterName::SP)?;
2020                        asm.expect_symbol(SymbolName::ParenClose)?;
2021                        asm.expect_symbol(SymbolName::Comma)?;
2022
2023                        match asm.next()? {
2024                            None => return asm.end_of_input_err(),
2025
2026                            Some(Token::Register {
2027                                name: RegisterName::HL,
2028                                ..
2029                            }) => {
2030                                asm.data.push(0xE3);
2031                            }
2032
2033                            Some(Token::Register {
2034                                name: RegisterName::IX,
2035                                ..
2036                            }) => {
2037                                asm.data.push(0xDD);
2038                                asm.data.push(0xE3);
2039                            }
2040
2041                            Some(Token::Register {
2042                                name: RegisterName::IY,
2043                                ..
2044                            }) => {
2045                                asm.data.push(0xFD);
2046                                asm.data.push(0xE3);
2047                            }
2048
2049                            Some(tok) => {
2050                                return asm_err!(
2051                                tok.loc(),
2052                                "Unexpected {}, expected the registers \"hl\", \"ix\", or \"iy\"",
2053                                tok.as_display(&asm.str_interner)
2054                            )
2055                            }
2056                        }
2057                    }
2058
2059                    Some(tok) => {
2060                        return asm_err!(
2061                            tok.loc(),
2062                            "Unexpected {}, expected the registers \"af\", \"de\", or \"(sp)\"",
2063                            tok.as_display(&asm.str_interner)
2064                        )
2065                    }
2066                }
2067            }
2068
2069            OperationName::Exx => {
2070                asm.next()?;
2071                asm.data.push(0xD9);
2072            }
2073
2074            OperationName::Halt => {
2075                asm.next()?;
2076                asm.data.push(0x76);
2077            }
2078
2079            OperationName::Im => {
2080                asm.next()?;
2081                asm.data.push(0xED);
2082                match asm.next()? {
2083                    None => return asm.end_of_input_err(),
2084
2085                    Some(Token::Number { value: 0, .. }) => {
2086                        asm.data.push(0x46);
2087                    }
2088
2089                    Some(Token::Number { value: 1, .. }) => {
2090                        asm.data.push(0x56);
2091                    }
2092
2093                    Some(Token::Number { value: 2, .. }) => {
2094                        asm.data.push(0x5E);
2095                    }
2096
2097                    Some(tok) => {
2098                        return asm_err!(
2099                            tok.loc(),
2100                            "Unexpected {}, expected the numbers 0, 1, or 2",
2101                            tok.as_display(&asm.str_interner)
2102                        )
2103                    }
2104                }
2105            }
2106
2107            OperationName::In => {
2108                asm.next()?;
2109                match asm.next()? {
2110                    None => return asm.end_of_input_err(),
2111
2112                    Some(Token::Register {
2113                        name: RegisterName::A,
2114                        ..
2115                    }) => {
2116                        asm.expect_symbol(SymbolName::Comma)?;
2117                        asm.expect_symbol(SymbolName::ParenOpen)?;
2118                        match asm.peek()? {
2119                            None => return asm.end_of_input_err(),
2120
2121                            Some(Token::Register {
2122                                name: RegisterName::C,
2123                                ..
2124                            }) => {
2125                                asm.next()?;
2126                                asm.expect_symbol(SymbolName::ParenClose)?;
2127                                asm.data.push(0xED);
2128                                asm.data.push(0x78);
2129                            }
2130
2131                            Some(_) => {
2132                                asm.data.push(0xDB);
2133                                let (loc, expr) = asm.expr()?;
2134                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
2135                                    if (value as u32) > (u8::MAX as u32) {
2136                                        return asm_err!(
2137                                            loc,
2138                                            "Expression result ({value}) will not fit in a byte"
2139                                        );
2140                                    }
2141                                    asm.data.push(value as u8);
2142                                } else {
2143                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
2144                                    asm.data.push(0);
2145                                }
2146                                asm.expect_symbol(SymbolName::ParenClose)?;
2147                            }
2148                        }
2149                    }
2150
2151                    Some(Token::Register {
2152                        name: RegisterName::B,
2153                        ..
2154                    }) => {
2155                        asm.data.push(0xED);
2156                        asm.data.push(0x40);
2157                        asm.expect_symbol(SymbolName::Comma)?;
2158                        asm.expect_symbol(SymbolName::ParenOpen)?;
2159                        asm.expect_register(RegisterName::C)?;
2160                        asm.expect_symbol(SymbolName::ParenClose)?;
2161                    }
2162
2163                    Some(Token::Register {
2164                        name: RegisterName::C,
2165                        ..
2166                    }) => {
2167                        asm.data.push(0xED);
2168                        asm.data.push(0x48);
2169                        asm.expect_symbol(SymbolName::Comma)?;
2170                        asm.expect_symbol(SymbolName::ParenOpen)?;
2171                        asm.expect_register(RegisterName::C)?;
2172                        asm.expect_symbol(SymbolName::ParenClose)?;
2173                    }
2174
2175                    Some(Token::Register {
2176                        name: RegisterName::D,
2177                        ..
2178                    }) => {
2179                        asm.data.push(0xED);
2180                        asm.data.push(0x50);
2181                        asm.expect_symbol(SymbolName::Comma)?;
2182                        asm.expect_symbol(SymbolName::ParenOpen)?;
2183                        asm.expect_register(RegisterName::C)?;
2184                        asm.expect_symbol(SymbolName::ParenClose)?;
2185                    }
2186
2187                    Some(Token::Register {
2188                        name: RegisterName::E,
2189                        ..
2190                    }) => {
2191                        asm.data.push(0xED);
2192                        asm.data.push(0x58);
2193                        asm.expect_symbol(SymbolName::Comma)?;
2194                        asm.expect_symbol(SymbolName::ParenOpen)?;
2195                        asm.expect_register(RegisterName::C)?;
2196                        asm.expect_symbol(SymbolName::ParenClose)?;
2197                    }
2198
2199                    Some(Token::Register {
2200                        name: RegisterName::H,
2201                        ..
2202                    }) => {
2203                        asm.data.push(0xED);
2204                        asm.data.push(0x60);
2205                        asm.expect_symbol(SymbolName::Comma)?;
2206                        asm.expect_symbol(SymbolName::ParenOpen)?;
2207                        asm.expect_register(RegisterName::C)?;
2208                        asm.expect_symbol(SymbolName::ParenClose)?;
2209                    }
2210
2211                    Some(Token::Register {
2212                        name: RegisterName::L,
2213                        ..
2214                    }) => {
2215                        asm.data.push(0xED);
2216                        asm.data.push(0x68);
2217                        asm.expect_symbol(SymbolName::Comma)?;
2218                        asm.expect_symbol(SymbolName::ParenOpen)?;
2219                        asm.expect_register(RegisterName::C)?;
2220                        asm.expect_symbol(SymbolName::ParenClose)?;
2221                    }
2222
2223                    Some(tok) => {
2224                        return asm_err!(
2225                            tok.loc(),
2226                            "Unexpected {}, expected a register",
2227                            tok.as_display(&asm.str_interner)
2228                        )
2229                    }
2230                }
2231            }
2232
2233            OperationName::Inc => {
2234                asm.next()?;
2235                match asm.next()? {
2236                    Some(Token::Register {
2237                        name: RegisterName::A,
2238                        ..
2239                    }) => {
2240                        asm.data.push(0x3C);
2241                    }
2242
2243                    Some(Token::Register {
2244                        name: RegisterName::B,
2245                        ..
2246                    }) => {
2247                        asm.data.push(0x04);
2248                    }
2249
2250                    Some(Token::Register {
2251                        name: RegisterName::C,
2252                        ..
2253                    }) => {
2254                        asm.data.push(0x0C);
2255                    }
2256
2257                    Some(Token::Register {
2258                        name: RegisterName::D,
2259                        ..
2260                    }) => {
2261                        asm.data.push(0x14);
2262                    }
2263
2264                    Some(Token::Register {
2265                        name: RegisterName::E,
2266                        ..
2267                    }) => {
2268                        asm.data.push(0x1C);
2269                    }
2270
2271                    Some(Token::Register {
2272                        name: RegisterName::H,
2273                        ..
2274                    }) => {
2275                        asm.data.push(0x24);
2276                    }
2277
2278                    Some(Token::Register {
2279                        name: RegisterName::L,
2280                        ..
2281                    }) => {
2282                        asm.data.push(0x2C);
2283                    }
2284
2285                    Some(Token::Register {
2286                        name: RegisterName::IXH,
2287                        ..
2288                    }) => {
2289                        asm.data.push(0xDD);
2290                        asm.data.push(0x24);
2291                    }
2292
2293                    Some(Token::Register {
2294                        name: RegisterName::IXL,
2295                        ..
2296                    }) => {
2297                        asm.data.push(0xDD);
2298                        asm.data.push(0x2C);
2299                    }
2300
2301                    Some(Token::Register {
2302                        name: RegisterName::IYH,
2303                        ..
2304                    }) => {
2305                        asm.data.push(0xFD);
2306                        asm.data.push(0x24);
2307                    }
2308
2309                    Some(Token::Register {
2310                        name: RegisterName::IYL,
2311                        ..
2312                    }) => {
2313                        asm.data.push(0xFD);
2314                        asm.data.push(0x2C);
2315                    }
2316
2317                    Some(Token::Register {
2318                        name: RegisterName::BC,
2319                        ..
2320                    }) => {
2321                        asm.data.push(0x03);
2322                    }
2323
2324                    Some(Token::Register {
2325                        name: RegisterName::DE,
2326                        ..
2327                    }) => {
2328                        asm.data.push(0x13);
2329                    }
2330
2331                    Some(Token::Register {
2332                        name: RegisterName::HL,
2333                        ..
2334                    }) => {
2335                        asm.data.push(0x23);
2336                    }
2337
2338                    Some(Token::Register {
2339                        name: RegisterName::SP,
2340                        ..
2341                    }) => {
2342                        asm.data.push(0x33);
2343                    }
2344
2345                    Some(Token::Register {
2346                        name: RegisterName::IX,
2347                        ..
2348                    }) => {
2349                        asm.data.push(0xDD);
2350                        asm.data.push(0x23);
2351                    }
2352
2353                    Some(Token::Register {
2354                        name: RegisterName::IY,
2355                        ..
2356                    }) => {
2357                        asm.data.push(0xFD);
2358                        asm.data.push(0x23);
2359                    }
2360
2361                    Some(Token::Symbol {
2362                        name: SymbolName::ParenOpen,
2363                        ..
2364                    }) => match asm.next()? {
2365                        None => return asm.end_of_input_err(),
2366
2367                        Some(Token::Register {
2368                            name: RegisterName::HL,
2369                            ..
2370                        }) => {
2371                            asm.data.push(0x34);
2372                            asm.expect_symbol(SymbolName::ParenClose)?;
2373                        }
2374
2375                        Some(Token::Register {
2376                            name: RegisterName::IX,
2377                            ..
2378                        }) => {
2379                            asm.expect_symbol(SymbolName::Plus)?;
2380                            asm.data.push(0xDD);
2381                            asm.data.push(0x34);
2382                            let (loc, expr) = asm.expr()?;
2383                            if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
2384                                if (value as u32) > (u8::MAX as u32) {
2385                                    return asm_err!(
2386                                        loc,
2387                                        "Expression result ({value}) will not fit in a byte"
2388                                    );
2389                                }
2390                                asm.data.push(value as u8);
2391                            } else {
2392                                asm.links.push(Link::byte(loc, asm.data.len(), expr));
2393                                asm.data.push(0);
2394                            }
2395                            asm.expect_symbol(SymbolName::ParenClose)?;
2396                        }
2397
2398                        Some(Token::Register {
2399                            name: RegisterName::IY,
2400                            ..
2401                        }) => {
2402                            asm.expect_symbol(SymbolName::Plus)?;
2403                            asm.data.push(0xFD);
2404                            asm.data.push(0x34);
2405                            let (loc, expr) = asm.expr()?;
2406                            if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
2407                                if (value as u32) > (u8::MAX as u32) {
2408                                    return asm_err!(
2409                                        loc,
2410                                        "Expression result ({value}) will not fit in a byte"
2411                                    );
2412                                }
2413                                asm.data.push(value as u8);
2414                            } else {
2415                                asm.links.push(Link::byte(loc, asm.data.len(), expr));
2416                                asm.data.push(0);
2417                            }
2418                            asm.expect_symbol(SymbolName::ParenClose)?;
2419                        }
2420
2421                        Some(tok) => {
2422                            return asm_err!(
2423                                tok.loc(),
2424                                "Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",
2425                                tok.as_display(&asm.str_interner)
2426                            )
2427                        }
2428                    },
2429
2430                    Some(tok) => {
2431                        return asm_err!(
2432                            tok.loc(),
2433                            "Unexpected {}, expected a register",
2434                            tok.as_display(&asm.str_interner)
2435                        )
2436                    }
2437                    None => return asm.end_of_input_err(),
2438                }
2439            }
2440
2441            OperationName::Ind => {
2442                asm.next()?;
2443                asm.data.push(0xED);
2444                asm.data.push(0xAA);
2445            }
2446
2447            OperationName::Indr => {
2448                asm.next()?;
2449                asm.data.push(0xED);
2450                asm.data.push(0xBA);
2451            }
2452
2453            OperationName::Ini => {
2454                asm.next()?;
2455                asm.data.push(0xED);
2456                asm.data.push(0xA2);
2457            }
2458
2459            OperationName::Inir => {
2460                asm.next()?;
2461                asm.data.push(0xED);
2462                asm.data.push(0xB2);
2463            }
2464
2465            OperationName::Jp => {
2466                asm.next()?;
2467                match asm.peek()? {
2468                    None => return asm.end_of_input_err(),
2469
2470                    Some(Token::Symbol {
2471                        name: SymbolName::ParenOpen,
2472                        ..
2473                    }) => {
2474                        asm.next()?;
2475                        match asm.next()? {
2476                            None => return asm.end_of_input_err(),
2477
2478                            Some(Token::Register {
2479                                name: RegisterName::HL,
2480                                ..
2481                            }) => {
2482                                asm.data.push(0xE9);
2483                            }
2484
2485                            Some(Token::Register {
2486                                name: RegisterName::IX,
2487                                ..
2488                            }) => {
2489                                asm.data.push(0xDD);
2490                                asm.data.push(0xE9);
2491                            }
2492
2493                            Some(Token::Register {
2494                                name: RegisterName::IY,
2495                                ..
2496                            }) => {
2497                                asm.data.push(0xFD);
2498                                asm.data.push(0xE9);
2499                            }
2500
2501                            Some(tok) => {
2502                                return asm_err!(
2503                                    tok.loc(),
2504                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
2505                                    tok.as_display(&asm.str_interner)
2506                                )
2507                            }
2508                        }
2509                        asm.expect_symbol(SymbolName::ParenClose)?;
2510                    }
2511
2512                    Some(_) => {
2513                        match asm.peek()? {
2514                            None => return asm.end_of_input_err(),
2515                            Some(Token::Flag {
2516                                name: FlagName::Zero,
2517                                ..
2518                            }) => {
2519                                asm.next()?;
2520                                asm.data.push(0xCA);
2521                                asm.expect_symbol(SymbolName::Comma)?;
2522                            }
2523                            Some(Token::Flag {
2524                                name: FlagName::NotZero,
2525                                ..
2526                            }) => {
2527                                asm.next()?;
2528                                asm.data.push(0xC2);
2529                                asm.expect_symbol(SymbolName::Comma)?;
2530                            }
2531                            Some(Token::Register {
2532                                name: RegisterName::C,
2533                                ..
2534                            }) => {
2535                                asm.next()?;
2536                                asm.data.push(0xDA);
2537                                asm.expect_symbol(SymbolName::Comma)?;
2538                            }
2539                            Some(Token::Flag {
2540                                name: FlagName::NotCarry,
2541                                ..
2542                            }) => {
2543                                asm.next()?;
2544                                asm.data.push(0xD2);
2545                                asm.expect_symbol(SymbolName::Comma)?;
2546                            }
2547                            Some(Token::Flag {
2548                                name: FlagName::ParityEven,
2549                                ..
2550                            }) => {
2551                                asm.next()?;
2552                                asm.data.push(0xEA);
2553                                asm.expect_symbol(SymbolName::Comma)?;
2554                            }
2555                            Some(Token::Flag {
2556                                name: FlagName::ParityOdd,
2557                                ..
2558                            }) => {
2559                                asm.next()?;
2560                                asm.data.push(0xE2);
2561                                asm.expect_symbol(SymbolName::Comma)?;
2562                            }
2563                            Some(Token::Flag {
2564                                name: FlagName::Positive,
2565                                ..
2566                            }) => {
2567                                asm.next()?;
2568                                asm.data.push(0xF2);
2569                                asm.expect_symbol(SymbolName::Comma)?;
2570                            }
2571                            Some(Token::Flag {
2572                                name: FlagName::Negative,
2573                                ..
2574                            }) => {
2575                                asm.next()?;
2576                                asm.data.push(0xFA);
2577                                asm.expect_symbol(SymbolName::Comma)?;
2578                            }
2579                            Some(_) => {
2580                                asm.data.push(0xC3);
2581                            }
2582                        }
2583                        let (loc, expr) = asm.expr()?;
2584                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
2585                            if (value as u32) > (u16::MAX as u32) {
2586                                return asm_err!(
2587                                    loc,
2588                                    "Expression result ({value}) will not fit in a word"
2589                                );
2590                            }
2591                            asm.data.extend_from_slice(&(value as u16).to_le_bytes());
2592                        } else {
2593                            asm.links.push(Link::word(loc, asm.data.len(), expr));
2594                            asm.data.push(0);
2595                            asm.data.push(0);
2596                        }
2597                    }
2598                }
2599            }
2600
2601            OperationName::Jr => {
2602                asm.next()?;
2603                match asm.peek()? {
2604                    None => return asm.end_of_input_err(),
2605
2606                    Some(Token::Flag {
2607                        name: FlagName::NotZero,
2608                        ..
2609                    }) => {
2610                        asm.next()?;
2611                        asm.data.push(0x20);
2612                        asm.expect_symbol(SymbolName::Comma)?;
2613                    }
2614
2615                    Some(Token::Flag {
2616                        name: FlagName::Zero,
2617                        ..
2618                    }) => {
2619                        asm.next()?;
2620                        asm.data.push(0x28);
2621                        asm.expect_symbol(SymbolName::Comma)?;
2622                    }
2623
2624                    Some(Token::Flag {
2625                        name: FlagName::NotCarry,
2626                        ..
2627                    }) => {
2628                        asm.next()?;
2629                        asm.data.push(0x30);
2630                        asm.expect_symbol(SymbolName::Comma)?;
2631                    }
2632
2633                    Some(Token::Register {
2634                        name: RegisterName::C,
2635                        ..
2636                    }) => {
2637                        asm.next()?;
2638                        asm.data.push(0x38);
2639                        asm.expect_symbol(SymbolName::Comma)?;
2640                    }
2641
2642                    Some(_) => {
2643                        asm.data.push(0x18);
2644                    }
2645                }
2646                let (loc, mut expr) = asm.expr()?;
2647                // Make the expression relative to @here
2648                expr.push(ExprNode::Value(asm.here.wrapping_add(2) as i32));
2649                expr.push(ExprNode::Sub);
2650                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
2651                    if (value < (i8::MIN as i32)) || (value > (i8::MAX as i32)) {
2652                        return asm_err!(loc, "Jump distance ({value}) will not fit in a byte");
2653                    }
2654                    asm.data.push(value as u8);
2655                } else {
2656                    asm.links.push(Link::signed_byte(loc, asm.data.len(), expr));
2657                    asm.data.push(0);
2658                }
2659            }
2660
2661            OperationName::Ld => {
2662                asm.next()?;
2663                match asm.next()? {
2664                    None => return asm.end_of_input_err(),
2665                    Some(Token::Register {
2666                        name: RegisterName::A,
2667                        ..
2668                    }) => {
2669                        asm.expect_symbol(SymbolName::Comma)?;
2670                        match asm.peek()? {
2671                            None => return asm.end_of_input_err(),
2672                            Some(Token::Register {
2673                                name: RegisterName::A,
2674                                ..
2675                            }) => {
2676                                asm.next()?;
2677                                asm.data.push(0x7F);
2678                            }
2679                            Some(Token::Register {
2680                                name: RegisterName::B,
2681                                ..
2682                            }) => {
2683                                asm.next()?;
2684                                asm.data.push(0x78);
2685                            }
2686                            Some(Token::Register {
2687                                name: RegisterName::C,
2688                                ..
2689                            }) => {
2690                                asm.next()?;
2691                                asm.data.push(0x79);
2692                            }
2693                            Some(Token::Register {
2694                                name: RegisterName::D,
2695                                ..
2696                            }) => {
2697                                asm.next()?;
2698                                asm.data.push(0x7A);
2699                            }
2700                            Some(Token::Register {
2701                                name: RegisterName::E,
2702                                ..
2703                            }) => {
2704                                asm.next()?;
2705                                asm.data.push(0x7B);
2706                            }
2707                            Some(Token::Register {
2708                                name: RegisterName::H,
2709                                ..
2710                            }) => {
2711                                asm.next()?;
2712                                asm.data.push(0x7C);
2713                            }
2714                            Some(Token::Register {
2715                                name: RegisterName::L,
2716                                ..
2717                            }) => {
2718                                asm.next()?;
2719                                asm.data.push(0x7D);
2720                            }
2721                            Some(Token::Register {
2722                                name: RegisterName::IXH,
2723                                ..
2724                            }) => {
2725                                asm.next()?;
2726                                asm.data.push(0xDD);
2727                                asm.data.push(0x7C);
2728                            }
2729                            Some(Token::Register {
2730                                name: RegisterName::IXL,
2731                                ..
2732                            }) => {
2733                                asm.next()?;
2734                                asm.data.push(0xDD);
2735                                asm.data.push(0x7D);
2736                            }
2737                            Some(Token::Register {
2738                                name: RegisterName::IYH,
2739                                ..
2740                            }) => {
2741                                asm.next()?;
2742                                asm.data.push(0xFD);
2743                                asm.data.push(0x7C);
2744                            }
2745                            Some(Token::Register {
2746                                name: RegisterName::IYL,
2747                                ..
2748                            }) => {
2749                                asm.next()?;
2750                                asm.data.push(0xFD);
2751                                asm.data.push(0x7D);
2752                            }
2753                            Some(Token::Register {
2754                                name: RegisterName::I,
2755                                ..
2756                            }) => {
2757                                asm.next()?;
2758                                asm.data.push(0xED);
2759                                asm.data.push(0x57);
2760                            }
2761                            Some(Token::Register {
2762                                name: RegisterName::R,
2763                                ..
2764                            }) => {
2765                                asm.next()?;
2766                                asm.data.push(0xED);
2767                                asm.data.push(0x5F);
2768                            }
2769                            Some(Token::Symbol {
2770                                name: SymbolName::ParenOpen,
2771                                ..
2772                            }) => {
2773                                asm.next()?;
2774                                match asm.peek()? {
2775                                    None => return asm.end_of_input_err(),
2776
2777                                    Some(Token::Register {
2778                                        name: RegisterName::BC,
2779                                        ..
2780                                    }) => {
2781                                        asm.next()?;
2782                                        asm.data.push(0x0A);
2783                                    }
2784
2785                                    Some(Token::Register {
2786                                        name: RegisterName::DE,
2787                                        ..
2788                                    }) => {
2789                                        asm.next()?;
2790                                        asm.data.push(0x1A);
2791                                    }
2792
2793                                    Some(Token::Register {
2794                                        name: RegisterName::HL,
2795                                        ..
2796                                    }) => {
2797                                        asm.next()?;
2798                                        asm.data.push(0x7E);
2799                                    }
2800
2801                                    Some(Token::Register { loc, name }) => {
2802                                        asm.next()?;
2803                                        match name {
2804                                            RegisterName::IX => {
2805                                                asm.data.push(0xDD);
2806                                                asm.data.push(0x7E);
2807                                            }
2808                                            RegisterName::IY => {
2809                                                asm.data.push(0xFD);
2810                                                asm.data.push(0x7E);
2811                                            }
2812                                            _ => return asm_err!(loc,"Unexpected register \"{name}\", expected register \"ix\" or \"iy\""),
2813                                        }
2814                                        asm.expect_symbol(SymbolName::Plus)?;
2815                                        let (loc, expr) = asm.expr()?;
2816                                        if let Some(value) =
2817                                            expr.evaluate(&asm.symtab, &asm.str_interner)
2818                                        {
2819                                            if (value as u32) > (u8::MAX as u32) {
2820                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
2821                                            }
2822                                            asm.data.push(value as u8);
2823                                        } else {
2824                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
2825                                            asm.data.push(0);
2826                                        }
2827                                    }
2828
2829                                    Some(_) => {
2830                                        asm.data.push(0x3A);
2831                                        let (loc, expr) = asm.expr()?;
2832                                        if let Some(value) =
2833                                            expr.evaluate(&asm.symtab, &asm.str_interner)
2834                                        {
2835                                            if (value as u32) > (u16::MAX as u32) {
2836                                                return asm_err!(loc,"Expression result ({value}) will not fit in a word");
2837                                            }
2838                                            asm.data
2839                                                .extend_from_slice(&(value as u16).to_le_bytes());
2840                                        } else {
2841                                            asm.links.push(Link::word(loc, asm.data.len(), expr));
2842                                            asm.data.push(0);
2843                                            asm.data.push(0);
2844                                        }
2845                                    }
2846                                }
2847                                asm.expect_symbol(SymbolName::ParenClose)?;
2848                            }
2849                            Some(_) => {
2850                                asm.data.push(0x3E);
2851                                let (loc, expr) = asm.expr()?;
2852                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
2853                                    if (value as u32) > (u8::MAX as u32) {
2854                                        return asm_err!(
2855                                            loc,
2856                                            "Expression result ({value}) will not fit in a byte"
2857                                        );
2858                                    }
2859                                    asm.data.push(value as u8);
2860                                } else {
2861                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
2862                                    asm.data.push(0);
2863                                }
2864                            }
2865                        }
2866                    }
2867
2868                    Some(Token::Register {
2869                        name: RegisterName::B,
2870                        ..
2871                    }) => {
2872                        asm.expect_symbol(SymbolName::Comma)?;
2873                        match asm.peek()? {
2874                            None => return asm.end_of_input_err(),
2875                            Some(Token::Register {
2876                                name: RegisterName::A,
2877                                ..
2878                            }) => {
2879                                asm.next()?;
2880                                asm.data.push(0x47);
2881                            }
2882                            Some(Token::Register {
2883                                name: RegisterName::B,
2884                                ..
2885                            }) => {
2886                                asm.next()?;
2887                                asm.data.push(0x40);
2888                            }
2889                            Some(Token::Register {
2890                                name: RegisterName::C,
2891                                ..
2892                            }) => {
2893                                asm.next()?;
2894                                asm.data.push(0x41);
2895                            }
2896                            Some(Token::Register {
2897                                name: RegisterName::D,
2898                                ..
2899                            }) => {
2900                                asm.next()?;
2901                                asm.data.push(0x42);
2902                            }
2903                            Some(Token::Register {
2904                                name: RegisterName::E,
2905                                ..
2906                            }) => {
2907                                asm.next()?;
2908                                asm.data.push(0x43);
2909                            }
2910                            Some(Token::Register {
2911                                name: RegisterName::H,
2912                                ..
2913                            }) => {
2914                                asm.next()?;
2915                                asm.data.push(0x44);
2916                            }
2917                            Some(Token::Register {
2918                                name: RegisterName::L,
2919                                ..
2920                            }) => {
2921                                asm.next()?;
2922                                asm.data.push(0x45);
2923                            }
2924                            Some(Token::Register {
2925                                name: RegisterName::IXH,
2926                                ..
2927                            }) => {
2928                                asm.next()?;
2929                                asm.data.push(0xDD);
2930                                asm.data.push(0x44);
2931                            }
2932                            Some(Token::Register {
2933                                name: RegisterName::IXL,
2934                                ..
2935                            }) => {
2936                                asm.next()?;
2937                                asm.data.push(0xDD);
2938                                asm.data.push(0x45);
2939                            }
2940                            Some(Token::Register {
2941                                name: RegisterName::IYH,
2942                                ..
2943                            }) => {
2944                                asm.next()?;
2945                                asm.data.push(0xFD);
2946                                asm.data.push(0x44);
2947                            }
2948                            Some(Token::Register {
2949                                name: RegisterName::IYL,
2950                                ..
2951                            }) => {
2952                                asm.next()?;
2953                                asm.data.push(0xFD);
2954                                asm.data.push(0x45);
2955                            }
2956                            Some(Token::Symbol {
2957                                name: SymbolName::ParenOpen,
2958                                ..
2959                            }) => {
2960                                asm.next()?;
2961                                match asm.peek()? {
2962                                    None => return asm.end_of_input_err(),
2963                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
2964                                        asm.next()?;
2965                                        asm.data.push(0x46);
2966                                    }
2967                                    Some(Token::Register { loc, name }) => {
2968                                        asm.next()?;
2969                                        match name {
2970                                            RegisterName::IX => {
2971                                                asm.data.push(0xDD);
2972                                                asm.data.push(0x46);
2973                                            }
2974                                            RegisterName::IY => {
2975                                                asm.data.push(0xFD);
2976                                                asm.data.push(0x46);
2977                                            }
2978                                            _ => return asm_err!(loc,"Unexpected register \"{name}\", expected register \"ix\" or \"iy\""),
2979                                        }
2980                                        asm.expect_symbol(SymbolName::Plus)?;
2981                                        let (loc, expr) = asm.expr()?;
2982                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
2983                                            if (value as u32) > (u8::MAX as u32) {
2984                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
2985                                            }
2986                                            asm.data.push(value as u8);
2987                                        } else {
2988                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
2989                                            asm.data.push(0);
2990                                        }
2991                                    }
2992                                    Some(tok) => return asm_err!(tok.loc() ,"Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
2993                                }
2994                                asm.expect_symbol(SymbolName::ParenClose)?;
2995                            }
2996                            Some(_) => {
2997                                asm.data.push(0x06);
2998                                let (loc, expr) = asm.expr()?;
2999                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3000                                    if (value as u32) > (u8::MAX as u32) {
3001                                        return asm_err!(
3002                                            loc,
3003                                            "Expression result ({value}) will not fit in a byte"
3004                                        );
3005                                    }
3006                                    asm.data.push(value as u8);
3007                                } else {
3008                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3009                                    asm.data.push(0);
3010                                }
3011                            }
3012                        }
3013                    }
3014
3015                    Some(Token::Register {
3016                        name: RegisterName::C,
3017                        ..
3018                    }) => {
3019                        asm.expect_symbol(SymbolName::Comma)?;
3020                        match asm.peek()? {
3021                            None => return asm.end_of_input_err(),
3022                            Some(Token::Register {
3023                                name: RegisterName::A,
3024                                ..
3025                            }) => {
3026                                asm.next()?;
3027                                asm.data.push(0x4F);
3028                            }
3029                            Some(Token::Register {
3030                                name: RegisterName::B,
3031                                ..
3032                            }) => {
3033                                asm.next()?;
3034                                asm.data.push(0x48);
3035                            }
3036                            Some(Token::Register {
3037                                name: RegisterName::C,
3038                                ..
3039                            }) => {
3040                                asm.next()?;
3041                                asm.data.push(0x49);
3042                            }
3043                            Some(Token::Register {
3044                                name: RegisterName::D,
3045                                ..
3046                            }) => {
3047                                asm.next()?;
3048                                asm.data.push(0x4A);
3049                            }
3050                            Some(Token::Register {
3051                                name: RegisterName::E,
3052                                ..
3053                            }) => {
3054                                asm.next()?;
3055                                asm.data.push(0x4B);
3056                            }
3057                            Some(Token::Register {
3058                                name: RegisterName::H,
3059                                ..
3060                            }) => {
3061                                asm.next()?;
3062                                asm.data.push(0x4C);
3063                            }
3064                            Some(Token::Register {
3065                                name: RegisterName::L,
3066                                ..
3067                            }) => {
3068                                asm.next()?;
3069                                asm.data.push(0x4D);
3070                            }
3071                            Some(Token::Register {
3072                                name: RegisterName::IXH,
3073                                ..
3074                            }) => {
3075                                asm.next()?;
3076                                asm.data.push(0xDD);
3077                                asm.data.push(0x4C);
3078                            }
3079                            Some(Token::Register {
3080                                name: RegisterName::IXL,
3081                                ..
3082                            }) => {
3083                                asm.next()?;
3084                                asm.data.push(0xDD);
3085                                asm.data.push(0x4D);
3086                            }
3087                            Some(Token::Register {
3088                                name: RegisterName::IYH,
3089                                ..
3090                            }) => {
3091                                asm.next()?;
3092                                asm.data.push(0xFD);
3093                                asm.data.push(0x4C);
3094                            }
3095                            Some(Token::Register {
3096                                name: RegisterName::IYL,
3097                                ..
3098                            }) => {
3099                                asm.next()?;
3100                                asm.data.push(0xFD);
3101                                asm.data.push(0x4D);
3102                            }
3103                            Some(Token::Symbol {
3104                                name: SymbolName::ParenOpen,
3105                                ..
3106                            }) => {
3107                                asm.next()?;
3108                                match asm.peek()? {
3109                                    None => return asm.end_of_input_err(),
3110                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
3111                                        asm.next()?;
3112                                        asm.data.push(0x4E);
3113                                    }
3114                                    Some(Token::Register { loc, name }) => {
3115                                        asm.next()?;
3116                                        match name {
3117                                            RegisterName::IX => {
3118                                                asm.data.push(0xDD);
3119                                                asm.data.push(0x4E);
3120                                            }
3121                                            RegisterName::IY => {
3122                                                asm.data.push(0xFD);
3123                                                asm.data.push(0x4E);
3124                                            }
3125                                            _ => return asm_err!(loc,"Unexpected register \"{name}\", expected register \"ix\" or \"iy\""),
3126                                        }
3127                                        asm.expect_symbol(SymbolName::Plus)?;
3128                                        let (loc, expr) = asm.expr()?;
3129                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3130                                            if (value as u32) > (u8::MAX as u32) {
3131                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
3132                                            }
3133                                            asm.data.push(value as u8);
3134                                        } else {
3135                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
3136                                            asm.data.push(0);
3137                                        }
3138                                    }
3139                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
3140                                }
3141                                asm.expect_symbol(SymbolName::ParenClose)?;
3142                            }
3143                            Some(_) => {
3144                                asm.data.push(0x0E);
3145                                let (loc, expr) = asm.expr()?;
3146                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3147                                    if (value as u32) > (u8::MAX as u32) {
3148                                        return asm_err!(
3149                                            loc,
3150                                            "Expression result ({value}) will not fit in a byte"
3151                                        );
3152                                    }
3153                                    asm.data.push(value as u8);
3154                                } else {
3155                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3156                                    asm.data.push(0);
3157                                }
3158                            }
3159                        }
3160                    }
3161
3162                    Some(Token::Register {
3163                        name: RegisterName::D,
3164                        ..
3165                    }) => {
3166                        asm.expect_symbol(SymbolName::Comma)?;
3167                        match asm.peek()? {
3168                            None => return asm.end_of_input_err(),
3169                            Some(Token::Register {
3170                                name: RegisterName::A,
3171                                ..
3172                            }) => {
3173                                asm.next()?;
3174                                asm.data.push(0x57);
3175                            }
3176                            Some(Token::Register {
3177                                name: RegisterName::B,
3178                                ..
3179                            }) => {
3180                                asm.next()?;
3181                                asm.data.push(0x50);
3182                            }
3183                            Some(Token::Register {
3184                                name: RegisterName::C,
3185                                ..
3186                            }) => {
3187                                asm.next()?;
3188                                asm.data.push(0x51);
3189                            }
3190                            Some(Token::Register {
3191                                name: RegisterName::D,
3192                                ..
3193                            }) => {
3194                                asm.next()?;
3195                                asm.data.push(0x52);
3196                            }
3197                            Some(Token::Register {
3198                                name: RegisterName::E,
3199                                ..
3200                            }) => {
3201                                asm.next()?;
3202                                asm.data.push(0x53);
3203                            }
3204                            Some(Token::Register {
3205                                name: RegisterName::H,
3206                                ..
3207                            }) => {
3208                                asm.next()?;
3209                                asm.data.push(0x54);
3210                            }
3211                            Some(Token::Register {
3212                                name: RegisterName::L,
3213                                ..
3214                            }) => {
3215                                asm.next()?;
3216                                asm.data.push(0x55);
3217                            }
3218                            Some(Token::Register {
3219                                name: RegisterName::IXH,
3220                                ..
3221                            }) => {
3222                                asm.next()?;
3223                                asm.data.push(0xDD);
3224                                asm.data.push(0x54);
3225                            }
3226                            Some(Token::Register {
3227                                name: RegisterName::IXL,
3228                                ..
3229                            }) => {
3230                                asm.next()?;
3231                                asm.data.push(0xDD);
3232                                asm.data.push(0x55);
3233                            }
3234                            Some(Token::Register {
3235                                name: RegisterName::IYH,
3236                                ..
3237                            }) => {
3238                                asm.next()?;
3239                                asm.data.push(0xFD);
3240                                asm.data.push(0x54);
3241                            }
3242                            Some(Token::Register {
3243                                name: RegisterName::IYL,
3244                                ..
3245                            }) => {
3246                                asm.next()?;
3247                                asm.data.push(0xFD);
3248                                asm.data.push(0x55);
3249                            }
3250                            Some(Token::Symbol {
3251                                name: SymbolName::ParenOpen,
3252                                ..
3253                            }) => {
3254                                asm.next()?;
3255                                match asm.peek()? {
3256                                    None => return asm.end_of_input_err(),
3257                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
3258                                        asm.next()?;
3259                                        asm.data.push(0x56);
3260                                    }
3261                                    Some(Token::Register { loc, name }) => {
3262                                        asm.next()?;
3263                                        match name {
3264                                            RegisterName::IX => {
3265                                                asm.data.push(0xDD);
3266                                                asm.data.push(0x56);
3267                                            }
3268                                            RegisterName::IY => {
3269                                                asm.data.push(0xFD);
3270                                                asm.data.push(0x56);
3271                                            }
3272                                            _ => return asm_err!(loc,"Unexpected register \"{name}\", expected register \"ix\" or \"iy\""),
3273                                        }
3274                                        asm.expect_symbol(SymbolName::Plus)?;
3275                                        let (loc, expr) = asm.expr()?;
3276                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3277                                            if (value as u32) > (u8::MAX as u32) {
3278                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
3279                                            }
3280                                            asm.data.push(value as u8);
3281                                        } else {
3282                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
3283                                            asm.data.push(0);
3284                                        }
3285                                    }
3286                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
3287                                }
3288                                asm.expect_symbol(SymbolName::ParenClose)?;
3289                            }
3290                            Some(_) => {
3291                                asm.data.push(0x16);
3292                                let (loc, expr) = asm.expr()?;
3293                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3294                                    if (value as u32) > (u8::MAX as u32) {
3295                                        return asm_err!(
3296                                            loc,
3297                                            "Expression result ({value}) will not fit in a byte"
3298                                        );
3299                                    }
3300                                    asm.data.push(value as u8);
3301                                } else {
3302                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3303                                    asm.data.push(0);
3304                                }
3305                            }
3306                        }
3307                    }
3308
3309                    Some(Token::Register {
3310                        name: RegisterName::E,
3311                        ..
3312                    }) => {
3313                        asm.expect_symbol(SymbolName::Comma)?;
3314                        match asm.peek()? {
3315                            None => return asm.end_of_input_err(),
3316                            Some(Token::Register {
3317                                name: RegisterName::A,
3318                                ..
3319                            }) => {
3320                                asm.next()?;
3321                                asm.data.push(0x5F);
3322                            }
3323                            Some(Token::Register {
3324                                name: RegisterName::B,
3325                                ..
3326                            }) => {
3327                                asm.next()?;
3328                                asm.data.push(0x58);
3329                            }
3330                            Some(Token::Register {
3331                                name: RegisterName::C,
3332                                ..
3333                            }) => {
3334                                asm.next()?;
3335                                asm.data.push(0x59);
3336                            }
3337                            Some(Token::Register {
3338                                name: RegisterName::D,
3339                                ..
3340                            }) => {
3341                                asm.next()?;
3342                                asm.data.push(0x5A);
3343                            }
3344                            Some(Token::Register {
3345                                name: RegisterName::E,
3346                                ..
3347                            }) => {
3348                                asm.next()?;
3349                                asm.data.push(0x5B);
3350                            }
3351                            Some(Token::Register {
3352                                name: RegisterName::H,
3353                                ..
3354                            }) => {
3355                                asm.next()?;
3356                                asm.data.push(0x5C);
3357                            }
3358                            Some(Token::Register {
3359                                name: RegisterName::L,
3360                                ..
3361                            }) => {
3362                                asm.next()?;
3363                                asm.data.push(0x5D);
3364                            }
3365                            Some(Token::Register {
3366                                name: RegisterName::IXH,
3367                                ..
3368                            }) => {
3369                                asm.next()?;
3370                                asm.data.push(0xDD);
3371                                asm.data.push(0x5C);
3372                            }
3373                            Some(Token::Register {
3374                                name: RegisterName::IXL,
3375                                ..
3376                            }) => {
3377                                asm.next()?;
3378                                asm.data.push(0xDD);
3379                                asm.data.push(0x5D);
3380                            }
3381                            Some(Token::Register {
3382                                name: RegisterName::IYH,
3383                                ..
3384                            }) => {
3385                                asm.next()?;
3386                                asm.data.push(0xFD);
3387                                asm.data.push(0x5C);
3388                            }
3389                            Some(Token::Register {
3390                                name: RegisterName::IYL,
3391                                ..
3392                            }) => {
3393                                asm.next()?;
3394                                asm.data.push(0xFD);
3395                                asm.data.push(0x5D);
3396                            }
3397                            Some(Token::Symbol {
3398                                name: SymbolName::ParenOpen,
3399                                ..
3400                            }) => {
3401                                asm.next()?;
3402                                match asm.peek()? {
3403                                    None => return asm.end_of_input_err(),
3404                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
3405                                        asm.next()?;
3406                                        asm.data.push(0x5E);
3407                                    }
3408                                    Some(Token::Register { loc, name }) => {
3409                                        asm.next()?;
3410                                        match name {
3411                                            RegisterName::IX => {
3412                                                asm.data.push(0xDD);
3413                                                asm.data.push(0x5E);
3414                                            }
3415                                            RegisterName::IY => {
3416                                                asm.data.push(0xFD);
3417                                                asm.data.push(0x5E);
3418                                            }
3419                                            _ => return asm_err!(loc,"Unexpected register \"{name}\", expected register \"ix\" or \"iy\""),
3420                                        }
3421                                        asm.expect_symbol(SymbolName::Plus)?;
3422                                        let (loc, expr) = asm.expr()?;
3423                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3424                                            if (value as u32) > (u8::MAX as u32) {
3425                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
3426                                            }
3427                                            asm.data.push(value as u8);
3428                                        } else {
3429                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
3430                                            asm.data.push(0);
3431                                        }
3432                                    }
3433                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
3434                                }
3435                                asm.expect_symbol(SymbolName::ParenClose)?;
3436                            }
3437                            Some(_) => {
3438                                asm.data.push(0x1E);
3439                                let (loc, expr) = asm.expr()?;
3440                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3441                                    if (value as u32) > (u8::MAX as u32) {
3442                                        return asm_err!(
3443                                            loc,
3444                                            "Expression result ({value}) will not fit in a byte"
3445                                        );
3446                                    }
3447                                    asm.data.push(value as u8);
3448                                } else {
3449                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3450                                    asm.data.push(0);
3451                                }
3452                            }
3453                        }
3454                    }
3455
3456                    Some(Token::Register {
3457                        name: RegisterName::H,
3458                        ..
3459                    }) => {
3460                        asm.expect_symbol(SymbolName::Comma)?;
3461                        match asm.peek()? {
3462                            None => return asm.end_of_input_err(),
3463                            Some(Token::Register {
3464                                name: RegisterName::A,
3465                                ..
3466                            }) => {
3467                                asm.next()?;
3468                                asm.data.push(0x67);
3469                            }
3470                            Some(Token::Register {
3471                                name: RegisterName::B,
3472                                ..
3473                            }) => {
3474                                asm.next()?;
3475                                asm.data.push(0x60);
3476                            }
3477                            Some(Token::Register {
3478                                name: RegisterName::C,
3479                                ..
3480                            }) => {
3481                                asm.next()?;
3482                                asm.data.push(0x61);
3483                            }
3484                            Some(Token::Register {
3485                                name: RegisterName::D,
3486                                ..
3487                            }) => {
3488                                asm.next()?;
3489                                asm.data.push(0x62);
3490                            }
3491                            Some(Token::Register {
3492                                name: RegisterName::E,
3493                                ..
3494                            }) => {
3495                                asm.next()?;
3496                                asm.data.push(0x63);
3497                            }
3498                            Some(Token::Register {
3499                                name: RegisterName::H,
3500                                ..
3501                            }) => {
3502                                asm.next()?;
3503                                asm.data.push(0x64);
3504                            }
3505                            Some(Token::Register {
3506                                name: RegisterName::L,
3507                                ..
3508                            }) => {
3509                                asm.next()?;
3510                                asm.data.push(0x65);
3511                            }
3512                            Some(Token::Symbol {
3513                                name: SymbolName::ParenOpen,
3514                                ..
3515                            }) => {
3516                                asm.next()?;
3517                                match asm.peek()? {
3518                                    None => return asm.end_of_input_err(),
3519                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
3520                                        asm.next()?;
3521                                        asm.data.push(0x66);
3522                                    }
3523                                    Some(Token::Register { loc, name }) => {
3524                                        asm.next()?;
3525                                        match name {
3526                                            RegisterName::IX => {
3527                                                asm.data.push(0xDD);
3528                                                asm.data.push(0x66);
3529                                            }
3530                                            RegisterName::IY => {
3531                                                asm.data.push(0xFD);
3532                                                asm.data.push(0x66);
3533                                            }
3534                                            _ => return asm_err!(loc,"Unexpected register \"{name}\", expected register \"ix\" or \"iy\""),
3535                                        }
3536                                        asm.expect_symbol(SymbolName::Plus)?;
3537                                        let (loc, expr) = asm.expr()?;
3538                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3539                                            if (value as u32) > (u8::MAX as u32) {
3540                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
3541                                            }
3542                                            asm.data.push(value as u8);
3543                                        } else {
3544                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
3545                                            asm.data.push(0);
3546                                        }
3547                                    }
3548                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
3549                                }
3550                                asm.expect_symbol(SymbolName::ParenClose)?;
3551                            }
3552                            Some(_) => {
3553                                asm.data.push(0x26);
3554                                let (loc, expr) = asm.expr()?;
3555                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3556                                    if (value as u32) > (u8::MAX as u32) {
3557                                        return asm_err!(
3558                                            loc,
3559                                            "Expression result ({value}) will not fit in a byte"
3560                                        );
3561                                    }
3562                                    asm.data.push(value as u8);
3563                                } else {
3564                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3565                                    asm.data.push(0);
3566                                }
3567                            }
3568                        }
3569                    }
3570
3571                    Some(Token::Register {
3572                        name: RegisterName::L,
3573                        ..
3574                    }) => {
3575                        asm.expect_symbol(SymbolName::Comma)?;
3576                        match asm.peek()? {
3577                            None => return asm.end_of_input_err(),
3578                            Some(Token::Register {
3579                                name: RegisterName::A,
3580                                ..
3581                            }) => {
3582                                asm.next()?;
3583                                asm.data.push(0x6F);
3584                            }
3585                            Some(Token::Register {
3586                                name: RegisterName::B,
3587                                ..
3588                            }) => {
3589                                asm.next()?;
3590                                asm.data.push(0x68);
3591                            }
3592                            Some(Token::Register {
3593                                name: RegisterName::C,
3594                                ..
3595                            }) => {
3596                                asm.next()?;
3597                                asm.data.push(0x69);
3598                            }
3599                            Some(Token::Register {
3600                                name: RegisterName::D,
3601                                ..
3602                            }) => {
3603                                asm.next()?;
3604                                asm.data.push(0x6A);
3605                            }
3606                            Some(Token::Register {
3607                                name: RegisterName::E,
3608                                ..
3609                            }) => {
3610                                asm.next()?;
3611                                asm.data.push(0x6B);
3612                            }
3613                            Some(Token::Register {
3614                                name: RegisterName::H,
3615                                ..
3616                            }) => {
3617                                asm.next()?;
3618                                asm.data.push(0x6C);
3619                            }
3620                            Some(Token::Register {
3621                                name: RegisterName::L,
3622                                ..
3623                            }) => {
3624                                asm.next()?;
3625                                asm.data.push(0x6D);
3626                            }
3627                            Some(Token::Symbol {
3628                                name: SymbolName::ParenOpen,
3629                                ..
3630                            }) => {
3631                                asm.next()?;
3632                                match asm.peek()? {
3633                                    None => return asm.end_of_input_err(),
3634                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
3635                                        asm.next()?;
3636                                        asm.data.push(0x6E);
3637                                    }
3638                                    Some(Token::Register { loc, name }) => {
3639                                        asm.next()?;
3640                                        match name {
3641                                            RegisterName::IX => {
3642                                                asm.data.push(0xDD);
3643                                                asm.data.push(0x6E);
3644                                            }
3645                                            RegisterName::IY => {
3646                                                asm.data.push(0xFD);
3647                                                asm.data.push(0x6E);
3648                                            }
3649                                            _ => return asm_err!(loc,"Unexpected register \"{name}\", expected register \"ix\" or \"iy\""),
3650                                        }
3651                                        asm.expect_symbol(SymbolName::Plus)?;
3652                                        let (loc, expr) = asm.expr()?;
3653                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3654                                            if (value as u32) > (u8::MAX as u32) {
3655                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
3656                                            }
3657                                            asm.data.push(value as u8);
3658                                        } else {
3659                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
3660                                            asm.data.push(0);
3661                                        }
3662                                    }
3663                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
3664                                }
3665                                asm.expect_symbol(SymbolName::ParenClose)?;
3666                            }
3667                            Some(_) => {
3668                                asm.data.push(0x2E);
3669                                let (loc, expr) = asm.expr()?;
3670                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3671                                    if (value as u32) > (u8::MAX as u32) {
3672                                        return asm_err!(
3673                                            loc,
3674                                            "Expression result ({value}) will not fit in a byte"
3675                                        );
3676                                    }
3677                                    asm.data.push(value as u8);
3678                                } else {
3679                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3680                                    asm.data.push(0);
3681                                }
3682                            }
3683                        }
3684                    }
3685
3686                    Some(Token::Register {
3687                        name: RegisterName::IXH,
3688                        ..
3689                    }) => {
3690                        asm.expect_symbol(SymbolName::Comma)?;
3691                        match asm.peek()? {
3692                            None => return asm.end_of_input_err(),
3693                            Some(Token::Register {
3694                                name: RegisterName::A,
3695                                ..
3696                            }) => {
3697                                asm.next()?;
3698                                asm.data.push(0xDD);
3699                                asm.data.push(0x67);
3700                            }
3701                            Some(Token::Register {
3702                                name: RegisterName::B,
3703                                ..
3704                            }) => {
3705                                asm.next()?;
3706                                asm.data.push(0xDD);
3707                                asm.data.push(0x60);
3708                            }
3709                            Some(Token::Register {
3710                                name: RegisterName::C,
3711                                ..
3712                            }) => {
3713                                asm.next()?;
3714                                asm.data.push(0xDD);
3715                                asm.data.push(0x61);
3716                            }
3717                            Some(Token::Register {
3718                                name: RegisterName::D,
3719                                ..
3720                            }) => {
3721                                asm.next()?;
3722                                asm.data.push(0xDD);
3723                                asm.data.push(0x62);
3724                            }
3725                            Some(Token::Register {
3726                                name: RegisterName::E,
3727                                ..
3728                            }) => {
3729                                asm.next()?;
3730                                asm.data.push(0xDD);
3731                                asm.data.push(0x63);
3732                            }
3733                            Some(Token::Register {
3734                                name: RegisterName::IXH,
3735                                ..
3736                            }) => {
3737                                asm.next()?;
3738                                asm.data.push(0xDD);
3739                                asm.data.push(0x64);
3740                            }
3741                            Some(Token::Register {
3742                                name: RegisterName::IXL,
3743                                ..
3744                            }) => {
3745                                asm.next()?;
3746                                asm.data.push(0xDD);
3747                                asm.data.push(0x65);
3748                            }
3749                            Some(_) => {
3750                                asm.data.push(0xDD);
3751                                asm.data.push(0x26);
3752                                let (loc, expr) = asm.expr()?;
3753                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3754                                    if (value as u32) > (u8::MAX as u32) {
3755                                        return asm_err!(
3756                                            loc,
3757                                            "Expression result ({value}) will not fit in a byte"
3758                                        );
3759                                    }
3760                                    asm.data.push(value as u8);
3761                                } else {
3762                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3763                                    asm.data.push(0);
3764                                }
3765                            }
3766                        }
3767                    }
3768
3769                    Some(Token::Register {
3770                        name: RegisterName::IXL,
3771                        ..
3772                    }) => {
3773                        asm.expect_symbol(SymbolName::Comma)?;
3774                        match asm.peek()? {
3775                            None => return asm.end_of_input_err(),
3776                            Some(Token::Register {
3777                                name: RegisterName::A,
3778                                ..
3779                            }) => {
3780                                asm.next()?;
3781                                asm.data.push(0xDD);
3782                                asm.data.push(0x6F);
3783                            }
3784                            Some(Token::Register {
3785                                name: RegisterName::B,
3786                                ..
3787                            }) => {
3788                                asm.next()?;
3789                                asm.data.push(0xDD);
3790                                asm.data.push(0x68);
3791                            }
3792                            Some(Token::Register {
3793                                name: RegisterName::C,
3794                                ..
3795                            }) => {
3796                                asm.next()?;
3797                                asm.data.push(0xDD);
3798                                asm.data.push(0x69);
3799                            }
3800                            Some(Token::Register {
3801                                name: RegisterName::D,
3802                                ..
3803                            }) => {
3804                                asm.next()?;
3805                                asm.data.push(0xDD);
3806                                asm.data.push(0x6A);
3807                            }
3808                            Some(Token::Register {
3809                                name: RegisterName::E,
3810                                ..
3811                            }) => {
3812                                asm.next()?;
3813                                asm.data.push(0xDD);
3814                                asm.data.push(0x6B);
3815                            }
3816                            Some(Token::Register {
3817                                name: RegisterName::IXH,
3818                                ..
3819                            }) => {
3820                                asm.next()?;
3821                                asm.data.push(0xDD);
3822                                asm.data.push(0x6C);
3823                            }
3824                            Some(Token::Register {
3825                                name: RegisterName::IXL,
3826                                ..
3827                            }) => {
3828                                asm.next()?;
3829                                asm.data.push(0xDD);
3830                                asm.data.push(0x6D);
3831                            }
3832                            Some(_) => {
3833                                asm.data.push(0xDD);
3834                                asm.data.push(0x2E);
3835                                let (loc, expr) = asm.expr()?;
3836                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3837                                    if (value as u32) > (u8::MAX as u32) {
3838                                        return asm_err!(
3839                                            loc,
3840                                            "Expression result ({value}) will not fit in a byte"
3841                                        );
3842                                    }
3843                                    asm.data.push(value as u8);
3844                                } else {
3845                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3846                                    asm.data.push(0);
3847                                }
3848                            }
3849                        }
3850                    }
3851
3852                    Some(Token::Register {
3853                        name: RegisterName::IYH,
3854                        ..
3855                    }) => {
3856                        asm.expect_symbol(SymbolName::Comma)?;
3857                        match asm.peek()? {
3858                            None => return asm.end_of_input_err(),
3859                            Some(Token::Register {
3860                                name: RegisterName::A,
3861                                ..
3862                            }) => {
3863                                asm.next()?;
3864                                asm.data.push(0xFD);
3865                                asm.data.push(0x67);
3866                            }
3867                            Some(Token::Register {
3868                                name: RegisterName::B,
3869                                ..
3870                            }) => {
3871                                asm.next()?;
3872                                asm.data.push(0xFD);
3873                                asm.data.push(0x60);
3874                            }
3875                            Some(Token::Register {
3876                                name: RegisterName::C,
3877                                ..
3878                            }) => {
3879                                asm.next()?;
3880                                asm.data.push(0xFD);
3881                                asm.data.push(0x61);
3882                            }
3883                            Some(Token::Register {
3884                                name: RegisterName::D,
3885                                ..
3886                            }) => {
3887                                asm.next()?;
3888                                asm.data.push(0xFD);
3889                                asm.data.push(0x62);
3890                            }
3891                            Some(Token::Register {
3892                                name: RegisterName::E,
3893                                ..
3894                            }) => {
3895                                asm.next()?;
3896                                asm.data.push(0xFD);
3897                                asm.data.push(0x63);
3898                            }
3899                            Some(Token::Register {
3900                                name: RegisterName::IYH,
3901                                ..
3902                            }) => {
3903                                asm.next()?;
3904                                asm.data.push(0xFD);
3905                                asm.data.push(0x64);
3906                            }
3907                            Some(Token::Register {
3908                                name: RegisterName::IYL,
3909                                ..
3910                            }) => {
3911                                asm.next()?;
3912                                asm.data.push(0xFD);
3913                                asm.data.push(0x65);
3914                            }
3915                            Some(_) => {
3916                                asm.data.push(0xFD);
3917                                asm.data.push(0x26);
3918                                let (loc, expr) = asm.expr()?;
3919                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
3920                                    if (value as u32) > (u8::MAX as u32) {
3921                                        return asm_err!(
3922                                            loc,
3923                                            "Expression result ({value}) will not fit in a byte"
3924                                        );
3925                                    }
3926                                    asm.data.push(value as u8);
3927                                } else {
3928                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
3929                                    asm.data.push(0);
3930                                }
3931                            }
3932                        }
3933                    }
3934
3935                    Some(Token::Register {
3936                        name: RegisterName::IYL,
3937                        ..
3938                    }) => {
3939                        asm.expect_symbol(SymbolName::Comma)?;
3940                        match asm.peek()? {
3941                            None => return asm.end_of_input_err(),
3942                            Some(Token::Register {
3943                                name: RegisterName::A,
3944                                ..
3945                            }) => {
3946                                asm.next()?;
3947                                asm.data.push(0xFD);
3948                                asm.data.push(0x6F);
3949                            }
3950                            Some(Token::Register {
3951                                name: RegisterName::B,
3952                                ..
3953                            }) => {
3954                                asm.next()?;
3955                                asm.data.push(0xFD);
3956                                asm.data.push(0x68);
3957                            }
3958                            Some(Token::Register {
3959                                name: RegisterName::C,
3960                                ..
3961                            }) => {
3962                                asm.next()?;
3963                                asm.data.push(0xFD);
3964                                asm.data.push(0x69);
3965                            }
3966                            Some(Token::Register {
3967                                name: RegisterName::D,
3968                                ..
3969                            }) => {
3970                                asm.next()?;
3971                                asm.data.push(0xFD);
3972                                asm.data.push(0x6A);
3973                            }
3974                            Some(Token::Register {
3975                                name: RegisterName::E,
3976                                ..
3977                            }) => {
3978                                asm.next()?;
3979                                asm.data.push(0xFD);
3980                                asm.data.push(0x6B);
3981                            }
3982                            Some(Token::Register {
3983                                name: RegisterName::IYH,
3984                                ..
3985                            }) => {
3986                                asm.next()?;
3987                                asm.data.push(0xFD);
3988                                asm.data.push(0x6C);
3989                            }
3990                            Some(Token::Register {
3991                                name: RegisterName::IYL,
3992                                ..
3993                            }) => {
3994                                asm.next()?;
3995                                asm.data.push(0xFD);
3996                                asm.data.push(0x6D);
3997                            }
3998                            Some(_) => {
3999                                asm.data.push(0xFD);
4000                                asm.data.push(0x2E);
4001                                let (loc, expr) = asm.expr()?;
4002                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4003                                    if (value as u32) > (u8::MAX as u32) {
4004                                        return asm_err!(
4005                                            loc,
4006                                            "Expression result ({value}) will not fit in a byte"
4007                                        );
4008                                    }
4009                                    asm.data.push(value as u8);
4010                                } else {
4011                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
4012                                    asm.data.push(0);
4013                                }
4014                            }
4015                        }
4016                    }
4017
4018                    Some(Token::Register {
4019                        name: RegisterName::R,
4020                        ..
4021                    }) => {
4022                        asm.data.push(0xED);
4023                        asm.data.push(0x4F);
4024                        asm.expect_symbol(SymbolName::Comma)?;
4025                        asm.expect_register(RegisterName::A)?;
4026                    }
4027
4028                    Some(Token::Register {
4029                        name: RegisterName::I,
4030                        ..
4031                    }) => {
4032                        asm.data.push(0xED);
4033                        asm.data.push(0x47);
4034                        asm.expect_symbol(SymbolName::Comma)?;
4035                        asm.expect_register(RegisterName::A)?;
4036                    }
4037
4038                    Some(Token::Register {
4039                        name: RegisterName::SP,
4040                        ..
4041                    }) => {
4042                        asm.expect_symbol(SymbolName::Comma)?;
4043                        match asm.peek()? {
4044                            None => return asm.end_of_input_err(),
4045                            Some(Token::Register {
4046                                name: RegisterName::HL,
4047                                ..
4048                            }) => {
4049                                asm.next()?;
4050                                asm.data.push(0xF9);
4051                            }
4052                            Some(Token::Register {
4053                                name: RegisterName::IX,
4054                                ..
4055                            }) => {
4056                                asm.next()?;
4057                                asm.data.push(0xDD);
4058                                asm.data.push(0xF9);
4059                            }
4060                            Some(Token::Register {
4061                                name: RegisterName::IY,
4062                                ..
4063                            }) => {
4064                                asm.next()?;
4065                                asm.data.push(0xFD);
4066                                asm.data.push(0xF9);
4067                            }
4068                            Some(_) => {
4069                                let indirect = matches!(
4070                                    asm.peek()?,
4071                                    Some(Token::Symbol {
4072                                        name: SymbolName::ParenOpen,
4073                                        ..
4074                                    })
4075                                );
4076                                if indirect {
4077                                    asm.next()?;
4078                                    asm.data.push(0xED);
4079                                    asm.data.push(0x7B);
4080                                } else {
4081                                    asm.data.push(0x31);
4082                                }
4083                                let (loc, expr) = asm.expr()?;
4084                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4085                                    if (value as u32) > (u16::MAX as u32) {
4086                                        return asm_err!(
4087                                            loc,
4088                                            "Expression result ({value}) will not fit in a word"
4089                                        );
4090                                    }
4091                                    asm.data.extend_from_slice(&(value as u16).to_le_bytes());
4092                                } else {
4093                                    asm.links.push(Link::word(loc, asm.data.len(), expr));
4094                                    asm.data.push(0);
4095                                    asm.data.push(0);
4096                                }
4097                                if indirect {
4098                                    asm.expect_symbol(SymbolName::ParenClose)?;
4099                                }
4100                            }
4101                        }
4102                    }
4103
4104                    Some(Token::Register {
4105                        name: RegisterName::BC,
4106                        ..
4107                    }) => {
4108                        asm.expect_symbol(SymbolName::Comma)?;
4109                        let indirect = matches!(
4110                            asm.peek()?,
4111                            Some(Token::Symbol {
4112                                name: SymbolName::ParenOpen,
4113                                ..
4114                            })
4115                        );
4116                        if indirect {
4117                            asm.next()?;
4118                            asm.data.push(0xED);
4119                            asm.data.push(0x4B);
4120                        } else {
4121                            asm.data.push(0x01);
4122                        }
4123                        let (loc, expr) = asm.expr()?;
4124                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4125                            if (value as u32) > (u16::MAX as u32) {
4126                                return asm_err!(
4127                                    loc,
4128                                    "Expression result ({value}) will not fit in a word"
4129                                );
4130                            }
4131                            asm.data.extend_from_slice(&(value as u16).to_le_bytes());
4132                        } else {
4133                            asm.links.push(Link::word(loc, asm.data.len(), expr));
4134                            asm.data.push(0);
4135                            asm.data.push(0);
4136                        }
4137                        if indirect {
4138                            asm.expect_symbol(SymbolName::ParenClose)?;
4139                        }
4140                    }
4141
4142                    Some(Token::Register {
4143                        name: RegisterName::DE,
4144                        ..
4145                    }) => {
4146                        asm.expect_symbol(SymbolName::Comma)?;
4147                        let indirect = matches!(
4148                            asm.peek()?,
4149                            Some(Token::Symbol {
4150                                name: SymbolName::ParenOpen,
4151                                ..
4152                            })
4153                        );
4154                        if indirect {
4155                            asm.next()?;
4156                            asm.data.push(0xED);
4157                            asm.data.push(0x5B);
4158                        } else {
4159                            asm.data.push(0x11);
4160                        }
4161                        let (loc, expr) = asm.expr()?;
4162                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4163                            if (value as u32) > (u16::MAX as u32) {
4164                                return asm_err!(
4165                                    loc,
4166                                    "Expression result ({value}) will not fit in a word"
4167                                );
4168                            }
4169                            asm.data.extend_from_slice(&(value as u16).to_le_bytes());
4170                        } else {
4171                            asm.links.push(Link::word(loc, asm.data.len(), expr));
4172                            asm.data.push(0);
4173                            asm.data.push(0);
4174                        }
4175                        if indirect {
4176                            asm.expect_symbol(SymbolName::ParenClose)?;
4177                        }
4178                    }
4179
4180                    Some(Token::Register {
4181                        name: RegisterName::HL,
4182                        ..
4183                    }) => {
4184                        asm.expect_symbol(SymbolName::Comma)?;
4185                        let indirect = matches!(
4186                            asm.peek()?,
4187                            Some(Token::Symbol {
4188                                name: SymbolName::ParenOpen,
4189                                ..
4190                            })
4191                        );
4192                        if indirect {
4193                            asm.next()?;
4194                            asm.data.push(0x2A);
4195                        } else {
4196                            asm.data.push(0x21);
4197                        }
4198                        let (loc, expr) = asm.expr()?;
4199                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4200                            if (value as u32) > (u16::MAX as u32) {
4201                                return asm_err!(
4202                                    loc,
4203                                    "Expression result ({value}) will not fit in a word"
4204                                );
4205                            }
4206                            asm.data.extend_from_slice(&(value as u16).to_le_bytes());
4207                        } else {
4208                            asm.links.push(Link::word(loc, asm.data.len(), expr));
4209                            asm.data.push(0);
4210                            asm.data.push(0);
4211                        }
4212                        if indirect {
4213                            asm.expect_symbol(SymbolName::ParenClose)?;
4214                        }
4215                    }
4216
4217                    Some(Token::Register {
4218                        name: RegisterName::IX,
4219                        ..
4220                    }) => {
4221                        asm.expect_symbol(SymbolName::Comma)?;
4222                        asm.data.push(0xDD);
4223                        let indirect = matches!(
4224                            asm.peek()?,
4225                            Some(Token::Symbol {
4226                                name: SymbolName::ParenOpen,
4227                                ..
4228                            })
4229                        );
4230                        if indirect {
4231                            asm.next()?;
4232                            asm.data.push(0x2A);
4233                        } else {
4234                            asm.data.push(0x21);
4235                        }
4236                        let (loc, expr) = asm.expr()?;
4237                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4238                            if (value as u32) > (u16::MAX as u32) {
4239                                return asm_err!(
4240                                    loc,
4241                                    "Expression result ({value}) will not fit in a word"
4242                                );
4243                            }
4244                            asm.data.extend_from_slice(&(value as u16).to_le_bytes());
4245                        } else {
4246                            asm.links.push(Link::word(loc, asm.data.len(), expr));
4247                            asm.data.push(0);
4248                            asm.data.push(0);
4249                        }
4250                        if indirect {
4251                            asm.expect_symbol(SymbolName::ParenClose)?;
4252                        }
4253                    }
4254
4255                    Some(Token::Register {
4256                        name: RegisterName::IY,
4257                        ..
4258                    }) => {
4259                        asm.expect_symbol(SymbolName::Comma)?;
4260                        asm.data.push(0xFD);
4261                        let indirect = matches!(
4262                            asm.peek()?,
4263                            Some(Token::Symbol {
4264                                name: SymbolName::ParenOpen,
4265                                ..
4266                            })
4267                        );
4268                        if indirect {
4269                            asm.next()?;
4270                            asm.data.push(0x2A);
4271                        } else {
4272                            asm.data.push(0x21);
4273                        }
4274                        let (loc, expr) = asm.expr()?;
4275                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4276                            if (value as u32) > (u16::MAX as u32) {
4277                                return asm_err!(
4278                                    loc,
4279                                    "Expression result ({value}) will not fit in a word"
4280                                );
4281                            }
4282                            asm.data.extend_from_slice(&(value as u16).to_le_bytes());
4283                        } else {
4284                            asm.links.push(Link::word(loc, asm.data.len(), expr));
4285                            asm.data.push(0);
4286                            asm.data.push(0);
4287                        }
4288                        if indirect {
4289                            asm.expect_symbol(SymbolName::ParenClose)?;
4290                        }
4291                    }
4292
4293                    Some(Token::Symbol {
4294                        name: SymbolName::ParenOpen,
4295                        ..
4296                    }) => match asm.peek()? {
4297                        None => return asm.end_of_input_err(),
4298                        Some(Token::Register {
4299                            name: RegisterName::BC,
4300                            ..
4301                        }) => {
4302                            asm.next()?;
4303                            asm.expect_symbol(SymbolName::ParenClose)?;
4304                            asm.expect_symbol(SymbolName::Comma)?;
4305                            asm.expect_register(RegisterName::A)?;
4306                            asm.data.push(0x02);
4307                        }
4308                        Some(Token::Register {
4309                            name: RegisterName::DE,
4310                            ..
4311                        }) => {
4312                            asm.next()?;
4313                            asm.expect_symbol(SymbolName::ParenClose)?;
4314                            asm.expect_symbol(SymbolName::Comma)?;
4315                            asm.expect_register(RegisterName::A)?;
4316                            asm.data.push(0x12);
4317                        }
4318                        Some(Token::Register {
4319                            name: RegisterName::HL,
4320                            ..
4321                        }) => {
4322                            asm.next()?;
4323                            asm.expect_symbol(SymbolName::ParenClose)?;
4324                            asm.expect_symbol(SymbolName::Comma)?;
4325                            match asm.peek()? {
4326                                None => return asm.end_of_input_err(),
4327                                Some(Token::Register {
4328                                    name: RegisterName::A,
4329                                    ..
4330                                }) => {
4331                                    asm.next()?;
4332                                    asm.data.push(0x77);
4333                                }
4334                                Some(Token::Register {
4335                                    name: RegisterName::B,
4336                                    ..
4337                                }) => {
4338                                    asm.next()?;
4339                                    asm.data.push(0x70);
4340                                }
4341                                Some(Token::Register {
4342                                    name: RegisterName::C,
4343                                    ..
4344                                }) => {
4345                                    asm.next()?;
4346                                    asm.data.push(0x71);
4347                                }
4348                                Some(Token::Register {
4349                                    name: RegisterName::D,
4350                                    ..
4351                                }) => {
4352                                    asm.next()?;
4353                                    asm.data.push(0x72);
4354                                }
4355                                Some(Token::Register {
4356                                    name: RegisterName::E,
4357                                    ..
4358                                }) => {
4359                                    asm.next()?;
4360                                    asm.data.push(0x73);
4361                                }
4362                                Some(Token::Register {
4363                                    name: RegisterName::H,
4364                                    ..
4365                                }) => {
4366                                    asm.next()?;
4367                                    asm.data.push(0x74);
4368                                }
4369                                Some(Token::Register {
4370                                    name: RegisterName::L,
4371                                    ..
4372                                }) => {
4373                                    asm.next()?;
4374                                    asm.data.push(0x75);
4375                                }
4376                                Some(_) => {
4377                                    asm.data.push(0x36);
4378                                    let (loc, expr) = asm.expr()?;
4379                                    if let Some(value) =
4380                                        expr.evaluate(&asm.symtab, &asm.str_interner)
4381                                    {
4382                                        if (value as u32) > (u8::MAX as u32) {
4383                                            return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
4384                                        }
4385                                        asm.data.push(value as u8);
4386                                    } else {
4387                                        asm.links.push(Link::byte(loc, asm.data.len(), expr));
4388                                        asm.data.push(0);
4389                                    }
4390                                }
4391                            }
4392                        }
4393                        Some(Token::Register {
4394                            name: RegisterName::IX,
4395                            ..
4396                        }) => {
4397                            asm.next()?;
4398                            asm.expect_symbol(SymbolName::Plus)?;
4399                            asm.data.push(0xDD);
4400                            let (loc, expr) = asm.expr()?;
4401                            let offset = if let Some(value) =
4402                                expr.evaluate(&asm.symtab, &asm.str_interner)
4403                            {
4404                                if (value as u32) > (u8::MAX as u32) {
4405                                    return asm_err!(
4406                                        loc,
4407                                        "Expression result ({value}) will not fit in a byte"
4408                                    );
4409                                }
4410                                value as u8
4411                            } else {
4412                                asm.links.push(Link::byte(loc, asm.data.len() + 1, expr));
4413                                0
4414                            };
4415                            asm.expect_symbol(SymbolName::ParenClose)?;
4416                            asm.expect_symbol(SymbolName::Comma)?;
4417                            match asm.peek()? {
4418                                None => return asm.end_of_input_err(),
4419                                Some(Token::Register {
4420                                    name: RegisterName::A,
4421                                    ..
4422                                }) => {
4423                                    asm.next()?;
4424                                    asm.data.push(0x77);
4425                                    asm.data.push(offset);
4426                                }
4427                                Some(Token::Register {
4428                                    name: RegisterName::B,
4429                                    ..
4430                                }) => {
4431                                    asm.next()?;
4432                                    asm.data.push(0x70);
4433                                    asm.data.push(offset);
4434                                }
4435                                Some(Token::Register {
4436                                    name: RegisterName::C,
4437                                    ..
4438                                }) => {
4439                                    asm.next()?;
4440                                    asm.data.push(0x71);
4441                                    asm.data.push(offset);
4442                                }
4443                                Some(Token::Register {
4444                                    name: RegisterName::D,
4445                                    ..
4446                                }) => {
4447                                    asm.next()?;
4448                                    asm.data.push(0x72);
4449                                    asm.data.push(offset);
4450                                }
4451                                Some(Token::Register {
4452                                    name: RegisterName::E,
4453                                    ..
4454                                }) => {
4455                                    asm.next()?;
4456                                    asm.data.push(0x73);
4457                                    asm.data.push(offset);
4458                                }
4459                                Some(Token::Register {
4460                                    name: RegisterName::H,
4461                                    ..
4462                                }) => {
4463                                    asm.next()?;
4464                                    asm.data.push(0x74);
4465                                    asm.data.push(offset);
4466                                }
4467                                Some(Token::Register {
4468                                    name: RegisterName::L,
4469                                    ..
4470                                }) => {
4471                                    asm.next()?;
4472                                    asm.data.push(0x75);
4473                                    asm.data.push(offset);
4474                                }
4475                                Some(_) => {
4476                                    asm.data.push(0x36);
4477                                    asm.data.push(offset);
4478                                    let (loc, expr) = asm.expr()?;
4479                                    if let Some(value) =
4480                                        expr.evaluate(&asm.symtab, &asm.str_interner)
4481                                    {
4482                                        if (value as u32) > (u8::MAX as u32) {
4483                                            return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
4484                                        }
4485                                        asm.data.push(value as u8);
4486                                    } else {
4487                                        asm.links.push(Link::byte(loc, asm.data.len(), expr));
4488                                        asm.data.push(0);
4489                                    }
4490                                }
4491                            }
4492                        }
4493                        Some(Token::Register {
4494                            name: RegisterName::IY,
4495                            ..
4496                        }) => {
4497                            asm.next()?;
4498                            asm.expect_symbol(SymbolName::Plus)?;
4499                            asm.data.push(0xFD);
4500                            let (loc, expr) = asm.expr()?;
4501                            let offset = if let Some(value) =
4502                                expr.evaluate(&asm.symtab, &asm.str_interner)
4503                            {
4504                                if (value as u32) > (u8::MAX as u32) {
4505                                    return asm_err!(
4506                                        loc,
4507                                        "Expression result ({value}) will not fit in a byte"
4508                                    );
4509                                }
4510                                value as u8
4511                            } else {
4512                                asm.links.push(Link::byte(loc, asm.data.len() + 1, expr));
4513                                0
4514                            };
4515                            asm.expect_symbol(SymbolName::ParenClose)?;
4516                            asm.expect_symbol(SymbolName::Comma)?;
4517                            match asm.peek()? {
4518                                None => return asm.end_of_input_err(),
4519                                Some(Token::Register {
4520                                    name: RegisterName::A,
4521                                    ..
4522                                }) => {
4523                                    asm.next()?;
4524                                    asm.data.push(0x77);
4525                                    asm.data.push(offset);
4526                                }
4527                                Some(Token::Register {
4528                                    name: RegisterName::B,
4529                                    ..
4530                                }) => {
4531                                    asm.next()?;
4532                                    asm.data.push(0x70);
4533                                    asm.data.push(offset);
4534                                }
4535                                Some(Token::Register {
4536                                    name: RegisterName::C,
4537                                    ..
4538                                }) => {
4539                                    asm.next()?;
4540                                    asm.data.push(0x71);
4541                                    asm.data.push(offset);
4542                                }
4543                                Some(Token::Register {
4544                                    name: RegisterName::D,
4545                                    ..
4546                                }) => {
4547                                    asm.next()?;
4548                                    asm.data.push(0x72);
4549                                    asm.data.push(offset);
4550                                }
4551                                Some(Token::Register {
4552                                    name: RegisterName::E,
4553                                    ..
4554                                }) => {
4555                                    asm.next()?;
4556                                    asm.data.push(0x73);
4557                                    asm.data.push(offset);
4558                                }
4559                                Some(Token::Register {
4560                                    name: RegisterName::H,
4561                                    ..
4562                                }) => {
4563                                    asm.next()?;
4564                                    asm.data.push(0x74);
4565                                    asm.data.push(offset);
4566                                }
4567                                Some(Token::Register {
4568                                    name: RegisterName::L,
4569                                    ..
4570                                }) => {
4571                                    asm.next()?;
4572                                    asm.data.push(0x75);
4573                                    asm.data.push(offset);
4574                                }
4575                                Some(_) => {
4576                                    asm.data.push(0x36);
4577                                    asm.data.push(offset);
4578                                    let (loc, expr) = asm.expr()?;
4579                                    if let Some(value) =
4580                                        expr.evaluate(&asm.symtab, &asm.str_interner)
4581                                    {
4582                                        if (value as u32) > (u8::MAX as u32) {
4583                                            return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
4584                                        }
4585                                        asm.data.push(value as u8);
4586                                    } else {
4587                                        asm.links.push(Link::byte(loc, asm.data.len(), expr));
4588                                        asm.data.push(0);
4589                                    }
4590                                }
4591                            }
4592                        }
4593                        Some(_) => {
4594                            let (loc, expr) = asm.expr()?;
4595                            asm.expect_symbol(SymbolName::ParenClose)?;
4596                            asm.expect_symbol(SymbolName::Comma)?;
4597                            match asm.next()? {
4598                                None => return asm.end_of_input_err(),
4599                                Some(Token::Register { name: RegisterName::A, .. }) => {
4600                                    asm.data.push(0x32);
4601                                }
4602                                Some(Token::Register { name: RegisterName::BC, .. }) => {
4603                                    asm.data.push(0xED);
4604                                    asm.data.push(0x43);
4605                                }
4606                                Some(Token::Register { name: RegisterName::DE, .. }) => {
4607                                    asm.data.push(0xED);
4608                                    asm.data.push(0x53);
4609                                }
4610                                Some(Token::Register { name: RegisterName::HL, .. }) => {
4611                                    asm.data.push(0x22);
4612                                }
4613                                Some(Token::Register { name: RegisterName::SP, .. }) => {
4614                                    asm.data.push(0xED);
4615                                    asm.data.push(0x73);
4616                                }
4617                                Some(Token::Register { name: RegisterName::IX, .. }) => {
4618                                    asm.data.push(0xDD);
4619                                    asm.data.push(0x22);
4620                                }
4621                                Some(Token::Register { name: RegisterName::IY, .. }) => {
4622                                    asm.data.push(0xFD);
4623                                    asm.data.push(0x22);
4624                                }
4625                                Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected registers \"a\", \"bc\", \"de\", \"hl\", \"sp\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
4626                            }
4627                            if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4628                                if (value as u32) > (u16::MAX as u32) {
4629                                    return asm_err!(
4630                                        loc,
4631                                        "Expression result ({value}) will not fit in a word"
4632                                    );
4633                                }
4634                                asm.data.extend_from_slice(&(value as u16).to_le_bytes());
4635                            } else {
4636                                asm.links.push(Link::word(loc, asm.data.len(), expr));
4637                                asm.data.push(0);
4638                                asm.data.push(0);
4639                            }
4640                        }
4641                    },
4642
4643                    Some(tok) => {
4644                        return asm_err!(
4645                            tok.loc(),
4646                            "Unexpected {}, expected a valid \"ld\" destination",
4647                            tok.as_display(&asm.str_interner)
4648                        )
4649                    }
4650                }
4651            }
4652
4653            OperationName::Ldd => {
4654                asm.next()?;
4655                asm.data.push(0xED);
4656                asm.data.push(0xA8);
4657            }
4658
4659            OperationName::Lddr => {
4660                asm.next()?;
4661                asm.data.push(0xED);
4662                asm.data.push(0xB8);
4663            }
4664
4665            OperationName::Ldi => {
4666                asm.next()?;
4667                asm.data.push(0xED);
4668                asm.data.push(0xA0);
4669            }
4670
4671            OperationName::Ldir => {
4672                asm.next()?;
4673                asm.data.push(0xED);
4674                asm.data.push(0xB0);
4675            }
4676
4677            OperationName::Neg => {
4678                asm.next()?;
4679                asm.data.push(0xED);
4680                asm.data.push(0x44);
4681            }
4682
4683            OperationName::Nop => {
4684                asm.next()?;
4685                asm.data.push(0x00);
4686            }
4687
4688            OperationName::Or => {
4689                asm.next()?;
4690                match asm.peek()? {
4691                    None => return asm.end_of_input_err(),
4692                    Some(Token::Register {
4693                        name: RegisterName::A,
4694                        ..
4695                    }) => {
4696                        asm.next()?;
4697                        asm.data.push(0xB7);
4698                    }
4699
4700                    Some(Token::Register {
4701                        name: RegisterName::B,
4702                        ..
4703                    }) => {
4704                        asm.next()?;
4705                        asm.data.push(0xB0);
4706                    }
4707
4708                    Some(Token::Register {
4709                        name: RegisterName::C,
4710                        ..
4711                    }) => {
4712                        asm.next()?;
4713                        asm.data.push(0xB1);
4714                    }
4715
4716                    Some(Token::Register {
4717                        name: RegisterName::D,
4718                        ..
4719                    }) => {
4720                        asm.next()?;
4721                        asm.data.push(0xB2);
4722                    }
4723
4724                    Some(Token::Register {
4725                        name: RegisterName::E,
4726                        ..
4727                    }) => {
4728                        asm.next()?;
4729                        asm.data.push(0xB3);
4730                    }
4731
4732                    Some(Token::Register {
4733                        name: RegisterName::H,
4734                        ..
4735                    }) => {
4736                        asm.next()?;
4737                        asm.data.push(0xB4);
4738                    }
4739
4740                    Some(Token::Register {
4741                        name: RegisterName::L,
4742                        ..
4743                    }) => {
4744                        asm.next()?;
4745                        asm.data.push(0xB5);
4746                    }
4747
4748                    Some(Token::Register {
4749                        name: RegisterName::IXH,
4750                        ..
4751                    }) => {
4752                        asm.next()?;
4753                        asm.data.push(0xDD);
4754                        asm.data.push(0xB4);
4755                    }
4756
4757                    Some(Token::Register {
4758                        name: RegisterName::IXL,
4759                        ..
4760                    }) => {
4761                        asm.next()?;
4762                        asm.data.push(0xDD);
4763                        asm.data.push(0xB5);
4764                    }
4765
4766                    Some(Token::Register {
4767                        name: RegisterName::IYH,
4768                        ..
4769                    }) => {
4770                        asm.next()?;
4771                        asm.data.push(0xFD);
4772                        asm.data.push(0xB4);
4773                    }
4774
4775                    Some(Token::Register {
4776                        name: RegisterName::IYL,
4777                        ..
4778                    }) => {
4779                        asm.next()?;
4780                        asm.data.push(0xFD);
4781                        asm.data.push(0xB5);
4782                    }
4783
4784                    Some(Token::Symbol {
4785                        name: SymbolName::ParenOpen,
4786                        ..
4787                    }) => {
4788                        asm.next()?;
4789                        match asm.next()? {
4790                            None => return asm.end_of_input_err(),
4791                            Some(Token::Register {
4792                                name: RegisterName::HL,
4793                                ..
4794                            }) => {
4795                                asm.data.push(0xB6);
4796                                asm.expect_symbol(SymbolName::ParenClose)?;
4797                            }
4798
4799                            Some(Token::Register {
4800                                name: RegisterName::IX,
4801                                ..
4802                            }) => {
4803                                asm.expect_symbol(SymbolName::Plus)?;
4804                                asm.data.push(0xDD);
4805                                asm.data.push(0xB6);
4806                                let (loc, expr) = asm.expr()?;
4807                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4808                                    if (value as u32) > (u8::MAX as u32) {
4809                                        return asm_err!(
4810                                            loc,
4811                                            "Expression result ({value}) will not fit in a byte"
4812                                        );
4813                                    }
4814                                    asm.data.push(value as u8);
4815                                } else {
4816                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
4817                                    asm.data.push(0);
4818                                }
4819                                asm.expect_symbol(SymbolName::ParenClose)?;
4820                            }
4821
4822                            Some(Token::Register {
4823                                name: RegisterName::IY,
4824                                ..
4825                            }) => {
4826                                asm.expect_symbol(SymbolName::Plus)?;
4827                                asm.data.push(0xFD);
4828                                asm.data.push(0xB6);
4829                                let (loc, expr) = asm.expr()?;
4830                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4831                                    if (value as u32) > (u8::MAX as u32) {
4832                                        return asm_err!(
4833                                            loc,
4834                                            "Expression result ({value}) will not fit in a byte"
4835                                        );
4836                                    }
4837                                    asm.data.push(value as u8);
4838                                } else {
4839                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
4840                                    asm.data.push(0);
4841                                }
4842                                asm.expect_symbol(SymbolName::ParenClose)?;
4843                            }
4844                            Some(tok) => {
4845                                return asm_err!(
4846                                    tok.loc(),
4847                                    "Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",
4848                                    tok.as_display(&asm.str_interner)
4849                                )
4850                            }
4851                        }
4852                    }
4853
4854                    Some(_) => {
4855                        asm.data.push(0xF6);
4856                        let (loc, expr) = asm.expr()?;
4857                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4858                            if (value as u32) > (u8::MAX as u32) {
4859                                return asm_err!(
4860                                    loc,
4861                                    "Expression result ({value}) will not fit in a byte"
4862                                );
4863                            }
4864                            asm.data.push(value as u8);
4865                        } else {
4866                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
4867                            asm.data.push(0);
4868                        }
4869                    }
4870                }
4871            }
4872
4873            OperationName::Otdr => {
4874                asm.next()?;
4875                asm.data.push(0xED);
4876                asm.data.push(0xBB);
4877            }
4878
4879            OperationName::Otir => {
4880                asm.next()?;
4881                asm.data.push(0xED);
4882                asm.data.push(0xB3);
4883            }
4884
4885            OperationName::Out => {
4886                asm.next()?;
4887                asm.expect_symbol(SymbolName::ParenOpen)?;
4888                match asm.peek()? {
4889                    None => return asm.end_of_input_err(),
4890
4891                    Some(Token::Register {
4892                        name: RegisterName::C,
4893                        ..
4894                    }) => {
4895                        asm.next()?;
4896                        asm.expect_symbol(SymbolName::ParenClose)?;
4897                        asm.expect_symbol(SymbolName::Comma)?;
4898                        asm.data.push(0xED);
4899                        match asm.next()? {
4900                            None => return asm.end_of_input_err(),
4901                            Some(Token::Register {
4902                                name: RegisterName::A,
4903                                ..
4904                            }) => {
4905                                asm.data.push(0x79);
4906                            }
4907                            Some(Token::Register {
4908                                name: RegisterName::B,
4909                                ..
4910                            }) => {
4911                                asm.data.push(0x41);
4912                            }
4913                            Some(Token::Register {
4914                                name: RegisterName::C,
4915                                ..
4916                            }) => {
4917                                asm.data.push(0x49);
4918                            }
4919                            Some(Token::Register {
4920                                name: RegisterName::D,
4921                                ..
4922                            }) => {
4923                                asm.data.push(0x51);
4924                            }
4925                            Some(Token::Register {
4926                                name: RegisterName::E,
4927                                ..
4928                            }) => {
4929                                asm.data.push(0x59);
4930                            }
4931                            Some(Token::Register {
4932                                name: RegisterName::H,
4933                                ..
4934                            }) => {
4935                                asm.data.push(0x61);
4936                            }
4937                            Some(Token::Register {
4938                                name: RegisterName::L,
4939                                ..
4940                            }) => {
4941                                asm.data.push(0x69);
4942                            }
4943                            Some(tok) => {
4944                                return asm_err!(
4945                                    tok.loc(),
4946                                    "Unexpected {}, expected a register",
4947                                    tok.as_display(&asm.str_interner)
4948                                )
4949                            }
4950                        }
4951                    }
4952
4953                    Some(_) => {
4954                        asm.data.push(0xD3);
4955                        let (loc, expr) = asm.expr()?;
4956                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
4957                            if (value as u32) > (u8::MAX as u32) {
4958                                return asm_err!(
4959                                    loc,
4960                                    "Expression result ({value}) will not fit in a byte"
4961                                );
4962                            }
4963                            asm.data.push(value as u8);
4964                        } else {
4965                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
4966                            asm.data.push(0);
4967                        }
4968                        asm.expect_symbol(SymbolName::ParenClose)?;
4969                        asm.expect_symbol(SymbolName::Comma)?;
4970                        asm.expect_register(RegisterName::A)?;
4971                    }
4972                }
4973            }
4974
4975            OperationName::Outd => {
4976                asm.next()?;
4977                asm.data.push(0xED);
4978                asm.data.push(0xAB);
4979            }
4980
4981            OperationName::Outi => {
4982                asm.next()?;
4983                asm.data.push(0xED);
4984                asm.data.push(0xA3);
4985            }
4986
4987            OperationName::Pop => {
4988                asm.next()?;
4989                match asm.next()? {
4990                    None => return asm.end_of_input_err(),
4991                    Some(Token::Register { name: RegisterName::BC, .. }) => {
4992                        asm.data.push(0xC1);
4993                    }
4994                    Some(Token::Register { name: RegisterName::DE, .. }) => {
4995                        asm.data.push(0xD1);
4996                    }
4997                    Some(Token::Register { name: RegisterName::HL, .. }) => {
4998                        asm.data.push(0xE1);
4999                    }
5000                    Some(Token::Register { name: RegisterName::AF, .. }) => {
5001                        asm.data.push(0xF1);
5002                    }
5003                    Some(Token::Register { name: RegisterName::IX, .. }) => {
5004                        asm.data.push(0xDD);
5005                        asm.data.push(0xE1);
5006                    }
5007                    Some(Token::Register { name: RegisterName::IY, .. }) => {
5008                        asm.data.push(0xFD);
5009                        asm.data.push(0xE1);
5010                    }
5011                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected register \"bc\", \"de\", \"hl\", \"af\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
5012                }
5013            }
5014
5015            OperationName::Push => {
5016                asm.next()?;
5017                match asm.next()? {
5018                    None => return asm.end_of_input_err(),
5019                    Some(Token::Register { name: RegisterName::BC, .. }) => {
5020                        asm.data.push(0xC5);
5021                    }
5022                    Some(Token::Register { name: RegisterName::DE, .. }) => {
5023                        asm.data.push(0xD5);
5024                    }
5025                    Some(Token::Register { name: RegisterName::HL, .. }) => {
5026                        asm.data.push(0xE5);
5027                    }
5028                    Some(Token::Register { name: RegisterName::AF, .. }) => {
5029                        asm.data.push(0xF5);
5030                    }
5031                    Some(Token::Register { name: RegisterName::IX, .. }) => {
5032                        asm.data.push(0xDD);
5033                        asm.data.push(0xE5);
5034                    }
5035                    Some(Token::Register { name: RegisterName::IY, .. }) => {
5036                        asm.data.push(0xFD);
5037                        asm.data.push(0xE5);
5038                    }
5039                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected register \"bc\", \"de\", \"hl\", \"af\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
5040                }
5041            }
5042
5043            OperationName::Res => {
5044                asm.next()?;
5045                match asm.const_expr()? {
5046                    (loc, None) => return asm_err!(loc, "Bit index must be immediately solvable"),
5047                    (loc, Some(value)) => {
5048                        if !(0..=7).contains(&value) {
5049                            return asm_err!(loc, "Bit index ({value}) must be between 0 and 7");
5050                        }
5051
5052                        asm.expect_symbol(SymbolName::Comma)?;
5053
5054                        match asm.next()? {
5055                            None => return asm.end_of_input_err(),
5056                            Some(Token::Register {
5057                                name: RegisterName::A,
5058                                ..
5059                            }) => {
5060                                asm.data.push(0xCB);
5061                                asm.data.push(match value {
5062                                    0 => 0x87,
5063                                    1 => 0x8F,
5064                                    2 => 0x97,
5065                                    3 => 0x9F,
5066                                    4 => 0xA7,
5067                                    5 => 0xAF,
5068                                    6 => 0xB7,
5069                                    7 => 0xBF,
5070                                    _ => unreachable!(),
5071                                });
5072                            }
5073
5074                            Some(Token::Register {
5075                                name: RegisterName::B,
5076                                ..
5077                            }) => {
5078                                asm.data.push(0xCB);
5079                                asm.data.push(match value {
5080                                    0 => 0x80,
5081                                    1 => 0x88,
5082                                    2 => 0x90,
5083                                    3 => 0x98,
5084                                    4 => 0xA0,
5085                                    5 => 0xA8,
5086                                    6 => 0xB0,
5087                                    7 => 0xB8,
5088                                    _ => unreachable!(),
5089                                });
5090                            }
5091
5092                            Some(Token::Register {
5093                                name: RegisterName::C,
5094                                ..
5095                            }) => {
5096                                asm.data.push(0xCB);
5097                                asm.data.push(match value {
5098                                    0 => 0x81,
5099                                    1 => 0x89,
5100                                    2 => 0x91,
5101                                    3 => 0x99,
5102                                    4 => 0xA1,
5103                                    5 => 0xA9,
5104                                    6 => 0xB1,
5105                                    7 => 0xB9,
5106                                    _ => unreachable!(),
5107                                });
5108                            }
5109
5110                            Some(Token::Register {
5111                                name: RegisterName::D,
5112                                ..
5113                            }) => {
5114                                asm.data.push(0xCB);
5115                                asm.data.push(match value {
5116                                    0 => 0x82,
5117                                    1 => 0x8A,
5118                                    2 => 0x92,
5119                                    3 => 0x9A,
5120                                    4 => 0xA2,
5121                                    5 => 0xAA,
5122                                    6 => 0xB2,
5123                                    7 => 0xBA,
5124                                    _ => unreachable!(),
5125                                });
5126                            }
5127
5128                            Some(Token::Register {
5129                                name: RegisterName::E,
5130                                ..
5131                            }) => {
5132                                asm.data.push(0xCB);
5133                                asm.data.push(match value {
5134                                    0 => 0x83,
5135                                    1 => 0x8B,
5136                                    2 => 0x93,
5137                                    3 => 0x9B,
5138                                    4 => 0xA3,
5139                                    5 => 0xAB,
5140                                    6 => 0xB3,
5141                                    7 => 0xBB,
5142                                    _ => unreachable!(),
5143                                });
5144                            }
5145
5146                            Some(Token::Register {
5147                                name: RegisterName::H,
5148                                ..
5149                            }) => {
5150                                asm.data.push(0xCB);
5151                                asm.data.push(match value {
5152                                    0 => 0x84,
5153                                    1 => 0x8C,
5154                                    2 => 0x94,
5155                                    3 => 0x9C,
5156                                    4 => 0xA4,
5157                                    5 => 0xAC,
5158                                    6 => 0xB4,
5159                                    7 => 0xBC,
5160                                    _ => unreachable!(),
5161                                });
5162                            }
5163
5164                            Some(Token::Register {
5165                                name: RegisterName::L,
5166                                ..
5167                            }) => {
5168                                asm.data.push(0xCB);
5169                                asm.data.push(match value {
5170                                    0 => 0x85,
5171                                    1 => 0x8D,
5172                                    2 => 0x95,
5173                                    3 => 0x9D,
5174                                    4 => 0xA5,
5175                                    5 => 0xAD,
5176                                    6 => 0xB5,
5177                                    7 => 0xBD,
5178                                    _ => unreachable!(),
5179                                });
5180                            }
5181
5182                            Some(Token::Symbol {
5183                                name: SymbolName::ParenOpen,
5184                                ..
5185                            }) => {
5186                                match asm.next()? {
5187                                    None => return asm.end_of_input_err(),
5188                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
5189                                        asm.data.push(0xCB);
5190                                        asm.data.push(match value {
5191                                            0 => 0x86,
5192                                            1 => 0x8E,
5193                                            2 => 0x96,
5194                                            3 => 0x9E,
5195                                            4 => 0xA6,
5196                                            5 => 0xAE,
5197                                            6 => 0xB6,
5198                                            7 => 0xBE,
5199                                            _ => unreachable!(),
5200                                        });
5201                                    }
5202
5203                                    Some(Token::Register { name: RegisterName::IX, .. }) => {
5204                                        asm.expect_symbol(SymbolName::Plus)?;
5205                                        asm.data.push(0xDD);
5206                                        asm.data.push(0xCB);
5207                                        let (loc, expr) = asm.expr()?;
5208                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5209                                            if (value as u32) > (u8::MAX as u32) {
5210                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
5211                                            }
5212                                            asm.data.push(value as u8);
5213                                        } else {
5214                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
5215                                            asm.data.push(0);
5216                                        }
5217                                        asm.data.push(match value {
5218                                            0 => 0x86,
5219                                            1 => 0x8E,
5220                                            2 => 0x96,
5221                                            3 => 0x9E,
5222                                            4 => 0xA6,
5223                                            5 => 0xAE,
5224                                            6 => 0xB6,
5225                                            7 => 0xBE,
5226                                            _ => unreachable!(),
5227                                        });
5228                                    }
5229
5230                                    Some(Token::Register { name: RegisterName::IY, .. }) => {
5231                                        asm.expect_symbol(SymbolName::Plus)?;
5232                                        asm.data.push(0xFD);
5233                                        asm.data.push(0xCB);
5234                                        let (loc, expr) = asm.expr()?;
5235                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5236                                            if (value as u32) > (u8::MAX as u32) {
5237                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
5238                                            }
5239                                            asm.data.push(value as u8);
5240                                        } else {
5241                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
5242                                            asm.data.push(0);
5243                                        }
5244                                        asm.data.push(match value {
5245                                            0 => 0x86,
5246                                            1 => 0x8E,
5247                                            2 => 0x96,
5248                                            3 => 0x9E,
5249                                            4 => 0xA6,
5250                                            5 => 0xAE,
5251                                            6 => 0xB6,
5252                                            7 => 0xBE,
5253                                            _ => unreachable!(),
5254                                        });
5255                                    }
5256
5257                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
5258                                }
5259                                asm.expect_symbol(SymbolName::ParenClose)?;
5260                            }
5261
5262                            Some(tok) => {
5263                                return asm_err!(
5264                                    tok.loc(),
5265                                    "Unexpected {}, expected a register",
5266                                    tok.as_display(&asm.str_interner)
5267                                )
5268                            }
5269                        }
5270                    }
5271                }
5272            }
5273
5274            OperationName::Ret => {
5275                asm.next()?;
5276                match asm.peek()? {
5277                    None => return asm.end_of_input_err()?,
5278                    Some(Token::Flag {
5279                        name: FlagName::NotZero,
5280                        ..
5281                    }) => {
5282                        asm.next()?;
5283                        asm.data.push(0xC0);
5284                    }
5285                    Some(Token::Flag {
5286                        name: FlagName::Zero,
5287                        ..
5288                    }) => {
5289                        asm.next()?;
5290                        asm.data.push(0xC8);
5291                    }
5292                    Some(Token::Flag {
5293                        name: FlagName::NotCarry,
5294                        ..
5295                    }) => {
5296                        asm.next()?;
5297                        asm.data.push(0xD0);
5298                    }
5299                    Some(Token::Register {
5300                        name: RegisterName::C,
5301                        ..
5302                    }) => {
5303                        asm.next()?;
5304                        asm.data.push(0xD8);
5305                    }
5306                    Some(Token::Flag {
5307                        name: FlagName::ParityOdd,
5308                        ..
5309                    }) => {
5310                        asm.next()?;
5311                        asm.data.push(0xE0);
5312                    }
5313                    Some(Token::Flag {
5314                        name: FlagName::ParityEven,
5315                        ..
5316                    }) => {
5317                        asm.next()?;
5318                        asm.data.push(0xE8);
5319                    }
5320                    Some(Token::Flag {
5321                        name: FlagName::Positive,
5322                        ..
5323                    }) => {
5324                        asm.next()?;
5325                        asm.data.push(0xF0);
5326                    }
5327                    Some(Token::Flag {
5328                        name: FlagName::Negative,
5329                        ..
5330                    }) => {
5331                        asm.next()?;
5332                        asm.data.push(0xF8);
5333                    }
5334                    Some(_) => {
5335                        asm.data.push(0xC9);
5336                    }
5337                }
5338            }
5339
5340            OperationName::Reti => {
5341                asm.next()?;
5342                asm.data.push(0xED);
5343                asm.data.push(0x4D);
5344            }
5345
5346            OperationName::Retn => {
5347                asm.next()?;
5348                asm.data.push(0xED);
5349                asm.data.push(0x45);
5350            }
5351
5352            OperationName::Rl => {
5353                asm.next()?;
5354                match asm.next()? {
5355                    None => return asm.end_of_input_err(),
5356                    Some(Token::Register {
5357                        name: RegisterName::A,
5358                        ..
5359                    }) => {
5360                        asm.data.push(0xCB);
5361                        asm.data.push(0x17);
5362                    }
5363                    Some(Token::Register {
5364                        name: RegisterName::B,
5365                        ..
5366                    }) => {
5367                        asm.data.push(0xCB);
5368                        asm.data.push(0x10);
5369                    }
5370                    Some(Token::Register {
5371                        name: RegisterName::C,
5372                        ..
5373                    }) => {
5374                        asm.data.push(0xCB);
5375                        asm.data.push(0x11);
5376                    }
5377                    Some(Token::Register {
5378                        name: RegisterName::D,
5379                        ..
5380                    }) => {
5381                        asm.data.push(0xCB);
5382                        asm.data.push(0x12);
5383                    }
5384                    Some(Token::Register {
5385                        name: RegisterName::E,
5386                        ..
5387                    }) => {
5388                        asm.data.push(0xCB);
5389                        asm.data.push(0x13);
5390                    }
5391                    Some(Token::Register {
5392                        name: RegisterName::H,
5393                        ..
5394                    }) => {
5395                        asm.data.push(0xCB);
5396                        asm.data.push(0x14);
5397                    }
5398                    Some(Token::Register {
5399                        name: RegisterName::L,
5400                        ..
5401                    }) => {
5402                        asm.data.push(0xCB);
5403                        asm.data.push(0x15);
5404                    }
5405                    Some(Token::Symbol {
5406                        name: SymbolName::ParenOpen,
5407                        ..
5408                    }) => {
5409                        match asm.next()? {
5410                            None => return asm.end_of_input_err(),
5411                            Some(Token::Register {
5412                                name: RegisterName::HL,
5413                                ..
5414                            }) => {
5415                                asm.data.push(0xCB);
5416                                asm.data.push(0x16);
5417                            }
5418                            Some(Token::Register {
5419                                name: RegisterName::IX,
5420                                ..
5421                            }) => {
5422                                asm.expect_symbol(SymbolName::Plus)?;
5423                                asm.data.push(0xDD);
5424                                asm.data.push(0xCB);
5425                                let (loc, expr) = asm.expr()?;
5426                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5427                                    if (value as u32) > (u8::MAX as u32) {
5428                                        return asm_err!(
5429                                            loc,
5430                                            "Expression result ({value}) will not fit in a byte"
5431                                        );
5432                                    }
5433                                    asm.data.push(value as u8);
5434                                } else {
5435                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5436                                    asm.data.push(0);
5437                                }
5438                                asm.data.push(0x16);
5439                            }
5440                            Some(Token::Register {
5441                                name: RegisterName::IY,
5442                                ..
5443                            }) => {
5444                                asm.expect_symbol(SymbolName::Plus)?;
5445                                asm.data.push(0xFD);
5446                                asm.data.push(0xCB);
5447                                let (loc, expr) = asm.expr()?;
5448                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5449                                    if (value as u32) > (u8::MAX as u32) {
5450                                        return asm_err!(
5451                                            loc,
5452                                            "Expression result ({value}) will not fit in a byte"
5453                                        );
5454                                    }
5455                                    asm.data.push(value as u8);
5456                                } else {
5457                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5458                                    asm.data.push(0);
5459                                }
5460                                asm.data.push(0x16);
5461                            }
5462                            Some(tok) => {
5463                                return asm_err!(
5464                                    tok.loc(),
5465                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
5466                                    tok.as_display(&asm.str_interner)
5467                                )
5468                            }
5469                        }
5470                        asm.expect_symbol(SymbolName::ParenClose)?;
5471                    }
5472                    Some(tok) => {
5473                        return asm_err!(
5474                            tok.loc(),
5475                            "Unexpected {}, expected register",
5476                            tok.as_display(&asm.str_interner)
5477                        )
5478                    }
5479                }
5480            }
5481
5482            OperationName::Rla => {
5483                asm.next()?;
5484                asm.data.push(0x17);
5485            }
5486
5487            OperationName::Rlc => {
5488                asm.next()?;
5489                match asm.next()? {
5490                    None => return asm.end_of_input_err(),
5491                    Some(Token::Register {
5492                        name: RegisterName::A,
5493                        ..
5494                    }) => {
5495                        asm.data.push(0xCB);
5496                        asm.data.push(0x07);
5497                    }
5498                    Some(Token::Register {
5499                        name: RegisterName::B,
5500                        ..
5501                    }) => {
5502                        asm.data.push(0xCB);
5503                        asm.data.push(0x00);
5504                    }
5505                    Some(Token::Register {
5506                        name: RegisterName::C,
5507                        ..
5508                    }) => {
5509                        asm.data.push(0xCB);
5510                        asm.data.push(0x01);
5511                    }
5512                    Some(Token::Register {
5513                        name: RegisterName::D,
5514                        ..
5515                    }) => {
5516                        asm.data.push(0xCB);
5517                        asm.data.push(0x02);
5518                    }
5519                    Some(Token::Register {
5520                        name: RegisterName::E,
5521                        ..
5522                    }) => {
5523                        asm.data.push(0xCB);
5524                        asm.data.push(0x03);
5525                    }
5526                    Some(Token::Register {
5527                        name: RegisterName::H,
5528                        ..
5529                    }) => {
5530                        asm.data.push(0xCB);
5531                        asm.data.push(0x04);
5532                    }
5533                    Some(Token::Register {
5534                        name: RegisterName::L,
5535                        ..
5536                    }) => {
5537                        asm.data.push(0xCB);
5538                        asm.data.push(0x05);
5539                    }
5540                    Some(Token::Symbol {
5541                        name: SymbolName::ParenOpen,
5542                        ..
5543                    }) => {
5544                        match asm.next()? {
5545                            None => return asm.end_of_input_err(),
5546                            Some(Token::Register {
5547                                name: RegisterName::HL,
5548                                ..
5549                            }) => {
5550                                asm.data.push(0xCB);
5551                                asm.data.push(0x06);
5552                            }
5553                            Some(Token::Register {
5554                                name: RegisterName::IX,
5555                                ..
5556                            }) => {
5557                                asm.expect_symbol(SymbolName::Plus)?;
5558                                asm.data.push(0xDD);
5559                                asm.data.push(0xCB);
5560                                let (loc, expr) = asm.expr()?;
5561                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5562                                    if (value as u32) > (u8::MAX as u32) {
5563                                        return asm_err!(
5564                                            loc,
5565                                            "Expression result ({value}) will not fit in a byte"
5566                                        );
5567                                    }
5568                                    asm.data.push(value as u8);
5569                                } else {
5570                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5571                                    asm.data.push(0);
5572                                }
5573                                asm.data.push(0x06);
5574                            }
5575                            Some(Token::Register {
5576                                name: RegisterName::IY,
5577                                ..
5578                            }) => {
5579                                asm.expect_symbol(SymbolName::Plus)?;
5580                                asm.data.push(0xFD);
5581                                asm.data.push(0xCB);
5582                                let (loc, expr) = asm.expr()?;
5583                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5584                                    if (value as u32) > (u8::MAX as u32) {
5585                                        return asm_err!(
5586                                            loc,
5587                                            "Expression result ({value}) will not fit in a byte"
5588                                        );
5589                                    }
5590                                    asm.data.push(value as u8);
5591                                } else {
5592                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5593                                    asm.data.push(0);
5594                                }
5595                                asm.data.push(0x06);
5596                            }
5597                            Some(tok) => {
5598                                return asm_err!(
5599                                    tok.loc(),
5600                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
5601                                    tok.as_display(&asm.str_interner)
5602                                )
5603                            }
5604                        }
5605                        asm.expect_symbol(SymbolName::ParenClose)?;
5606                    }
5607                    Some(tok) => {
5608                        return asm_err!(
5609                            tok.loc(),
5610                            "Unexpected {}, expected register",
5611                            tok.as_display(&asm.str_interner)
5612                        )
5613                    }
5614                }
5615            }
5616
5617            OperationName::Rlca => {
5618                asm.next()?;
5619                asm.data.push(0x07);
5620            }
5621
5622            OperationName::Rld => {
5623                asm.next()?;
5624                asm.data.push(0xED);
5625                asm.data.push(0x6F);
5626            }
5627
5628            OperationName::Rr => {
5629                asm.next()?;
5630                match asm.next()? {
5631                    None => return asm.end_of_input_err(),
5632                    Some(Token::Register {
5633                        name: RegisterName::A,
5634                        ..
5635                    }) => {
5636                        asm.data.push(0xCB);
5637                        asm.data.push(0x1F);
5638                    }
5639                    Some(Token::Register {
5640                        name: RegisterName::B,
5641                        ..
5642                    }) => {
5643                        asm.data.push(0xCB);
5644                        asm.data.push(0x18);
5645                    }
5646                    Some(Token::Register {
5647                        name: RegisterName::C,
5648                        ..
5649                    }) => {
5650                        asm.data.push(0xCB);
5651                        asm.data.push(0x19);
5652                    }
5653                    Some(Token::Register {
5654                        name: RegisterName::D,
5655                        ..
5656                    }) => {
5657                        asm.data.push(0xCB);
5658                        asm.data.push(0x1A);
5659                    }
5660                    Some(Token::Register {
5661                        name: RegisterName::E,
5662                        ..
5663                    }) => {
5664                        asm.data.push(0xCB);
5665                        asm.data.push(0x1B);
5666                    }
5667                    Some(Token::Register {
5668                        name: RegisterName::H,
5669                        ..
5670                    }) => {
5671                        asm.data.push(0xCB);
5672                        asm.data.push(0x1C);
5673                    }
5674                    Some(Token::Register {
5675                        name: RegisterName::L,
5676                        ..
5677                    }) => {
5678                        asm.data.push(0xCB);
5679                        asm.data.push(0x1D);
5680                    }
5681                    Some(Token::Symbol {
5682                        name: SymbolName::ParenOpen,
5683                        ..
5684                    }) => {
5685                        match asm.next()? {
5686                            None => return asm.end_of_input_err(),
5687                            Some(Token::Register {
5688                                name: RegisterName::HL,
5689                                ..
5690                            }) => {
5691                                asm.data.push(0xCB);
5692                                asm.data.push(0x1E);
5693                            }
5694                            Some(Token::Register {
5695                                name: RegisterName::IX,
5696                                ..
5697                            }) => {
5698                                asm.expect_symbol(SymbolName::Plus)?;
5699                                asm.data.push(0xDD);
5700                                asm.data.push(0xCB);
5701                                let (loc, expr) = asm.expr()?;
5702                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5703                                    if (value as u32) > (u8::MAX as u32) {
5704                                        return asm_err!(
5705                                            loc,
5706                                            "Expression result ({value}) will not fit in a byte"
5707                                        );
5708                                    }
5709                                    asm.data.push(value as u8);
5710                                } else {
5711                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5712                                    asm.data.push(0);
5713                                }
5714                                asm.data.push(0x1E);
5715                            }
5716                            Some(Token::Register {
5717                                name: RegisterName::IY,
5718                                ..
5719                            }) => {
5720                                asm.expect_symbol(SymbolName::Plus)?;
5721                                asm.data.push(0xFD);
5722                                asm.data.push(0xCB);
5723                                let (loc, expr) = asm.expr()?;
5724                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5725                                    if (value as u32) > (u8::MAX as u32) {
5726                                        return asm_err!(
5727                                            loc,
5728                                            "Expression result ({value}) will not fit in a byte"
5729                                        );
5730                                    }
5731                                    asm.data.push(value as u8);
5732                                } else {
5733                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5734                                    asm.data.push(0);
5735                                }
5736                                asm.data.push(0x1E);
5737                            }
5738                            Some(tok) => {
5739                                return asm_err!(
5740                                    tok.loc(),
5741                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
5742                                    tok.as_display(&asm.str_interner)
5743                                )
5744                            }
5745                        }
5746                        asm.expect_symbol(SymbolName::ParenClose)?;
5747                    }
5748                    Some(tok) => {
5749                        return asm_err!(
5750                            tok.loc(),
5751                            "Unexpected {}, expected register",
5752                            tok.as_display(&asm.str_interner)
5753                        )
5754                    }
5755                }
5756            }
5757
5758            OperationName::Rra => {
5759                asm.next()?;
5760                asm.data.push(0x1F);
5761            }
5762
5763            OperationName::Rrc => {
5764                asm.next()?;
5765                match asm.next()? {
5766                    None => return asm.end_of_input_err(),
5767                    Some(Token::Register {
5768                        name: RegisterName::A,
5769                        ..
5770                    }) => {
5771                        asm.data.push(0xCB);
5772                        asm.data.push(0x0F);
5773                    }
5774                    Some(Token::Register {
5775                        name: RegisterName::B,
5776                        ..
5777                    }) => {
5778                        asm.data.push(0xCB);
5779                        asm.data.push(0x08);
5780                    }
5781                    Some(Token::Register {
5782                        name: RegisterName::C,
5783                        ..
5784                    }) => {
5785                        asm.data.push(0xCB);
5786                        asm.data.push(0x09);
5787                    }
5788                    Some(Token::Register {
5789                        name: RegisterName::D,
5790                        ..
5791                    }) => {
5792                        asm.data.push(0xCB);
5793                        asm.data.push(0x0A);
5794                    }
5795                    Some(Token::Register {
5796                        name: RegisterName::E,
5797                        ..
5798                    }) => {
5799                        asm.data.push(0xCB);
5800                        asm.data.push(0x0B);
5801                    }
5802                    Some(Token::Register {
5803                        name: RegisterName::H,
5804                        ..
5805                    }) => {
5806                        asm.data.push(0xCB);
5807                        asm.data.push(0x0C);
5808                    }
5809                    Some(Token::Register {
5810                        name: RegisterName::L,
5811                        ..
5812                    }) => {
5813                        asm.data.push(0xCB);
5814                        asm.data.push(0x0D);
5815                    }
5816                    Some(Token::Symbol {
5817                        name: SymbolName::ParenOpen,
5818                        ..
5819                    }) => {
5820                        match asm.next()? {
5821                            None => return asm.end_of_input_err(),
5822                            Some(Token::Register {
5823                                name: RegisterName::HL,
5824                                ..
5825                            }) => {
5826                                asm.data.push(0xCB);
5827                                asm.data.push(0x0E);
5828                            }
5829                            Some(Token::Register {
5830                                name: RegisterName::IX,
5831                                ..
5832                            }) => {
5833                                asm.expect_symbol(SymbolName::Plus)?;
5834                                asm.data.push(0xDD);
5835                                asm.data.push(0xCB);
5836                                let (loc, expr) = asm.expr()?;
5837                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5838                                    if (value as u32) > (u8::MAX as u32) {
5839                                        return asm_err!(
5840                                            loc,
5841                                            "Expression result ({value}) will not fit in a byte"
5842                                        );
5843                                    }
5844                                    asm.data.push(value as u8);
5845                                } else {
5846                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5847                                    asm.data.push(0);
5848                                }
5849                                asm.data.push(0x0E);
5850                            }
5851                            Some(Token::Register {
5852                                name: RegisterName::IY,
5853                                ..
5854                            }) => {
5855                                asm.expect_symbol(SymbolName::Plus)?;
5856                                asm.data.push(0xFD);
5857                                asm.data.push(0xCB);
5858                                let (loc, expr) = asm.expr()?;
5859                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
5860                                    if (value as u32) > (u8::MAX as u32) {
5861                                        return asm_err!(
5862                                            loc,
5863                                            "Expression result ({value}) will not fit in a byte"
5864                                        );
5865                                    }
5866                                    asm.data.push(value as u8);
5867                                } else {
5868                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
5869                                    asm.data.push(0);
5870                                }
5871                                asm.data.push(0x0E);
5872                            }
5873                            Some(tok) => {
5874                                return asm_err!(
5875                                    tok.loc(),
5876                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
5877                                    tok.as_display(&asm.str_interner)
5878                                )
5879                            }
5880                        }
5881                        asm.expect_symbol(SymbolName::ParenClose)?;
5882                    }
5883                    Some(tok) => {
5884                        return asm_err!(
5885                            tok.loc(),
5886                            "Unexpected {}, expected register",
5887                            tok.as_display(&asm.str_interner)
5888                        )
5889                    }
5890                }
5891            }
5892
5893            OperationName::Rrca => {
5894                asm.next()?;
5895                asm.data.push(0x0F);
5896            }
5897
5898            OperationName::Rrd => {
5899                asm.next()?;
5900                asm.data.push(0xED);
5901                asm.data.push(0x67);
5902            }
5903
5904            OperationName::Rst => {
5905                asm.next()?;
5906                match asm.const_expr()? {
5907                    (loc, None) => return asm_err!(loc,"The expression following an \"rst\" instruction must be immediately solvable"),
5908                    (loc, Some(value)) => {
5909                        let byte = match value {
5910                            0x00 => 0xC7,
5911                            0x08 => 0xCF,
5912                            0x10 => 0xD7,
5913                            0x18 => 0xDF,
5914                            0x20 => 0xE7,
5915                            0x28 => 0xEF,
5916                            0x30 => 0xF7,
5917                            0x38 => 0xFF,
5918                            _ => return asm_err!(loc,"The \"rst\" value ({value}) is not valid"),
5919                        };
5920                        asm.data.push(byte);
5921                    }
5922                }
5923            }
5924
5925            OperationName::Sbc => {
5926                asm.next()?;
5927                match asm.next()? {
5928                    None => return asm.end_of_input_err(),
5929                    Some(Token::Register {
5930                        name: RegisterName::A,
5931                        ..
5932                    }) => {
5933                        asm.expect_symbol(SymbolName::Comma)?;
5934
5935                        match asm.peek()? {
5936                            None => return asm.end_of_input_err(),
5937                            Some(Token::Register {
5938                                name: RegisterName::A,
5939                                ..
5940                            }) => {
5941                                asm.next()?;
5942                                asm.data.push(0x9F);
5943                            }
5944
5945                            Some(Token::Register {
5946                                name: RegisterName::B,
5947                                ..
5948                            }) => {
5949                                asm.next()?;
5950                                asm.data.push(0x98);
5951                            }
5952
5953                            Some(Token::Register {
5954                                name: RegisterName::C,
5955                                ..
5956                            }) => {
5957                                asm.next()?;
5958                                asm.data.push(0x99);
5959                            }
5960
5961                            Some(Token::Register {
5962                                name: RegisterName::D,
5963                                ..
5964                            }) => {
5965                                asm.next()?;
5966                                asm.data.push(0x9A);
5967                            }
5968
5969                            Some(Token::Register {
5970                                name: RegisterName::E,
5971                                ..
5972                            }) => {
5973                                asm.next()?;
5974                                asm.data.push(0x9B);
5975                            }
5976
5977                            Some(Token::Register {
5978                                name: RegisterName::H,
5979                                ..
5980                            }) => {
5981                                asm.next()?;
5982                                asm.data.push(0x9C);
5983                            }
5984
5985                            Some(Token::Register {
5986                                name: RegisterName::L,
5987                                ..
5988                            }) => {
5989                                asm.next()?;
5990                                asm.data.push(0x9D);
5991                            }
5992
5993                            Some(Token::Register {
5994                                name: RegisterName::IXH,
5995                                ..
5996                            }) => {
5997                                asm.next()?;
5998                                asm.data.push(0xDD);
5999                                asm.data.push(0x9C);
6000                            }
6001
6002                            Some(Token::Register {
6003                                name: RegisterName::IXL,
6004                                ..
6005                            }) => {
6006                                asm.next()?;
6007                                asm.data.push(0xDD);
6008                                asm.data.push(0x9D);
6009                            }
6010
6011                            Some(Token::Register {
6012                                name: RegisterName::IYH,
6013                                ..
6014                            }) => {
6015                                asm.next()?;
6016                                asm.data.push(0xFD);
6017                                asm.data.push(0x9C);
6018                            }
6019
6020                            Some(Token::Register {
6021                                name: RegisterName::IYL,
6022                                ..
6023                            }) => {
6024                                asm.next()?;
6025                                asm.data.push(0xFD);
6026                                asm.data.push(0x9D);
6027                            }
6028
6029                            Some(Token::Symbol {
6030                                name: SymbolName::ParenOpen,
6031                                ..
6032                            }) => {
6033                                asm.next()?;
6034                                match asm.next()? {
6035                                    None => return asm.end_of_input_err(),
6036                                    Some(Token::Register {
6037                                        name: RegisterName::HL,
6038                                        ..
6039                                    }) => {
6040                                        asm.data.push(0x9E);
6041                                        asm.expect_symbol(SymbolName::ParenClose)?;
6042                                    }
6043
6044                                    Some(Token::Register {
6045                                        name: RegisterName::IX,
6046                                        ..
6047                                    }) => {
6048                                        asm.expect_symbol(SymbolName::Plus)?;
6049                                        asm.data.push(0xDD);
6050                                        asm.data.push(0x9E);
6051                                        let (loc, expr) = asm.expr()?;
6052                                        if let Some(value) =
6053                                            expr.evaluate(&asm.symtab, &asm.str_interner)
6054                                        {
6055                                            if (value as u32) > (u8::MAX as u32) {
6056                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
6057                                            }
6058                                            asm.data.push(value as u8);
6059                                        } else {
6060                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
6061                                            asm.data.push(0);
6062                                        }
6063                                        asm.expect_symbol(SymbolName::ParenClose)?;
6064                                    }
6065
6066                                    Some(Token::Register {
6067                                        name: RegisterName::IY,
6068                                        ..
6069                                    }) => {
6070                                        asm.expect_symbol(SymbolName::Plus)?;
6071                                        asm.data.push(0xFD);
6072                                        asm.data.push(0x9E);
6073                                        let (loc, expr) = asm.expr()?;
6074                                        if let Some(value) =
6075                                            expr.evaluate(&asm.symtab, &asm.str_interner)
6076                                        {
6077                                            if (value as u32) > (u8::MAX as u32) {
6078                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
6079                                            }
6080                                            asm.data.push(value as u8);
6081                                        } else {
6082                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
6083                                            asm.data.push(0);
6084                                        }
6085                                        asm.expect_symbol(SymbolName::ParenClose)?;
6086                                    }
6087
6088                                    Some(_) => {
6089                                        asm.data.push(0x9E);
6090                                        let (loc, expr) = asm.expr()?;
6091                                        if let Some(value) =
6092                                            expr.evaluate(&asm.symtab, &asm.str_interner)
6093                                        {
6094                                            if (value as u32) > (u8::MAX as u32) {
6095                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
6096                                            }
6097                                            asm.data.push(value as u8);
6098                                        } else {
6099                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
6100                                            asm.data.push(0);
6101                                        }
6102                                        asm.expect_symbol(SymbolName::ParenClose)?;
6103                                    }
6104                                }
6105                            }
6106
6107                            Some(_) => {
6108                                asm.data.push(0xDE);
6109                                let (loc, expr) = asm.expr()?;
6110                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6111                                    if (value as u32) > (u8::MAX as u32) {
6112                                        return asm_err!(
6113                                            loc,
6114                                            "Expression result ({value}) will not fit in a byte"
6115                                        );
6116                                    }
6117                                    asm.data.push(value as u8);
6118                                } else {
6119                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6120                                    asm.data.push(0);
6121                                }
6122                            }
6123                        }
6124                    }
6125
6126                    Some(Token::Register {
6127                        name: RegisterName::HL,
6128                        ..
6129                    }) => {
6130                        asm.expect_symbol(SymbolName::Comma)?;
6131                        match asm.next()? {
6132                            None => return asm.end_of_input_err(),
6133                            Some(Token::Register {
6134                                name: RegisterName::BC,
6135                                ..
6136                            }) => {
6137                                asm.data.push(0xED);
6138                                asm.data.push(0x42);
6139                            }
6140
6141                            Some(Token::Register {
6142                                name: RegisterName::DE,
6143                                ..
6144                            }) => {
6145                                asm.data.push(0xED);
6146                                asm.data.push(0x52);
6147                            }
6148
6149                            Some(Token::Register {
6150                                name: RegisterName::HL,
6151                                ..
6152                            }) => {
6153                                asm.data.push(0xED);
6154                                asm.data.push(0x62);
6155                            }
6156
6157                            Some(Token::Register {
6158                                name: RegisterName::SP,
6159                                ..
6160                            }) => {
6161                                asm.data.push(0xED);
6162                                asm.data.push(0x72);
6163                            }
6164
6165                            Some(tok) => {
6166                                return asm_err!(
6167                                tok.loc(),
6168                                "Unexpected {}, expected register \"bc\", \"de\", \"hl\" or \"sp\"",
6169                                tok.as_display(&asm.str_interner)
6170                            )
6171                            }
6172                        }
6173                    }
6174
6175                    Some(tok) => {
6176                        return asm_err!(
6177                            tok.loc(),
6178                            "Unexpected {}, expected register \"a\" or \"hl\"",
6179                            tok.as_display(&asm.str_interner)
6180                        )
6181                    }
6182                }
6183            }
6184
6185            OperationName::Scf => {
6186                asm.next()?;
6187                asm.data.push(0x37);
6188            }
6189
6190            OperationName::Set => {
6191                asm.next()?;
6192                match asm.const_expr()? {
6193                    (loc, None) => return asm_err!(loc, "Bit index must be immediately solvable"),
6194                    (loc, Some(value)) => {
6195                        if !(0..=7).contains(&value) {
6196                            return asm_err!(loc, "Bit index ({value}) must be between 0 and 7");
6197                        }
6198
6199                        asm.expect_symbol(SymbolName::Comma)?;
6200
6201                        match asm.next()? {
6202                            None => return asm.end_of_input_err(),
6203                            Some(Token::Register {
6204                                name: RegisterName::A,
6205                                ..
6206                            }) => {
6207                                asm.data.push(0xCB);
6208                                asm.data.push(match value {
6209                                    0 => 0xC7,
6210                                    1 => 0xCF,
6211                                    2 => 0xD7,
6212                                    3 => 0xDF,
6213                                    4 => 0xE7,
6214                                    5 => 0xEF,
6215                                    6 => 0xF7,
6216                                    7 => 0xFF,
6217                                    _ => unreachable!(),
6218                                });
6219                            }
6220
6221                            Some(Token::Register {
6222                                name: RegisterName::B,
6223                                ..
6224                            }) => {
6225                                asm.data.push(0xCB);
6226                                asm.data.push(match value {
6227                                    0 => 0xC0,
6228                                    1 => 0xC8,
6229                                    2 => 0xD0,
6230                                    3 => 0xD8,
6231                                    4 => 0xE0,
6232                                    5 => 0xE8,
6233                                    6 => 0xF0,
6234                                    7 => 0xF8,
6235                                    _ => unreachable!(),
6236                                });
6237                            }
6238
6239                            Some(Token::Register {
6240                                name: RegisterName::C,
6241                                ..
6242                            }) => {
6243                                asm.data.push(0xCB);
6244                                asm.data.push(match value {
6245                                    0 => 0xC1,
6246                                    1 => 0xC9,
6247                                    2 => 0xD1,
6248                                    3 => 0xD9,
6249                                    4 => 0xE1,
6250                                    5 => 0xE9,
6251                                    6 => 0xF1,
6252                                    7 => 0xF9,
6253                                    _ => unreachable!(),
6254                                });
6255                            }
6256
6257                            Some(Token::Register {
6258                                name: RegisterName::D,
6259                                ..
6260                            }) => {
6261                                asm.data.push(0xCB);
6262                                asm.data.push(match value {
6263                                    0 => 0xC2,
6264                                    1 => 0xCA,
6265                                    2 => 0xD2,
6266                                    3 => 0xDA,
6267                                    4 => 0xE2,
6268                                    5 => 0xEA,
6269                                    6 => 0xF2,
6270                                    7 => 0xFA,
6271                                    _ => unreachable!(),
6272                                });
6273                            }
6274
6275                            Some(Token::Register {
6276                                name: RegisterName::E,
6277                                ..
6278                            }) => {
6279                                asm.data.push(0xCB);
6280                                asm.data.push(match value {
6281                                    0 => 0xC3,
6282                                    1 => 0xCB,
6283                                    2 => 0xD3,
6284                                    3 => 0xDB,
6285                                    4 => 0xE3,
6286                                    5 => 0xEB,
6287                                    6 => 0xF3,
6288                                    7 => 0xFB,
6289                                    _ => unreachable!(),
6290                                });
6291                            }
6292
6293                            Some(Token::Register {
6294                                name: RegisterName::H,
6295                                ..
6296                            }) => {
6297                                asm.data.push(0xCB);
6298                                asm.data.push(match value {
6299                                    0 => 0xC4,
6300                                    1 => 0xCC,
6301                                    2 => 0xD4,
6302                                    3 => 0xDC,
6303                                    4 => 0xE4,
6304                                    5 => 0xEC,
6305                                    6 => 0xF4,
6306                                    7 => 0xFC,
6307                                    _ => unreachable!(),
6308                                });
6309                            }
6310
6311                            Some(Token::Register {
6312                                name: RegisterName::L,
6313                                ..
6314                            }) => {
6315                                asm.data.push(0xCB);
6316                                asm.data.push(match value {
6317                                    0 => 0xC5,
6318                                    1 => 0xCD,
6319                                    2 => 0xD5,
6320                                    3 => 0xDD,
6321                                    4 => 0xE5,
6322                                    5 => 0xED,
6323                                    6 => 0xF5,
6324                                    7 => 0xFD,
6325                                    _ => unreachable!(),
6326                                });
6327                            }
6328
6329                            Some(Token::Symbol {
6330                                name: SymbolName::ParenOpen,
6331                                ..
6332                            }) => {
6333                                match asm.next()? {
6334                                    None => return asm.end_of_input_err(),
6335                                    Some(Token::Register { name: RegisterName::HL, .. }) => {
6336                                        asm.data.push(0xCB);
6337                                        asm.data.push(match value {
6338                                            0 => 0xC6,
6339                                            1 => 0xCE,
6340                                            2 => 0xD6,
6341                                            3 => 0xDE,
6342                                            4 => 0xE6,
6343                                            5 => 0xEE,
6344                                            6 => 0xF6,
6345                                            7 => 0xFE,
6346                                            _ => unreachable!(),
6347                                        });
6348                                    }
6349
6350                                    Some(Token::Register { name: RegisterName::IX, .. }) => {
6351                                        asm.expect_symbol(SymbolName::Plus)?;
6352                                        asm.data.push(0xDD);
6353                                        asm.data.push(0xCB);
6354                                        let (loc, expr) = asm.expr()?;
6355                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6356                                            if (value as u32) > (u8::MAX as u32) {
6357                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
6358                                            }
6359                                            asm.data.push(value as u8);
6360                                        } else {
6361                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
6362                                            asm.data.push(0);
6363                                        }
6364                                        asm.data.push(match value {
6365                                            0 => 0xC6,
6366                                            1 => 0xCE,
6367                                            2 => 0xD6,
6368                                            3 => 0xDE,
6369                                            4 => 0xE6,
6370                                            5 => 0xEE,
6371                                            6 => 0xF6,
6372                                            7 => 0xFE,
6373                                            _ => unreachable!(),
6374                                        });
6375                                    }
6376
6377                                    Some(Token::Register { name: RegisterName::IY, .. }) => {
6378                                        asm.expect_symbol(SymbolName::Plus)?;
6379                                        asm.data.push(0xFD);
6380                                        asm.data.push(0xCB);
6381                                        let (loc, expr) = asm.expr()?;
6382                                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6383                                            if (value as u32) > (u8::MAX as u32) {
6384                                                return asm_err!(loc,"Expression result ({value}) will not fit in a byte");
6385                                            }
6386                                            asm.data.push(value as u8);
6387                                        } else {
6388                                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
6389                                            asm.data.push(0);
6390                                        }
6391                                        asm.data.push(match value {
6392                                            0 => 0xC6,
6393                                            1 => 0xCE,
6394                                            2 => 0xD6,
6395                                            3 => 0xDE,
6396                                            4 => 0xE6,
6397                                            5 => 0xEE,
6398                                            6 => 0xF6,
6399                                            7 => 0xFE,
6400                                            _ => unreachable!(),
6401                                        });
6402                                    }
6403
6404                                    Some(tok) => return asm_err!(tok.loc(),"Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",tok.as_display(&asm.str_interner)),
6405                                }
6406                                asm.expect_symbol(SymbolName::ParenClose)?;
6407                            }
6408
6409                            Some(tok) => {
6410                                return asm_err!(
6411                                    tok.loc(),
6412                                    "Unexpected {}, expected a register",
6413                                    tok.as_display(&asm.str_interner)
6414                                )
6415                            }
6416                        }
6417                    }
6418                }
6419            }
6420
6421            OperationName::Sla => {
6422                asm.next()?;
6423                match asm.next()? {
6424                    None => return asm.end_of_input_err(),
6425                    Some(Token::Register {
6426                        name: RegisterName::A,
6427                        ..
6428                    }) => {
6429                        asm.data.push(0xCB);
6430                        asm.data.push(0x27);
6431                    }
6432                    Some(Token::Register {
6433                        name: RegisterName::B,
6434                        ..
6435                    }) => {
6436                        asm.data.push(0xCB);
6437                        asm.data.push(0x20);
6438                    }
6439                    Some(Token::Register {
6440                        name: RegisterName::C,
6441                        ..
6442                    }) => {
6443                        asm.data.push(0xCB);
6444                        asm.data.push(0x21);
6445                    }
6446                    Some(Token::Register {
6447                        name: RegisterName::D,
6448                        ..
6449                    }) => {
6450                        asm.data.push(0xCB);
6451                        asm.data.push(0x22);
6452                    }
6453                    Some(Token::Register {
6454                        name: RegisterName::E,
6455                        ..
6456                    }) => {
6457                        asm.data.push(0xCB);
6458                        asm.data.push(0x23);
6459                    }
6460                    Some(Token::Register {
6461                        name: RegisterName::H,
6462                        ..
6463                    }) => {
6464                        asm.data.push(0xCB);
6465                        asm.data.push(0x24);
6466                    }
6467                    Some(Token::Register {
6468                        name: RegisterName::L,
6469                        ..
6470                    }) => {
6471                        asm.data.push(0xCB);
6472                        asm.data.push(0x25);
6473                    }
6474                    Some(Token::Symbol {
6475                        name: SymbolName::ParenOpen,
6476                        ..
6477                    }) => {
6478                        match asm.next()? {
6479                            None => return asm.end_of_input_err(),
6480                            Some(Token::Register {
6481                                name: RegisterName::HL,
6482                                ..
6483                            }) => {
6484                                asm.data.push(0xCB);
6485                                asm.data.push(0x26);
6486                            }
6487                            Some(Token::Register {
6488                                name: RegisterName::IX,
6489                                ..
6490                            }) => {
6491                                asm.expect_symbol(SymbolName::Plus)?;
6492                                asm.data.push(0xDD);
6493                                asm.data.push(0xCB);
6494                                let (loc, expr) = asm.expr()?;
6495                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6496                                    if (value as u32) > (u8::MAX as u32) {
6497                                        return asm_err!(
6498                                            loc,
6499                                            "Expression result ({value}) will not fit in a byte"
6500                                        );
6501                                    }
6502                                    asm.data.push(value as u8);
6503                                } else {
6504                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6505                                    asm.data.push(0);
6506                                }
6507                                asm.data.push(0x26);
6508                            }
6509                            Some(Token::Register {
6510                                name: RegisterName::IY,
6511                                ..
6512                            }) => {
6513                                asm.expect_symbol(SymbolName::Plus)?;
6514                                asm.data.push(0xFD);
6515                                asm.data.push(0xCB);
6516                                let (loc, expr) = asm.expr()?;
6517                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6518                                    if (value as u32) > (u8::MAX as u32) {
6519                                        return asm_err!(
6520                                            loc,
6521                                            "Expression result ({value}) will not fit in a byte"
6522                                        );
6523                                    }
6524                                    asm.data.push(value as u8);
6525                                } else {
6526                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6527                                    asm.data.push(0);
6528                                }
6529                                asm.data.push(0x26);
6530                            }
6531                            Some(tok) => {
6532                                return asm_err!(
6533                                    tok.loc(),
6534                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
6535                                    tok.as_display(&asm.str_interner)
6536                                )
6537                            }
6538                        }
6539                        asm.expect_symbol(SymbolName::ParenClose)?;
6540                    }
6541                    Some(tok) => {
6542                        return asm_err!(
6543                            tok.loc(),
6544                            "Unexpected {}, expected register",
6545                            tok.as_display(&asm.str_interner)
6546                        )
6547                    }
6548                }
6549            }
6550
6551            OperationName::Sll => {
6552                asm.next()?;
6553                match asm.next()? {
6554                    None => return asm.end_of_input_err(),
6555                    Some(Token::Register {
6556                        name: RegisterName::A,
6557                        ..
6558                    }) => {
6559                        asm.data.push(0xCB);
6560                        asm.data.push(0x37);
6561                    }
6562                    Some(Token::Register {
6563                        name: RegisterName::B,
6564                        ..
6565                    }) => {
6566                        asm.data.push(0xCB);
6567                        asm.data.push(0x30);
6568                    }
6569                    Some(Token::Register {
6570                        name: RegisterName::C,
6571                        ..
6572                    }) => {
6573                        asm.data.push(0xCB);
6574                        asm.data.push(0x31);
6575                    }
6576                    Some(Token::Register {
6577                        name: RegisterName::D,
6578                        ..
6579                    }) => {
6580                        asm.data.push(0xCB);
6581                        asm.data.push(0x32);
6582                    }
6583                    Some(Token::Register {
6584                        name: RegisterName::E,
6585                        ..
6586                    }) => {
6587                        asm.data.push(0xCB);
6588                        asm.data.push(0x33);
6589                    }
6590                    Some(Token::Register {
6591                        name: RegisterName::H,
6592                        ..
6593                    }) => {
6594                        asm.data.push(0xCB);
6595                        asm.data.push(0x34);
6596                    }
6597                    Some(Token::Register {
6598                        name: RegisterName::L,
6599                        ..
6600                    }) => {
6601                        asm.data.push(0xCB);
6602                        asm.data.push(0x35);
6603                    }
6604                    Some(Token::Symbol {
6605                        name: SymbolName::ParenOpen,
6606                        ..
6607                    }) => {
6608                        match asm.next()? {
6609                            None => return asm.end_of_input_err(),
6610                            Some(Token::Register {
6611                                name: RegisterName::HL,
6612                                ..
6613                            }) => {
6614                                asm.data.push(0xCB);
6615                                asm.data.push(0x36);
6616                            }
6617                            Some(Token::Register {
6618                                name: RegisterName::IX,
6619                                ..
6620                            }) => {
6621                                asm.expect_symbol(SymbolName::Plus)?;
6622                                asm.data.push(0xDD);
6623                                asm.data.push(0xCB);
6624                                let (loc, expr) = asm.expr()?;
6625                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6626                                    if (value as u32) > (u8::MAX as u32) {
6627                                        return asm_err!(
6628                                            loc,
6629                                            "Expression result ({value}) will not fit in a byte"
6630                                        );
6631                                    }
6632                                    asm.data.push(value as u8);
6633                                } else {
6634                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6635                                    asm.data.push(0);
6636                                }
6637                                asm.data.push(0x36);
6638                            }
6639                            Some(Token::Register {
6640                                name: RegisterName::IY,
6641                                ..
6642                            }) => {
6643                                asm.expect_symbol(SymbolName::Plus)?;
6644                                asm.data.push(0xFD);
6645                                asm.data.push(0xCB);
6646                                let (loc, expr) = asm.expr()?;
6647                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6648                                    if (value as u32) > (u8::MAX as u32) {
6649                                        return asm_err!(
6650                                            loc,
6651                                            "Expression result ({value}) will not fit in a byte"
6652                                        );
6653                                    }
6654                                    asm.data.push(value as u8);
6655                                } else {
6656                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6657                                    asm.data.push(0);
6658                                }
6659                                asm.data.push(0x36);
6660                            }
6661                            Some(tok) => {
6662                                return asm_err!(
6663                                    tok.loc(),
6664                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
6665                                    tok.as_display(&asm.str_interner)
6666                                )
6667                            }
6668                        }
6669                        asm.expect_symbol(SymbolName::ParenClose)?;
6670                    }
6671                    Some(tok) => {
6672                        return asm_err!(
6673                            tok.loc(),
6674                            "Unexpected {}, expected register",
6675                            tok.as_display(&asm.str_interner)
6676                        )
6677                    }
6678                }
6679            }
6680
6681            OperationName::Sra => {
6682                asm.next()?;
6683                match asm.next()? {
6684                    None => return asm.end_of_input_err(),
6685                    Some(Token::Register {
6686                        name: RegisterName::A,
6687                        ..
6688                    }) => {
6689                        asm.data.push(0xCB);
6690                        asm.data.push(0x2F);
6691                    }
6692                    Some(Token::Register {
6693                        name: RegisterName::B,
6694                        ..
6695                    }) => {
6696                        asm.data.push(0xCB);
6697                        asm.data.push(0x28);
6698                    }
6699                    Some(Token::Register {
6700                        name: RegisterName::C,
6701                        ..
6702                    }) => {
6703                        asm.data.push(0xCB);
6704                        asm.data.push(0x29);
6705                    }
6706                    Some(Token::Register {
6707                        name: RegisterName::D,
6708                        ..
6709                    }) => {
6710                        asm.data.push(0xCB);
6711                        asm.data.push(0x2A);
6712                    }
6713                    Some(Token::Register {
6714                        name: RegisterName::E,
6715                        ..
6716                    }) => {
6717                        asm.data.push(0xCB);
6718                        asm.data.push(0x2B);
6719                    }
6720                    Some(Token::Register {
6721                        name: RegisterName::H,
6722                        ..
6723                    }) => {
6724                        asm.data.push(0xCB);
6725                        asm.data.push(0x2C);
6726                    }
6727                    Some(Token::Register {
6728                        name: RegisterName::L,
6729                        ..
6730                    }) => {
6731                        asm.data.push(0xCB);
6732                        asm.data.push(0x2D);
6733                    }
6734                    Some(Token::Symbol {
6735                        name: SymbolName::ParenOpen,
6736                        ..
6737                    }) => {
6738                        match asm.next()? {
6739                            None => return asm.end_of_input_err(),
6740                            Some(Token::Register {
6741                                name: RegisterName::HL,
6742                                ..
6743                            }) => {
6744                                asm.data.push(0xCB);
6745                                asm.data.push(0x2E);
6746                            }
6747                            Some(Token::Register {
6748                                name: RegisterName::IX,
6749                                ..
6750                            }) => {
6751                                asm.expect_symbol(SymbolName::Plus)?;
6752                                asm.data.push(0xDD);
6753                                asm.data.push(0xCB);
6754                                let (loc, expr) = asm.expr()?;
6755                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6756                                    if (value as u32) > (u8::MAX as u32) {
6757                                        return asm_err!(
6758                                            loc,
6759                                            "Expression result ({value}) will not fit in a byte"
6760                                        );
6761                                    }
6762                                    asm.data.push(value as u8);
6763                                } else {
6764                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6765                                    asm.data.push(0);
6766                                }
6767                                asm.data.push(0x2E);
6768                            }
6769                            Some(Token::Register {
6770                                name: RegisterName::IY,
6771                                ..
6772                            }) => {
6773                                asm.expect_symbol(SymbolName::Plus)?;
6774                                asm.data.push(0xFD);
6775                                asm.data.push(0xCB);
6776                                let (loc, expr) = asm.expr()?;
6777                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6778                                    if (value as u32) > (u8::MAX as u32) {
6779                                        return asm_err!(
6780                                            loc,
6781                                            "Expression result ({value}) will not fit in a byte"
6782                                        );
6783                                    }
6784                                    asm.data.push(value as u8);
6785                                } else {
6786                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6787                                    asm.data.push(0);
6788                                }
6789                                asm.data.push(0x2E);
6790                            }
6791                            Some(tok) => {
6792                                return asm_err!(
6793                                    tok.loc(),
6794                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
6795                                    tok.as_display(&asm.str_interner)
6796                                )
6797                            }
6798                        }
6799                        asm.expect_symbol(SymbolName::ParenClose)?;
6800                    }
6801                    Some(tok) => {
6802                        return asm_err!(
6803                            tok.loc(),
6804                            "Unexpected {}, expected register",
6805                            tok.as_display(&asm.str_interner)
6806                        )
6807                    }
6808                }
6809            }
6810
6811            OperationName::Srl => {
6812                asm.next()?;
6813                match asm.next()? {
6814                    None => return asm.end_of_input_err(),
6815                    Some(Token::Register {
6816                        name: RegisterName::A,
6817                        ..
6818                    }) => {
6819                        asm.data.push(0xCB);
6820                        asm.data.push(0x3F);
6821                    }
6822                    Some(Token::Register {
6823                        name: RegisterName::B,
6824                        ..
6825                    }) => {
6826                        asm.data.push(0xCB);
6827                        asm.data.push(0x38);
6828                    }
6829                    Some(Token::Register {
6830                        name: RegisterName::C,
6831                        ..
6832                    }) => {
6833                        asm.data.push(0xCB);
6834                        asm.data.push(0x39);
6835                    }
6836                    Some(Token::Register {
6837                        name: RegisterName::D,
6838                        ..
6839                    }) => {
6840                        asm.data.push(0xCB);
6841                        asm.data.push(0x3A);
6842                    }
6843                    Some(Token::Register {
6844                        name: RegisterName::E,
6845                        ..
6846                    }) => {
6847                        asm.data.push(0xCB);
6848                        asm.data.push(0x3B);
6849                    }
6850                    Some(Token::Register {
6851                        name: RegisterName::H,
6852                        ..
6853                    }) => {
6854                        asm.data.push(0xCB);
6855                        asm.data.push(0x3C);
6856                    }
6857                    Some(Token::Register {
6858                        name: RegisterName::L,
6859                        ..
6860                    }) => {
6861                        asm.data.push(0xCB);
6862                        asm.data.push(0x3D);
6863                    }
6864                    Some(Token::Symbol {
6865                        name: SymbolName::ParenOpen,
6866                        ..
6867                    }) => {
6868                        match asm.next()? {
6869                            None => return asm.end_of_input_err(),
6870                            Some(Token::Register {
6871                                name: RegisterName::HL,
6872                                ..
6873                            }) => {
6874                                asm.data.push(0xCB);
6875                                asm.data.push(0x3E);
6876                            }
6877                            Some(Token::Register {
6878                                name: RegisterName::IX,
6879                                ..
6880                            }) => {
6881                                asm.expect_symbol(SymbolName::Plus)?;
6882                                asm.data.push(0xDD);
6883                                asm.data.push(0xCB);
6884                                let (loc, expr) = asm.expr()?;
6885                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6886                                    if (value as u32) > (u8::MAX as u32) {
6887                                        return asm_err!(
6888                                            loc,
6889                                            "Expression result ({value}) will not fit in a byte"
6890                                        );
6891                                    }
6892                                    asm.data.push(value as u8);
6893                                } else {
6894                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6895                                    asm.data.push(0);
6896                                }
6897                                asm.data.push(0x3E);
6898                            }
6899                            Some(Token::Register {
6900                                name: RegisterName::IY,
6901                                ..
6902                            }) => {
6903                                asm.expect_symbol(SymbolName::Plus)?;
6904                                asm.data.push(0xFD);
6905                                asm.data.push(0xCB);
6906                                let (loc, expr) = asm.expr()?;
6907                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
6908                                    if (value as u32) > (u8::MAX as u32) {
6909                                        return asm_err!(
6910                                            loc,
6911                                            "Expression result ({value}) will not fit in a byte"
6912                                        );
6913                                    }
6914                                    asm.data.push(value as u8);
6915                                } else {
6916                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
6917                                    asm.data.push(0);
6918                                }
6919                                asm.data.push(0x3E);
6920                            }
6921                            Some(tok) => {
6922                                return asm_err!(
6923                                    tok.loc(),
6924                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
6925                                    tok.as_display(&asm.str_interner)
6926                                )
6927                            }
6928                        }
6929                        asm.expect_symbol(SymbolName::ParenClose)?;
6930                    }
6931                    Some(tok) => {
6932                        return asm_err!(
6933                            tok.loc(),
6934                            "Unexpected {}, expected register",
6935                            tok.as_display(&asm.str_interner)
6936                        )
6937                    }
6938                }
6939            }
6940
6941            OperationName::Sub => {
6942                asm.next()?;
6943                match asm.peek()? {
6944                    None => return asm.end_of_input_err(),
6945                    Some(Token::Register {
6946                        name: RegisterName::A,
6947                        ..
6948                    }) => {
6949                        asm.next()?;
6950                        asm.data.push(0x97);
6951                    }
6952
6953                    Some(Token::Register {
6954                        name: RegisterName::B,
6955                        ..
6956                    }) => {
6957                        asm.next()?;
6958                        asm.data.push(0x90);
6959                    }
6960
6961                    Some(Token::Register {
6962                        name: RegisterName::C,
6963                        ..
6964                    }) => {
6965                        asm.next()?;
6966                        asm.data.push(0x91);
6967                    }
6968
6969                    Some(Token::Register {
6970                        name: RegisterName::D,
6971                        ..
6972                    }) => {
6973                        asm.next()?;
6974                        asm.data.push(0x92);
6975                    }
6976
6977                    Some(Token::Register {
6978                        name: RegisterName::E,
6979                        ..
6980                    }) => {
6981                        asm.next()?;
6982                        asm.data.push(0x93);
6983                    }
6984
6985                    Some(Token::Register {
6986                        name: RegisterName::H,
6987                        ..
6988                    }) => {
6989                        asm.next()?;
6990                        asm.data.push(0x94);
6991                    }
6992
6993                    Some(Token::Register {
6994                        name: RegisterName::L,
6995                        ..
6996                    }) => {
6997                        asm.next()?;
6998                        asm.data.push(0x95);
6999                    }
7000
7001                    Some(Token::Register {
7002                        name: RegisterName::IXH,
7003                        ..
7004                    }) => {
7005                        asm.next()?;
7006                        asm.data.push(0xDD);
7007                        asm.data.push(0x94);
7008                    }
7009
7010                    Some(Token::Register {
7011                        name: RegisterName::IXL,
7012                        ..
7013                    }) => {
7014                        asm.next()?;
7015                        asm.data.push(0xDD);
7016                        asm.data.push(0x95);
7017                    }
7018
7019                    Some(Token::Register {
7020                        name: RegisterName::IYH,
7021                        ..
7022                    }) => {
7023                        asm.next()?;
7024                        asm.data.push(0xFD);
7025                        asm.data.push(0x94);
7026                    }
7027
7028                    Some(Token::Register {
7029                        name: RegisterName::IYL,
7030                        ..
7031                    }) => {
7032                        asm.next()?;
7033                        asm.data.push(0xFD);
7034                        asm.data.push(0x95);
7035                    }
7036
7037                    Some(Token::Symbol {
7038                        name: SymbolName::ParenOpen,
7039                        ..
7040                    }) => {
7041                        asm.next()?;
7042                        match asm.next()? {
7043                            None => return asm.end_of_input_err(),
7044                            Some(Token::Register {
7045                                name: RegisterName::HL,
7046                                ..
7047                            }) => {
7048                                asm.data.push(0x96);
7049                                asm.expect_symbol(SymbolName::ParenClose)?;
7050                            }
7051
7052                            Some(Token::Register {
7053                                name: RegisterName::IX,
7054                                ..
7055                            }) => {
7056                                asm.expect_symbol(SymbolName::Plus)?;
7057                                asm.data.push(0xDD);
7058                                asm.data.push(0x96);
7059                                let (loc, expr) = asm.expr()?;
7060                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
7061                                    if (value as u32) > (u8::MAX as u32) {
7062                                        return asm_err!(
7063                                            loc,
7064                                            "Expression result ({value}) will not fit in a byte"
7065                                        );
7066                                    }
7067                                    asm.data.push(value as u8);
7068                                } else {
7069                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
7070                                    asm.data.push(0);
7071                                }
7072                                asm.expect_symbol(SymbolName::ParenClose)?;
7073                            }
7074
7075                            Some(Token::Register {
7076                                name: RegisterName::IY,
7077                                ..
7078                            }) => {
7079                                asm.expect_symbol(SymbolName::Plus)?;
7080                                asm.data.push(0xFD);
7081                                asm.data.push(0x96);
7082                                let (loc, expr) = asm.expr()?;
7083                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
7084                                    if (value as u32) > (u8::MAX as u32) {
7085                                        return asm_err!(
7086                                            loc,
7087                                            "Expression result ({value}) will not fit in a byte"
7088                                        );
7089                                    }
7090                                    asm.data.push(value as u8);
7091                                } else {
7092                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
7093                                    asm.data.push(0);
7094                                }
7095                                asm.expect_symbol(SymbolName::ParenClose)?;
7096                            }
7097                            Some(tok) => {
7098                                return asm_err!(
7099                                    tok.loc(),
7100                                    "Unexpected {}, expected register \"hl\", \"ix\", or \"iy\"",
7101                                    tok.as_display(&asm.str_interner)
7102                                )
7103                            }
7104                        }
7105                    }
7106                    Some(_) => {
7107                        asm.data.push(0xD6);
7108                        let (loc, expr) = asm.expr()?;
7109                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
7110                            if (value as u32) > (u8::MAX as u32) {
7111                                return asm_err!(
7112                                    loc,
7113                                    "Expression result ({value}) will not fit in a byte"
7114                                );
7115                            }
7116                            asm.data.push(value as u8);
7117                        } else {
7118                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
7119                            asm.data.push(0);
7120                        }
7121                    }
7122                }
7123            }
7124
7125            OperationName::Xor => {
7126                asm.next()?;
7127                match asm.peek()? {
7128                    None => return asm.end_of_input_err(),
7129                    Some(Token::Register {
7130                        name: RegisterName::A,
7131                        ..
7132                    }) => {
7133                        asm.next()?;
7134                        asm.data.push(0xAF);
7135                    }
7136
7137                    Some(Token::Register {
7138                        name: RegisterName::B,
7139                        ..
7140                    }) => {
7141                        asm.next()?;
7142                        asm.data.push(0xA8);
7143                    }
7144
7145                    Some(Token::Register {
7146                        name: RegisterName::C,
7147                        ..
7148                    }) => {
7149                        asm.next()?;
7150                        asm.data.push(0xA9);
7151                    }
7152
7153                    Some(Token::Register {
7154                        name: RegisterName::D,
7155                        ..
7156                    }) => {
7157                        asm.next()?;
7158                        asm.data.push(0xAA);
7159                    }
7160
7161                    Some(Token::Register {
7162                        name: RegisterName::E,
7163                        ..
7164                    }) => {
7165                        asm.next()?;
7166                        asm.data.push(0xAB);
7167                    }
7168
7169                    Some(Token::Register {
7170                        name: RegisterName::H,
7171                        ..
7172                    }) => {
7173                        asm.next()?;
7174                        asm.data.push(0xAC);
7175                    }
7176
7177                    Some(Token::Register {
7178                        name: RegisterName::L,
7179                        ..
7180                    }) => {
7181                        asm.next()?;
7182                        asm.data.push(0xAD);
7183                    }
7184
7185                    Some(Token::Register {
7186                        name: RegisterName::IXH,
7187                        ..
7188                    }) => {
7189                        asm.next()?;
7190                        asm.data.push(0xDD);
7191                        asm.data.push(0xAC);
7192                    }
7193
7194                    Some(Token::Register {
7195                        name: RegisterName::IXL,
7196                        ..
7197                    }) => {
7198                        asm.next()?;
7199                        asm.data.push(0xDD);
7200                        asm.data.push(0xAD);
7201                    }
7202
7203                    Some(Token::Register {
7204                        name: RegisterName::IYH,
7205                        ..
7206                    }) => {
7207                        asm.next()?;
7208                        asm.data.push(0xFD);
7209                        asm.data.push(0xAC);
7210                    }
7211
7212                    Some(Token::Register {
7213                        name: RegisterName::IYL,
7214                        ..
7215                    }) => {
7216                        asm.next()?;
7217                        asm.data.push(0xFD);
7218                        asm.data.push(0xAD);
7219                    }
7220
7221                    Some(Token::Symbol {
7222                        name: SymbolName::ParenOpen,
7223                        ..
7224                    }) => {
7225                        asm.next()?;
7226                        match asm.next()? {
7227                            None => return asm.end_of_input_err(),
7228                            Some(Token::Register {
7229                                name: RegisterName::HL,
7230                                ..
7231                            }) => {
7232                                asm.data.push(0xAE);
7233                                asm.expect_symbol(SymbolName::ParenClose)?;
7234                            }
7235
7236                            Some(Token::Register {
7237                                name: RegisterName::IX,
7238                                ..
7239                            }) => {
7240                                asm.expect_symbol(SymbolName::Plus)?;
7241                                asm.data.push(0xDD);
7242                                asm.data.push(0xAE);
7243                                let (loc, expr) = asm.expr()?;
7244                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
7245                                    if (value as u32) > (u8::MAX as u32) {
7246                                        return asm_err!(
7247                                            loc,
7248                                            "Expression result ({value}) will not fit in a byte"
7249                                        );
7250                                    }
7251                                    asm.data.push(value as u8);
7252                                } else {
7253                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
7254                                    asm.data.push(0);
7255                                }
7256                                asm.expect_symbol(SymbolName::ParenClose)?;
7257                            }
7258
7259                            Some(Token::Register {
7260                                name: RegisterName::IY,
7261                                ..
7262                            }) => {
7263                                asm.expect_symbol(SymbolName::Plus)?;
7264                                asm.data.push(0xFD);
7265                                asm.data.push(0xAE);
7266                                let (loc, expr) = asm.expr()?;
7267                                if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
7268                                    if (value as u32) > (u8::MAX as u32) {
7269                                        return asm_err!(
7270                                            loc,
7271                                            "Expression result ({value}) will not fit in a byte"
7272                                        );
7273                                    }
7274                                    asm.data.push(value as u8);
7275                                } else {
7276                                    asm.links.push(Link::byte(loc, asm.data.len(), expr));
7277                                    asm.data.push(0);
7278                                }
7279                                asm.expect_symbol(SymbolName::ParenClose)?;
7280                            }
7281                            Some(tok) => {
7282                                return asm_err!(
7283                                    tok.loc(),
7284                                    "Unexpected {}, expected registers \"hl\", \"ix\", or \"iy\"",
7285                                    tok.as_display(&asm.str_interner)
7286                                )
7287                            }
7288                        }
7289                    }
7290
7291                    Some(_) => {
7292                        asm.data.push(0xEE);
7293                        let (loc, expr) = asm.expr()?;
7294                        if let Some(value) = expr.evaluate(&asm.symtab, &asm.str_interner) {
7295                            if (value as u32) > (u8::MAX as u32) {
7296                                return asm_err!(
7297                                    loc,
7298                                    "Expression result ({value}) will not fit in a byte"
7299                                );
7300                            }
7301                            asm.data.push(value as u8);
7302                        } else {
7303                            asm.links.push(Link::byte(loc, asm.data.len(), expr));
7304                            asm.data.push(0);
7305                        }
7306                    }
7307                }
7308            }
7309        }
7310        Ok(())
7311    }
7312}