const std = @import("std"); pub const PseudoOp = enum { IS, GREG, LOC, BYTE, WYDE, TETRA, OCTA, }; pub const Opcode = enum(u8) { TRAP, FCMP, FUN, FEQL, FADD, FIX, FSUB, FIXU, FLOT, FLOTI, FLOTU, FLOTUI, SFLOT, SFLOTI, SFLOTU, SFLOTUI, FMUL, FCMPE, FUNE, FEQLE, FDIV, FSQRT, FREM, FINT, MUL, MULI, MULU, MULUI, DIV, DIVI, DIVU, DIVUI, ADD, ADDI, ADDU, ADDUI, SUB, SUBI, SUBU, SUBUI, _2ADDU, _2ADDUI, _4ADDU, _4ADDUI, _8ADDU, _8ADDUI, _16ADDU, _16ADDUI, CMP, CMPI, CMPU, CMPUI, NEG, NEGI, NEGU, NEGUI, SL, SLI, SLU, SLUI, SR, SRI, SRU, SRUI, BN, BNB, BZ, BZB, BP, BPB, BOD, BODB, BNN, BNNB, BNZ, BNZB, BNP, BNPB, BEV, BEVB, PBN, PBNB, PBZ, PBZB, PBP, PBPB, PBOD, PBODB, PBNN, PBNNB, PBNZ, PBNZB, PBNP, PBNPB, PBEV, PBEVB, CSN, CSNI, CSZ, CSZI, CSP, CSPI, CSOD, CSODI, CSNN, CSNNI, CSNZ, CSNZI, CSNP, CSNPI, CSEV, CSEVI, ZSN, ZSNI, ZSZ, ZSZI, ZSP, ZSPI, ZSOD, ZSODI, ZSNN, ZSNNI, ZSNZ, ZSNZI, ZSNP, ZSNPI, ZSEV, ZSEVI, LDB, LDBI, LDBU, LDBUI, LDW, LDWI, LDWU, LDWUI, LDT, LDTI, LDTU, LDTUI, LDO, LDOI, LDOU, LDOUI, LDSF, LDSFI, LDHT, LDHTI, CSWAP, CSWAPI, LDUNC, LDUNCI, LDVTS, LDVTSI, PRELD, PRELDI, PREGO, PREGOI, GO, GOI, STB, STBI, STBU, STBUI, STW, STWI, STWU, STWUI, STT, STTI, STTU, STTUI, STO, STOI, STOU, STOUI, STSF, STSFI, STHT, STHTI, STCO, STCOI, STUNC, STUNCI, SYNCD, SYNCDI, PREST, PRESTI, SYNCID, SYNCIDI, PUSHGO, PUSHGOI, OR, ORI, ORN, ORNI, NOR, NORI, XOR, XORI, AND, ANDI, ANDN, ANDNI, NAND, NANDI, NXOR, NXORI, BDIF, BDIFI, WDIF, WDIFI, TDIF, TDIFI, ODIF, ODIFI, MUX, MUXI, SADD, SADDI, MOR, MORI, MXOR, MXORI, SETH, SETMH, SETML, SETL, INCH, INCMH, INCML, INCL, ORH, ORMH, ORML, ORL, ANDNH, ANDNMH, ANDNML, ANDNL, JMP, JMPB, PUSHJ, PUSHJB, GETA, GETAB, PUT, PUTI, POP, RESUME, SAVE, UNSAVE, SYNC, SWYM, GET, TRIP, }; pub const OperationType = enum { pseudo_op, opcode, }; pub const Operation = union(OperationType) { pseudo_op: PseudoOp, opcode: Opcode, }; pub fn parseOp(allocator: std.mem.Allocator, text: []const u8) !Operation { const upper_str = try std.ascii.allocUpperString(allocator, text); var out: Operation = undefined; const opcode = getOpcode(upper_str) catch |err| { if (err == error.NoOpcode) { if (std.mem.eql(u8, upper_str, "IS")) { out = Operation{ .pseudo_op = PseudoOp.IS }; } else if (std.mem.eql(u8, upper_str, "GREG")) { out = Operation{ .pseudo_op = PseudoOp.GREG }; } else if (std.mem.eql(u8, upper_str, "LOC")) { out = Operation{ .pseudo_op = PseudoOp.LOC }; } else if (std.mem.eql(u8, upper_str, "BYTE")) { out = Operation{ .pseudo_op = PseudoOp.BYTE }; } else if (std.mem.eql(u8, upper_str, "WYDE")) { out = Operation{ .pseudo_op = PseudoOp.WYDE }; } else if (std.mem.eql(u8, upper_str, "TETRA")) { out = Operation{ .pseudo_op = PseudoOp.TETRA }; } else if (std.mem.eql(u8, upper_str, "OCTA")) { out = Operation{ .pseudo_op = PseudoOp.OCTA }; } else { allocator.free(upper_str); return err; } allocator.free(upper_str); return out; } allocator.free(upper_str); return err; }; allocator.free(upper_str); return Operation{ .opcode = opcode }; } fn getOpcode(upper_str: []const u8) !Opcode { if (std.mem.eql(u8, upper_str, "TRAP")) { return Opcode.TRAP; } if (std.mem.eql(u8, upper_str, "FCMP")) { return Opcode.FCMP; } if (std.mem.eql(u8, upper_str, "FUN")) { return Opcode.FUN; } if (std.mem.eql(u8, upper_str, "FEQL")) { return Opcode.FEQL; } if (std.mem.eql(u8, upper_str, "FADD")) { return Opcode.FADD; } if (std.mem.eql(u8, upper_str, "FIX")) { return Opcode.FIX; } if (std.mem.eql(u8, upper_str, "FSUB")) { return Opcode.FSUB; } if (std.mem.eql(u8, upper_str, "FIXU")) { return Opcode.FIXU; } if (std.mem.eql(u8, upper_str, "FLOT")) { return Opcode.FLOT; } if (std.mem.eql(u8, upper_str, "FLOTU")) { return Opcode.FLOTU; } if (std.mem.eql(u8, upper_str, "SFLOT")) { return Opcode.SFLOT; } if (std.mem.eql(u8, upper_str, "SFLOTU")) { return Opcode.SFLOTU; } if (std.mem.eql(u8, upper_str, "FMUL")) { return Opcode.FMUL; } if (std.mem.eql(u8, upper_str, "FCMPE")) { return Opcode.FCMPE; } if (std.mem.eql(u8, upper_str, "FUNE")) { return Opcode.FUNE; } if (std.mem.eql(u8, upper_str, "FEQLE")) { return Opcode.FEQLE; } if (std.mem.eql(u8, upper_str, "FDIV")) { return Opcode.FDIV; } if (std.mem.eql(u8, upper_str, "FSQRT")) { return Opcode.FSQRT; } if (std.mem.eql(u8, upper_str, "FREM")) { return Opcode.FREM; } if (std.mem.eql(u8, upper_str, "FINT")) { return Opcode.FINT; } if (std.mem.eql(u8, upper_str, "MUL")) { return Opcode.MUL; } if (std.mem.eql(u8, upper_str, "MULU")) { return Opcode.MULU; } if (std.mem.eql(u8, upper_str, "DIV")) { return Opcode.DIV; } if (std.mem.eql(u8, upper_str, "DIVU")) { return Opcode.DIVU; } if (std.mem.eql(u8, upper_str, "ADD")) { return Opcode.ADD; } if (std.mem.eql(u8, upper_str, "ADDU")) { return Opcode.ADDU; } if (std.mem.eql(u8, upper_str, "SUB")) { return Opcode.SUB; } if (std.mem.eql(u8, upper_str, "SUBU")) { return Opcode.SUBU; } if (std.mem.eql(u8, upper_str, "2ADDU")) { return Opcode._2ADDU; } if (std.mem.eql(u8, upper_str, "4ADDU")) { return Opcode._4ADDU; } if (std.mem.eql(u8, upper_str, "8ADDU")) { return Opcode._8ADDU; } if (std.mem.eql(u8, upper_str, "16ADDU")) { return Opcode._16ADDU; } if (std.mem.eql(u8, upper_str, "CMP")) { return Opcode.CMP; } if (std.mem.eql(u8, upper_str, "CMPU")) { return Opcode.CMPU; } if (std.mem.eql(u8, upper_str, "NEG")) { return Opcode.NEG; } if (std.mem.eql(u8, upper_str, "NEGU")) { return Opcode.NEGU; } if (std.mem.eql(u8, upper_str, "SL")) { return Opcode.SL; } if (std.mem.eql(u8, upper_str, "SLU")) { return Opcode.SLU; } if (std.mem.eql(u8, upper_str, "SR")) { return Opcode.SR; } if (std.mem.eql(u8, upper_str, "SRU")) { return Opcode.SRU; } if (std.mem.eql(u8, upper_str, "BN")) { return Opcode.BN; } if (std.mem.eql(u8, upper_str, "BZ")) { return Opcode.BZ; } if (std.mem.eql(u8, upper_str, "BP")) { return Opcode.BP; } if (std.mem.eql(u8, upper_str, "BOD")) { return Opcode.BOD; } if (std.mem.eql(u8, upper_str, "BNN")) { return Opcode.BNN; } if (std.mem.eql(u8, upper_str, "BNZ")) { return Opcode.BNZ; } if (std.mem.eql(u8, upper_str, "BNP")) { return Opcode.BNP; } if (std.mem.eql(u8, upper_str, "BEV")) { return Opcode.BEV; } if (std.mem.eql(u8, upper_str, "PBN")) { return Opcode.PBN; } if (std.mem.eql(u8, upper_str, "PBZ")) { return Opcode.PBZ; } if (std.mem.eql(u8, upper_str, "PBP")) { return Opcode.PBP; } if (std.mem.eql(u8, upper_str, "PBOD")) { return Opcode.PBOD; } if (std.mem.eql(u8, upper_str, "PBNN")) { return Opcode.PBNN; } if (std.mem.eql(u8, upper_str, "PBNZ")) { return Opcode.PBNZ; } if (std.mem.eql(u8, upper_str, "PBNP")) { return Opcode.PBNP; } if (std.mem.eql(u8, upper_str, "PBEV")) { return Opcode.PBEV; } if (std.mem.eql(u8, upper_str, "CSN")) { return Opcode.CSN; } if (std.mem.eql(u8, upper_str, "CSZ")) { return Opcode.CSZ; } if (std.mem.eql(u8, upper_str, "CSP")) { return Opcode.CSP; } if (std.mem.eql(u8, upper_str, "CSOD")) { return Opcode.CSOD; } if (std.mem.eql(u8, upper_str, "CSNN")) { return Opcode.CSNN; } if (std.mem.eql(u8, upper_str, "CSNZ")) { return Opcode.CSNZ; } if (std.mem.eql(u8, upper_str, "CSNP")) { return Opcode.CSNP; } if (std.mem.eql(u8, upper_str, "CSEV")) { return Opcode.CSEV; } if (std.mem.eql(u8, upper_str, "ZSN")) { return Opcode.ZSN; } if (std.mem.eql(u8, upper_str, "ZSZ")) { return Opcode.ZSZ; } if (std.mem.eql(u8, upper_str, "ZSP")) { return Opcode.ZSP; } if (std.mem.eql(u8, upper_str, "ZSOD")) { return Opcode.ZSOD; } if (std.mem.eql(u8, upper_str, "ZSNN")) { return Opcode.ZSNN; } if (std.mem.eql(u8, upper_str, "ZSNZ")) { return Opcode.ZSNZ; } if (std.mem.eql(u8, upper_str, "ZSNP")) { return Opcode.ZSNP; } if (std.mem.eql(u8, upper_str, "ZSEV")) { return Opcode.ZSEV; } if (std.mem.eql(u8, upper_str, "LDB")) { return Opcode.LDB; } if (std.mem.eql(u8, upper_str, "LDBU")) { return Opcode.LDBU; } if (std.mem.eql(u8, upper_str, "LDW")) { return Opcode.LDW; } if (std.mem.eql(u8, upper_str, "LDWU")) { return Opcode.LDWU; } if (std.mem.eql(u8, upper_str, "LDT")) { return Opcode.LDT; } if (std.mem.eql(u8, upper_str, "LDTU")) { return Opcode.LDTU; } if (std.mem.eql(u8, upper_str, "LDO")) { return Opcode.LDO; } if (std.mem.eql(u8, upper_str, "LDOU")) { return Opcode.LDOU; } if (std.mem.eql(u8, upper_str, "LDSF")) { return Opcode.LDSF; } if (std.mem.eql(u8, upper_str, "LDHT")) { return Opcode.LDHT; } if (std.mem.eql(u8, upper_str, "CSWAP")) { return Opcode.CSWAP; } if (std.mem.eql(u8, upper_str, "LDUNC")) { return Opcode.LDUNC; } if (std.mem.eql(u8, upper_str, "LDVTS")) { return Opcode.LDVTS; } if (std.mem.eql(u8, upper_str, "PRELD")) { return Opcode.PRELD; } if (std.mem.eql(u8, upper_str, "PREGO")) { return Opcode.PREGO; } if (std.mem.eql(u8, upper_str, "GO")) { return Opcode.GO; } if (std.mem.eql(u8, upper_str, "STB")) { return Opcode.STB; } if (std.mem.eql(u8, upper_str, "STBU")) { return Opcode.STBU; } if (std.mem.eql(u8, upper_str, "STW")) { return Opcode.STW; } if (std.mem.eql(u8, upper_str, "STWU")) { return Opcode.STWU; } if (std.mem.eql(u8, upper_str, "STT")) { return Opcode.STT; } if (std.mem.eql(u8, upper_str, "STTU")) { return Opcode.STTU; } if (std.mem.eql(u8, upper_str, "STO")) { return Opcode.STO; } if (std.mem.eql(u8, upper_str, "STOU")) { return Opcode.STOU; } if (std.mem.eql(u8, upper_str, "STSF")) { return Opcode.STSF; } if (std.mem.eql(u8, upper_str, "STHT")) { return Opcode.STHT; } if (std.mem.eql(u8, upper_str, "STCO")) { return Opcode.STCO; } if (std.mem.eql(u8, upper_str, "STUNC")) { return Opcode.STUNC; } if (std.mem.eql(u8, upper_str, "SYNCD")) { return Opcode.SYNCD; } if (std.mem.eql(u8, upper_str, "PREST")) { return Opcode.PREST; } if (std.mem.eql(u8, upper_str, "SYNCID")) { return Opcode.SYNCID; } if (std.mem.eql(u8, upper_str, "PUSHGO")) { return Opcode.PUSHGO; } if (std.mem.eql(u8, upper_str, "OR")) { return Opcode.OR; } if (std.mem.eql(u8, upper_str, "ORN")) { return Opcode.ORN; } if (std.mem.eql(u8, upper_str, "NOR")) { return Opcode.NOR; } if (std.mem.eql(u8, upper_str, "XOR")) { return Opcode.XOR; } if (std.mem.eql(u8, upper_str, "AND")) { return Opcode.AND; } if (std.mem.eql(u8, upper_str, "ANDN")) { return Opcode.ANDN; } if (std.mem.eql(u8, upper_str, "NAND")) { return Opcode.NAND; } if (std.mem.eql(u8, upper_str, "NXOR")) { return Opcode.NXOR; } if (std.mem.eql(u8, upper_str, "BDIF")) { return Opcode.BDIF; } if (std.mem.eql(u8, upper_str, "WDIF")) { return Opcode.WDIF; } if (std.mem.eql(u8, upper_str, "TDIF")) { return Opcode.TDIF; } if (std.mem.eql(u8, upper_str, "ODIF")) { return Opcode.ODIF; } if (std.mem.eql(u8, upper_str, "MUX")) { return Opcode.MUX; } if (std.mem.eql(u8, upper_str, "SADD")) { return Opcode.SADD; } if (std.mem.eql(u8, upper_str, "MOR")) { return Opcode.MOR; } if (std.mem.eql(u8, upper_str, "MXOR")) { return Opcode.MXOR; } if (std.mem.eql(u8, upper_str, "SETH")) { return Opcode.SETH; } if (std.mem.eql(u8, upper_str, "SETMH")) { return Opcode.SETMH; } if (std.mem.eql(u8, upper_str, "SETML")) { return Opcode.SETML; } if (std.mem.eql(u8, upper_str, "SETL")) { return Opcode.SETL; } if (std.mem.eql(u8, upper_str, "INCH")) { return Opcode.INCH; } if (std.mem.eql(u8, upper_str, "INCMH")) { return Opcode.INCMH; } if (std.mem.eql(u8, upper_str, "INCML")) { return Opcode.INCML; } if (std.mem.eql(u8, upper_str, "INCL")) { return Opcode.INCL; } if (std.mem.eql(u8, upper_str, "ORH")) { return Opcode.ORH; } if (std.mem.eql(u8, upper_str, "ORMH")) { return Opcode.ORMH; } if (std.mem.eql(u8, upper_str, "ORML")) { return Opcode.ORML; } if (std.mem.eql(u8, upper_str, "ORL")) { return Opcode.ORL; } if (std.mem.eql(u8, upper_str, "ANDNH")) { return Opcode.ANDNH; } if (std.mem.eql(u8, upper_str, "ANDNMH")) { return Opcode.ANDNMH; } if (std.mem.eql(u8, upper_str, "ANDNML")) { return Opcode.ANDNML; } if (std.mem.eql(u8, upper_str, "ANDNL")) { return Opcode.ANDNL; } if (std.mem.eql(u8, upper_str, "JMP")) { return Opcode.JMP; } if (std.mem.eql(u8, upper_str, "PUSHJ")) { return Opcode.PUSHJ; } if (std.mem.eql(u8, upper_str, "GETA")) { return Opcode.GETA; } if (std.mem.eql(u8, upper_str, "PUT")) { return Opcode.PUT; } if (std.mem.eql(u8, upper_str, "POP")) { return Opcode.POP; } if (std.mem.eql(u8, upper_str, "RESUME")) { return Opcode.RESUME; } if (std.mem.eql(u8, upper_str, "SAVE")) { return Opcode.SAVE; } if (std.mem.eql(u8, upper_str, "UNSAVE")) { return Opcode.UNSAVE; } if (std.mem.eql(u8, upper_str, "SYNC")) { return Opcode.SYNC; } if (std.mem.eql(u8, upper_str, "SWYM")) { return Opcode.SWYM; } if (std.mem.eql(u8, upper_str, "GET")) { return Opcode.GET; } if (std.mem.eql(u8, upper_str, "TRIP")) { return Opcode.TRIP; } return error.NoOpcode; } test "Opcodes encode correctly" { const test_cases = [_][]const u8{ // opcodes "TRAP", "FCMP", "FUN", "FEQL", "FADD", "FIX", "FSUB", "FIXU", "FLOT", "FLOTU", "SFLOT", "SFLOTU", "FMUL", "FCMPE", "FUNE", "FEQLE", "FDIV", "FSQRT", "FREM", "FINT", "MUL", "MULU", "DIV", "DIVU", "ADD", "ADDU", "SUB", "SUBU", "2ADDU", "4ADDU", "8ADDU", "16ADDU", "CMP", "CMPU", "NEG", "NEGU", "SL", "SLU", "SR", "SRU", "BN", "BZ", "BP", "BOD", "BNN", "BNZ", "BNP", "BEV", "PBN", "PBZ", "PBP", "PBOD", "PBNN", "PBNZ", "PBNP", "PBEV", "CSN", "CSZ", "CSP", "CSOD", "CSNN", "CSNZ", "CSNP", "CSEV", "ZSN", "ZSZ", "ZSP", "ZSOD", "ZSNN", "ZSNZ", "ZSNP", "ZSEV", "LDB", "LDBU", "LDW", "LDWU", "LDT", "LDTU", "LDO", "LDOU", "LDSF", "LDHT", "CSWAP", "LDUNC", "LDVTS", "PRELD", "PREGO", "GO", "STB", "STBU", "STW", "STWU", "STT", "STTU", "STO", "STOU", "STSF", "STHT", "STCO", "STUNC", "SYNCD", "PREST", "SYNCID", "PUSHGO", "OR", "ORN", "NOR", "XOR", "AND", "ANDN", "NAND", "NXOR", "BDIF", "WDIF", "TDIF", "ODIF", "MUX", "SADD", "MOR", "MXOR", "SETH", "SETMH", "SETML", "SETL", "INCH", "INCMH", "INCML", "INCL", "ORH", "ORMH", "ORML", "ORL", "ANDNH", "ANDNMH", "ANDNML", "ANDNL", "JMP", "PUSHJ", "GETA", "PUT", "POP", "RESUME", "SAVE", "UNSAVE", "SYNC", "SWYM", "GET", "TRIP", // pseudo ops "IS", "GREG", "LOC", "BYTE", "WYDE", "TETRA", "OCTA", }; const expected = [_]Operation{ Operation{ .opcode = Opcode.TRAP }, Operation{ .opcode = Opcode.FCMP }, Operation{ .opcode = Opcode.FUN }, Operation{ .opcode = Opcode.FEQL }, Operation{ .opcode = Opcode.FADD }, Operation{ .opcode = Opcode.FIX }, Operation{ .opcode = Opcode.FSUB }, Operation{ .opcode = Opcode.FIXU }, Operation{ .opcode = Opcode.FLOT }, Operation{ .opcode = Opcode.FLOTU }, Operation{ .opcode = Opcode.SFLOT }, Operation{ .opcode = Opcode.SFLOTU }, Operation{ .opcode = Opcode.FMUL }, Operation{ .opcode = Opcode.FCMPE }, Operation{ .opcode = Opcode.FUNE }, Operation{ .opcode = Opcode.FEQLE }, Operation{ .opcode = Opcode.FDIV }, Operation{ .opcode = Opcode.FSQRT }, Operation{ .opcode = Opcode.FREM }, Operation{ .opcode = Opcode.FINT }, Operation{ .opcode = Opcode.MUL }, Operation{ .opcode = Opcode.MULU }, Operation{ .opcode = Opcode.DIV }, Operation{ .opcode = Opcode.DIVU }, Operation{ .opcode = Opcode.ADD }, Operation{ .opcode = Opcode.ADDU }, Operation{ .opcode = Opcode.SUB }, Operation{ .opcode = Opcode.SUBU }, Operation{ .opcode = Opcode._2ADDU }, Operation{ .opcode = Opcode._4ADDU }, Operation{ .opcode = Opcode._8ADDU }, Operation{ .opcode = Opcode._16ADDU }, Operation{ .opcode = Opcode.CMP }, Operation{ .opcode = Opcode.CMPU }, Operation{ .opcode = Opcode.NEG }, Operation{ .opcode = Opcode.NEGU }, Operation{ .opcode = Opcode.SL }, Operation{ .opcode = Opcode.SLU }, Operation{ .opcode = Opcode.SR }, Operation{ .opcode = Opcode.SRU }, Operation{ .opcode = Opcode.BN }, Operation{ .opcode = Opcode.BZ }, Operation{ .opcode = Opcode.BP }, Operation{ .opcode = Opcode.BOD }, Operation{ .opcode = Opcode.BNN }, Operation{ .opcode = Opcode.BNZ }, Operation{ .opcode = Opcode.BNP }, Operation{ .opcode = Opcode.BEV }, Operation{ .opcode = Opcode.PBN }, Operation{ .opcode = Opcode.PBZ }, Operation{ .opcode = Opcode.PBP }, Operation{ .opcode = Opcode.PBOD }, Operation{ .opcode = Opcode.PBNN }, Operation{ .opcode = Opcode.PBNZ }, Operation{ .opcode = Opcode.PBNP }, Operation{ .opcode = Opcode.PBEV }, Operation{ .opcode = Opcode.CSN }, Operation{ .opcode = Opcode.CSZ }, Operation{ .opcode = Opcode.CSP }, Operation{ .opcode = Opcode.CSOD }, Operation{ .opcode = Opcode.CSNN }, Operation{ .opcode = Opcode.CSNZ }, Operation{ .opcode = Opcode.CSNP }, Operation{ .opcode = Opcode.CSEV }, Operation{ .opcode = Opcode.ZSN }, Operation{ .opcode = Opcode.ZSZ }, Operation{ .opcode = Opcode.ZSP }, Operation{ .opcode = Opcode.ZSOD }, Operation{ .opcode = Opcode.ZSNN }, Operation{ .opcode = Opcode.ZSNZ }, Operation{ .opcode = Opcode.ZSNP }, Operation{ .opcode = Opcode.ZSEV }, Operation{ .opcode = Opcode.LDB }, Operation{ .opcode = Opcode.LDBU }, Operation{ .opcode = Opcode.LDW }, Operation{ .opcode = Opcode.LDWU }, Operation{ .opcode = Opcode.LDT }, Operation{ .opcode = Opcode.LDTU }, Operation{ .opcode = Opcode.LDO }, Operation{ .opcode = Opcode.LDOU }, Operation{ .opcode = Opcode.LDSF }, Operation{ .opcode = Opcode.LDHT }, Operation{ .opcode = Opcode.CSWAP }, Operation{ .opcode = Opcode.LDUNC }, Operation{ .opcode = Opcode.LDVTS }, Operation{ .opcode = Opcode.PRELD }, Operation{ .opcode = Opcode.PREGO }, Operation{ .opcode = Opcode.GO }, Operation{ .opcode = Opcode.STB }, Operation{ .opcode = Opcode.STBU }, Operation{ .opcode = Opcode.STW }, Operation{ .opcode = Opcode.STWU }, Operation{ .opcode = Opcode.STT }, Operation{ .opcode = Opcode.STTU }, Operation{ .opcode = Opcode.STO }, Operation{ .opcode = Opcode.STOU }, Operation{ .opcode = Opcode.STSF }, Operation{ .opcode = Opcode.STHT }, Operation{ .opcode = Opcode.STCO }, Operation{ .opcode = Opcode.STUNC }, Operation{ .opcode = Opcode.SYNCD }, Operation{ .opcode = Opcode.PREST }, Operation{ .opcode = Opcode.SYNCID }, Operation{ .opcode = Opcode.PUSHGO }, Operation{ .opcode = Opcode.OR }, Operation{ .opcode = Opcode.ORN }, Operation{ .opcode = Opcode.NOR }, Operation{ .opcode = Opcode.XOR }, Operation{ .opcode = Opcode.AND }, Operation{ .opcode = Opcode.ANDN }, Operation{ .opcode = Opcode.NAND }, Operation{ .opcode = Opcode.NXOR }, Operation{ .opcode = Opcode.BDIF }, Operation{ .opcode = Opcode.WDIF }, Operation{ .opcode = Opcode.TDIF }, Operation{ .opcode = Opcode.ODIF }, Operation{ .opcode = Opcode.MUX }, Operation{ .opcode = Opcode.SADD }, Operation{ .opcode = Opcode.MOR }, Operation{ .opcode = Opcode.MXOR }, Operation{ .opcode = Opcode.SETH }, Operation{ .opcode = Opcode.SETMH }, Operation{ .opcode = Opcode.SETML }, Operation{ .opcode = Opcode.SETL }, Operation{ .opcode = Opcode.INCH }, Operation{ .opcode = Opcode.INCMH }, Operation{ .opcode = Opcode.INCML }, Operation{ .opcode = Opcode.INCL }, Operation{ .opcode = Opcode.ORH }, Operation{ .opcode = Opcode.ORMH }, Operation{ .opcode = Opcode.ORML }, Operation{ .opcode = Opcode.ORL }, Operation{ .opcode = Opcode.ANDNH }, Operation{ .opcode = Opcode.ANDNMH }, Operation{ .opcode = Opcode.ANDNML }, Operation{ .opcode = Opcode.ANDNL }, Operation{ .opcode = Opcode.JMP }, Operation{ .opcode = Opcode.PUSHJ }, Operation{ .opcode = Opcode.GETA }, Operation{ .opcode = Opcode.PUT }, Operation{ .opcode = Opcode.POP }, Operation{ .opcode = Opcode.RESUME }, Operation{ .opcode = Opcode.SAVE }, Operation{ .opcode = Opcode.UNSAVE }, Operation{ .opcode = Opcode.SYNC }, Operation{ .opcode = Opcode.SWYM }, Operation{ .opcode = Opcode.GET }, Operation{ .opcode = Opcode.TRIP }, Operation{ .pseudo_op = PseudoOp.IS }, Operation{ .pseudo_op = PseudoOp.GREG }, Operation{ .pseudo_op = PseudoOp.LOC }, Operation{ .pseudo_op = PseudoOp.BYTE }, Operation{ .pseudo_op = PseudoOp.WYDE }, Operation{ .pseudo_op = PseudoOp.TETRA }, Operation{ .pseudo_op = PseudoOp.OCTA }, }; for (0..test_cases.len) |i| { const operation = try parseOp(std.testing.allocator, test_cases[i]); try std.testing.expectEqual(expected[i], operation); } } test "Invalid opcodes return error" { var operation = parseOp(std.testing.allocator, "ALKSFDJ"); try std.testing.expectEqual(error.NoOpcode, operation); operation = parseOp(std.testing.allocator, "ADDI"); try std.testing.expectEqual(error.NoOpcode, operation); }