Use `<>` instead of `!=` everywhere

ad47874009b6086f03c0f9bbf424efc90c20fb3b755125210cd754f3e5cad365
Alexis Sellier committed ago 1 parent c92591c9
compiler/radiance.rad +1 -1
402 402
    let options = lower::LowerOptions { debug: ctx.debug, buildTest: ctx.config.buildTest };
403 403
    let mut low = lower::lowerer(res, &ctx.graph, entryPkg.name, &mut res.arena, options);
404 404
405 405
    // Lower all packages except entry.
406 406
    for i in 0..ctx.packageCount {
407 -
        if i != entryIdx {
407 +
        if i <> entryIdx {
408 408
            try lowerPackage(ctx, res, &mut low, &mut ctx.packages[i], false);
409 409
        }
410 410
    }
411 411
    // Lower entry package.
412 412
    let defaultFn = try lowerPackage(ctx, res, &mut low, &mut ctx.packages[entryIdx], true);
lib/std/arch/rv64/decode.rad +7 -7
44 44
//////////////////////////
45 45
46 46
/// Extract I-type immediate (sign-extended).
47 47
export fn immI(instr: u32) -> i32 {
48 48
    let imm = instr >> 20;
49 -
    if (imm & 0x800) != 0 {
49 +
    if (imm & 0x800) <> 0 {
50 50
        return (imm | 0xFFFFF000) as i32;
51 51
    }
52 52
    return imm as i32;
53 53
}
54 54
55 55
/// Extract S-type immediate (sign-extended).
56 56
export fn immS(instr: u32) -> i32 {
57 57
    let lo = (instr >> 7) & 0x1F;
58 58
    let hi = (instr >> 25) & 0x7F;
59 59
    let imm = (hi << 5) | lo;
60 -
    if (imm & 0x800) != 0 {
60 +
    if (imm & 0x800) <> 0 {
61 61
        return (imm | 0xFFFFF000) as i32;
62 62
    }
63 63
    return imm as i32;
64 64
}
65 65
68 68
    let imm11 = (instr >> 7) & 0x1;
69 69
    let imm4_1 = (instr >> 8) & 0xF;
70 70
    let imm10_5 = (instr >> 25) & 0x3F;
71 71
    let imm12 = (instr >> 31) & 0x1;
72 72
    let imm = (imm12 << 12) | (imm11 << 11) | (imm10_5 << 5) | (imm4_1 << 1);
73 -
    if (imm & 0x1000) != 0 {
73 +
    if (imm & 0x1000) <> 0 {
74 74
        return (imm | 0xFFFFE000) as i32;
75 75
    }
76 76
    return imm as i32;
77 77
}
78 78
81 81
    let imm19_12 = (instr >> 12) & 0xFF;
82 82
    let imm11 = (instr >> 20) & 0x1;
83 83
    let imm10_1 = (instr >> 21) & 0x3FF;
84 84
    let imm20 = (instr >> 31) & 0x1;
85 85
    let imm = (imm20 << 20) | (imm19_12 << 12) | (imm11 << 11) | (imm10_1 << 1);
86 -
    if (imm & 0x100000) != 0 {
86 +
    if (imm & 0x100000) <> 0 {
87 87
        return (imm | 0xFFE00000) as i32;
88 88
    }
89 89
    return imm as i32;
90 90
}
91 91
92 92
/// Extract U-type immediate (upper 20 bits, sign-extended).
93 93
export fn immU(instr: u32) -> i32 {
94 94
    let imm = instr >> 12;
95 -
    if (imm & 0x80000) != 0 {
95 +
    if (imm & 0x80000) <> 0 {
96 96
        return (imm | 0xFFF00000) as i32;
97 97
    }
98 98
    return imm as i32;
99 99
}
100 100
261 261
                case encode::F3_OR   => return Instr::Ori { rd, rs1, imm },
262 262
                case encode::F3_AND  => return Instr::Andi { rd, rs1, imm },
263 263
                case encode::F3_SLL  => return Instr::Slli { rd, rs1, shamt: imm & 0x3F },
264 264
                case encode::F3_SRL  => {
265 265
                    let shamt = imm & 0x3F;
266 -
                    if (imm & 0x400) != 0 {
266 +
                    if (imm & 0x400) <> 0 {
267 267
                        return Instr::Srai { rd, rs1, shamt };
268 268
                    } else {
269 269
                        return Instr::Srli { rd, rs1, shamt };
270 270
                    }
271 271
                },
316 316
            match f3 {
317 317
                case encode::F3_ADD => return Instr::Addiw { rd, rs1, imm },
318 318
                case encode::F3_SLL => return Instr::Slliw { rd, rs1, shamt: imm & 0x1F },
319 319
                case encode::F3_SRL => {
320 320
                    let shamt = imm & 0x1F;
321 -
                    if (imm & 0x400) != 0 {
321 +
                    if (imm & 0x400) <> 0 {
322 322
                        return Instr::Sraiw { rd, rs1, shamt };
323 323
                    } else {
324 324
                        return Instr::Srliw { rd, rs1, shamt };
325 325
                    }
326 326
                },
lib/std/arch/rv64/emit.rad +3 -3
157 157
158 158
    // Build list of callee-saved registers with offsets.
159 159
    let mut offset = totalSize - (super::DWORD_SIZE * 3);
160 160
    for reg, i in super::CALLEE_SAVED {
161 161
        // Check if this register is in use.
162 -
        if (usedCalleeSaved & (1 << i)) != 0 {
162 +
        if (usedCalleeSaved & (1 << i)) <> 0 {
163 163
            frame.savedRegs[frame.savedRegsLen] = SavedReg {
164 164
                reg,
165 165
                offset,
166 166
            };
167 167
            frame.savedRegsLen += 1;
405 405
export fn splitImm(imm: i32) -> SplitImm {
406 406
    let lo = imm & 0xFFF;
407 407
    let mut hi = (imm >> 12) & 0xFFFFF;
408 408
    // If `lo`'s sign bit is set, it will be sign-extended to negative.
409 409
    // Compensate by incrementing `hi`.
410 -
    if (lo & 0x800) != 0 {
410 +
    if (lo & 0x800) <> 0 {
411 411
        hi += 1;
412 412
        return SplitImm { hi, lo: lo | 0xFFFFF000 as i32 };
413 413
    }
414 414
    return SplitImm { hi, lo };
415 415
}
446 446
    // Check if the value fits in 32 bits (sign-extended).
447 447
    let lo32 = imm as i32;
448 448
    if lo32 as i64 == imm {
449 449
        let s = splitImm(lo32);
450 450
        emit(e, encode::lui(rd, s.hi));
451 -
        if s.lo != 0 {
451 +
        if s.lo <> 0 {
452 452
            emit(e, encode::addiw(rd, rd, s.lo));
453 453
        }
454 454
        return;
455 455
    }
456 456
    // Full 64-bit immediate: use only rd, no scratch registers.
lib/std/arch/rv64/encode.rad +3 -3
468 468
/// Branch if equal: `if (rs1 == rs2) pc += imm`.
469 469
export fn beq(rs1: gen::Reg, rs2: gen::Reg, imm: i32) -> u32 {
470 470
    return encodeB(OP_BRANCH, rs1, rs2, F3_BEQ, imm);
471 471
}
472 472
473 -
/// Branch if not equal: `if (rs1 != rs2) pc += imm`.
473 +
/// Branch if not equal: `if (rs1 <> rs2) pc += imm`.
474 474
export fn bne(rs1: gen::Reg, rs2: gen::Reg, imm: i32) -> u32 {
475 475
    return encodeB(OP_BRANCH, rs1, rs2, F3_BNE, imm);
476 476
}
477 477
478 478
/// Branch if less than (signed): `if (rs1 < rs2) pc += imm`.
587 587
/// Implemented as `sltiu rd, rs, 1`.
588 588
export fn seqz(rd: gen::Reg, rs: gen::Reg) -> u32 {
589 589
    return sltiu(rd, rs, 1);
590 590
}
591 591
592 -
/// Set if not equal to zero: `rd = (rs != 0) ? 1 : 0`.
592 +
/// Set if not equal to zero: `rd = (rs <> 0) ? 1 : 0`.
593 593
/// Implemented as `sltu rd, zero, rs`.
594 594
export fn snez(rd: gen::Reg, rs: gen::Reg) -> u32 {
595 595
    return sltu(rd, super::ZERO, rs);
596 596
}
597 597
598 598
/// Branch if equal to zero: `if (rs == 0) pc += imm`.
599 599
export fn beqz(rs: gen::Reg, imm: i32) -> u32 {
600 600
    return beq(rs, super::ZERO, imm);
601 601
}
602 602
603 -
/// Branch if not equal to zero: `if (rs != 0) pc += imm`.
603 +
/// Branch if not equal to zero: `if (rs <> 0) pc += imm`.
604 604
export fn bnez(rs: gen::Reg, imm: i32) -> u32 {
605 605
    return bne(rs, super::ZERO, imm);
606 606
}
607 607
608 608
/// Call: `jal ra, imm`.
lib/std/arch/rv64/isel.rad +17 -17
211 211
    return rd;
212 212
}
213 213
214 214
/// Emit a move instruction if source and destination differ.
215 215
fn emitMv(s: *mut Selector, rd: gen::Reg, rs: gen::Reg) {
216 -
    if *rd != *rs {
216 +
    if *rd <> *rs {
217 217
        emit::emit(s.e, encode::mv(rd, rs));
218 218
    }
219 219
}
220 220
221 221
/// Emit zero-extension from a sub-word type to the full register width.
255 255
/// Resolve a value, trap if zero (unless known non-zero), and return the register.
256 256
fn resolveAndTrapIfZero(s: *mut Selector, b: il::Val) -> gen::Reg {
257 257
    let rs2 = resolveVal(s, super::SCRATCH2, b);
258 258
    let mut knownNonZero = false;
259 259
    if let case il::Val::Imm(imm) = b {
260 -
        knownNonZero = imm != 0;
260 +
        knownNonZero = imm <> 0;
261 261
    }
262 262
    if not knownNonZero {
263 263
        emit::emit(s.e, encode::bne(rs2, super::ZERO, super::INSTR_SIZE * 2));
264 264
        emit::emit(s.e, encode::ebreak());
265 265
    }
494 494
495 495
            // For large blits where both pointers are in real registers,
496 496
            // use an inline loop instead of unrolled LD/SD pairs.
497 497
            let dwordBytes = remaining & ~(super::DWORD_SIZE - 1);
498 498
            let canLoop = not bothSpilled
499 -
                and *rsrc != *super::SCRATCH1 and *rsrc != *super::SCRATCH2
500 -
                and *rdst != *super::SCRATCH1 and *rdst != *super::SCRATCH2;
499 +
                and *rsrc <> *super::SCRATCH1 and *rsrc <> *super::SCRATCH2
500 +
                and *rdst <> *super::SCRATCH1 and *rdst <> *super::SCRATCH2;
501 501
502 502
            if canLoop and dwordBytes >= super::BLIT_LOOP_THRESHOLD {
503 503
                emit::emitAddImm(s.e, super::SCRATCH1, rsrc, dwordBytes);
504 504
505 505
                let loopStart = s.e.codeLen;
506 506
507 507
                emit::emitLd(s.e, super::SCRATCH2, rsrc, 0);
508 508
                emit::emitSd(s.e, super::SCRATCH2, rdst, 0);
509 509
                emit::emit(s.e, encode::addi(rsrc, rsrc, super::DWORD_SIZE));
510 510
511 -
                if *rdst != *rsrc {
511 +
                if *rdst <> *rsrc {
512 512
                    emit::emit(s.e, encode::addi(rdst, rdst, super::DWORD_SIZE));
513 513
                }
514 514
                let brOff = (loopStart as i32 - s.e.codeLen as i32) * super::INSTR_SIZE;
515 515
516 516
                emit::emit(s.e, encode::bne(rsrc, super::SCRATCH1, brOff));
523 523
            // it does, advance the base registers by the accumulated
524 524
            // offset and reset to zero.
525 525
            while remaining >= super::DWORD_SIZE {
526 526
                if offset > super::MAX_IMM - super::DWORD_SIZE {
527 527
                    emit::emitAddImm(s.e, rsrc, rsrc, offset);
528 -
                    if *rdst != *rsrc {
528 +
                    if *rdst <> *rsrc {
529 529
                        emit::emitAddImm(s.e, rdst, rdst, offset);
530 530
                    }
531 531
                    offset = 0;
532 532
                }
533 533
                if let off = srcReload {
541 541
                remaining -= super::DWORD_SIZE;
542 542
            }
543 543
            if remaining >= super::WORD_SIZE {
544 544
                if offset > super::MAX_IMM - super::WORD_SIZE {
545 545
                    emit::emitAddImm(s.e, rsrc, rsrc, offset);
546 -
                    if *rdst != *rsrc {
546 +
                    if *rdst <> *rsrc {
547 547
                        emit::emitAddImm(s.e, rdst, rdst, offset);
548 548
                    }
549 549
                    offset = 0;
550 550
                }
551 551
                if let off = srcReload {
559 559
                remaining -= super::WORD_SIZE;
560 560
            }
561 561
            while remaining > 0 {
562 562
                if offset > super::MAX_IMM - 1 {
563 563
                    emit::emitAddImm(s.e, rsrc, rsrc, offset);
564 -
                    if *rdst != *rsrc {
564 +
                    if *rdst <> *rsrc {
565 565
                        emit::emitAddImm(s.e, rdst, rdst, offset);
566 566
                    }
567 567
                    offset = 0;
568 568
                }
569 569
                if let off = srcReload {
578 578
            }
579 579
            // Restore base registers if they were advanced (never happens
580 580
            // in the both-spilled case since size <= MAX_IMM).
581 581
            if not bothSpilled {
582 582
                let advanced = staticSize as i32 - offset;
583 -
                if advanced != 0 {
583 +
                if advanced <> 0 {
584 584
                    emit::emitAddImm(s.e, rsrc, rsrc, 0 - advanced);
585 -
                    if *rdst != *rsrc {
585 +
                    if *rdst <> *rsrc {
586 586
                        emit::emitAddImm(s.e, rdst, rdst, 0 - advanced);
587 587
                    }
588 588
                }
589 589
            }
590 590
        },
603 603
                let rs = resolveVal(s, super::SCRATCH1, v);
604 604
                emitMv(s, super::A0, rs);
605 605
            }
606 606
            // Skip the jump to epilogue if this RET is in the last block,
607 607
            // since the epilogue immediately follows.
608 -
            if frame.totalSize != 0 and blockIdx + 1 == frame.epilogueBlock {
608 +
            if frame.totalSize <> 0 and blockIdx + 1 == frame.epilogueBlock {
609 609
                // Epilogue is the next block; fallthrough is sufficient.
610 610
            } else {
611 611
                emit::emitReturn(s.e, frame);
612 612
            }
613 613
        },
614 614
        case il::Instr::Jmp { target, args } => {
615 615
            // Move arguments to target block's parameter registers.
616 616
            emitBlockArgs(s, func, target, args);
617 617
            // Skip branch if target is the next block (fallthrough).
618 -
            if target != blockIdx + 1 {
618 +
            if target <> blockIdx + 1 {
619 619
                emit::recordBranch(s.e, target, emit::BranchKind::Jump);
620 620
            }
621 621
        },
622 622
        case il::Instr::Br { op, typ, a, b, thenTarget, thenArgs, elseTarget, elseArgs } => {
623 623
            // Use zero register directly for immediate `0` operands.
672 672
                panic "selectInstr: both `then` and `else` have block arguments";
673 673
            } else if thenArgs.len > 0 {
674 674
                emit::recordBranch(s.e, elseTarget, emit::BranchKind::InvertedCond { op, rs1, rs2 });
675 675
                emitBlockArgs(s, func, thenTarget, thenArgs);
676 676
                // Skip trailing jump if then is the next block (fallthrough).
677 -
                if thenTarget != blockIdx + 1 {
677 +
                if thenTarget <> blockIdx + 1 {
678 678
                    emit::recordBranch(s.e, thenTarget, emit::BranchKind::Jump);
679 679
                }
680 680
            } else if thenTarget == blockIdx + 1 and elseArgs.len == 0 {
681 681
                // Then is the next block and no else args: invert the
682 682
                // condition to branch to else and fall through to then.
683 683
                emit::recordBranch(s.e, elseTarget, emit::BranchKind::InvertedCond { op, rs1, rs2 });
684 684
            } else {
685 685
                emit::recordBranch(s.e, thenTarget, emit::BranchKind::Cond { op, rs1, rs2 });
686 686
                emitBlockArgs(s, func, elseTarget, elseArgs);
687 687
                // Skip trailing jump if else is the next block (fallthrough).
688 -
                if elseTarget != blockIdx + 1 {
688 +
                if elseTarget <> blockIdx + 1 {
689 689
                    emit::recordBranch(s.e, elseTarget, emit::BranchKind::Jump);
690 690
                }
691 691
            }
692 692
        },
693 693
        case il::Instr::Switch { val, defaultTarget, defaultArgs, cases } => {
1057 1057
    // Number of pending moves.
1058 1058
    let mut numPending: u32 = 0;
1059 1059
1060 1060
    for i in 0..n {
1061 1061
        let dst = dsts[i];
1062 -
        if dst != super::ZERO { // Skip entries with no destination.
1062 +
        if dst <> super::ZERO { // Skip entries with no destination.
1063 1063
            match args[i] {
1064 1064
                case il::Val::Reg(r) => {
1065 1065
                    if let _ = regalloc::spill::spillSlot(&s.ralloc.spill, r) {
1066 1066
                        // Spilled value needs load, not a register move.
1067 1067
                        pending[i] = true;
1068 1068
                        numPending += 1;
1069 1069
                    } else {
1070 1070
                        let src = getReg(s, r);
1071 -
                        if src != dst {
1071 +
                        if src <> dst {
1072 1072
                            // Register-to-register move needed.
1073 1073
                            srcRegs[i] = src;
1074 1074
                            isRegMove[i] = true;
1075 1075
                            pending[i] = true;
1076 1076
                            numPending += 1;
1103 1103
                let dst = dsts[i];
1104 1104
                let mut isReady = true;
1105 1105
1106 1106
                // Check if `dst` is used as source by any other pending register move.
1107 1107
                for j in 0..n {
1108 -
                    if j != i and pending[j] and isRegMove[j] and srcRegs[j] == dst {
1108 +
                    if j <> i and pending[j] and isRegMove[j] and srcRegs[j] == dst {
1109 1109
                        isReady = false;
1110 1110
                        break;
1111 1111
                    }
1112 1112
                }
1113 1113
                if isReady {
lib/std/fmt.rad +4 -4
23 23
    if x == 0 {
24 24
        i -= 1;
25 25
        buffer[i] = '0';
26 26
    } else {
27 27
        // Write digits backwards from the end of the buffer.
28 -
        while x != 0 {
28 +
        while x <> 0 {
29 29
            i -= 1;
30 30
            buffer[i] = ('0' + (x % 10) as u8);
31 31
            x /= 10;
32 32
        }
33 33
    }
47 47
    if x == 0 {
48 48
        i -= 1;
49 49
        buffer[i] = '0';
50 50
    } else {
51 51
        // Write digits backwards from the end of the buffer.
52 -
        while x != 0 {
52 +
        while x <> 0 {
53 53
            i -= 1;
54 54
            buffer[i] = '0' + (x % 10) as u8;
55 55
            x /= 10;
56 56
        }
57 57
        // Add the negative sign if needed.
72 72
73 73
    if x == 0 {
74 74
        i -= 1;
75 75
        buffer[i] = '0';
76 76
    } else {
77 -
        while x != 0 {
77 +
        while x <> 0 {
78 78
            i -= 1;
79 79
            buffer[i] = ('0' + (x % 10) as u8);
80 80
            x /= 10;
81 81
        }
82 82
    }
92 92
    let mut i: u32 = buffer.len;
93 93
    if x == 0 {
94 94
        i -= 1;
95 95
        buffer[i] = '0';
96 96
    } else {
97 -
        while x != 0 {
97 +
        while x <> 0 {
98 98
            i -= 1;
99 99
            buffer[i] = '0' + (x % 10) as u8;
100 100
            x /= 10;
101 101
        }
102 102
        if neg {
lib/std/lang/alloc/tests.rad +1 -1
116 116
117 117
    let p2 = a.func(a.ctx, 8, 8);
118 118
    try testing::expect(super::used(&arena) == 24);
119 119
120 120
    // Verify the pointers are distinct.
121 -
    try testing::expect(p1 as u64 != p2 as u64);
121 +
    try testing::expect(p1 as u64 <> p2 as u64);
122 122
}
lib/std/lang/ast.rad +2 -2
64 64
    return false;
65 65
}
66 66
67 67
/// Check if an attribute set includes the given attribute.
68 68
export fn hasAttribute(attrs: u32, attr: Attribute) -> bool {
69 -
    return (attrs & (attr as u32)) != 0;
69 +
    return (attrs & (attr as u32)) <> 0;
70 70
}
71 71
72 72
/// Signedness of an integer type.
73 73
export union Signedness {
74 74
    /// Signed, eg. `i8`.
124 124
    /// Right shift (`>>`).
125 125
    Shr,
126 126
127 127
    /// Equality comparison (`==`).
128 128
    Eq,
129 -
    /// Inequality comparison (`!=`).
129 +
    /// Inequality comparison (`<>`).
130 130
    Ne,
131 131
    /// Less-than comparison (`<`).
132 132
    Lt,
133 133
    /// Greater-than comparison (`>`).
134 134
    Gt,
lib/std/lang/ast/printer.rad +1 -1
16 16
        case super::BinaryOp::BitOr => return "|",
17 17
        case super::BinaryOp::BitXor => return "^",
18 18
        case super::BinaryOp::Shl => return "<<",
19 19
        case super::BinaryOp::Shr => return ">>",
20 20
        case super::BinaryOp::Eq => return "==",
21 -
        case super::BinaryOp::Ne => return "!=",
21 +
        case super::BinaryOp::Ne => return "<>",
22 22
        case super::BinaryOp::Lt => return "<",
23 23
        case super::BinaryOp::Gt => return ">",
24 24
        case super::BinaryOp::Lte => return "<=",
25 25
        case super::BinaryOp::Gte => return ">=",
26 26
        case super::BinaryOp::And => return "and",
lib/std/lang/gen/bitset.rad +3 -3
84 84
        return false;
85 85
    }
86 86
    let word = n / 32;
87 87
    let b = n % 32;
88 88
89 -
    return (bs.bits[word] & (1 << b)) != 0;
89 +
    return (bs.bits[word] & (1 << b)) <> 0;
90 90
}
91 91
92 92
/// Count the number of set bits.
93 93
export fn count(bs: *Bitset) -> u32 {
94 94
    let mut total: u32 = 0;
95 95
    let numWords = bs.bits.len;
96 96
    for i in 0..numWords {
97 97
        let word = bs.bits[i];
98 -
        if word != 0 {
98 +
        if word <> 0 {
99 99
            total += popCount(word);
100 100
        }
101 101
    }
102 102
    return total;
103 103
}
141 141
    let maxWords = max(numWordsA, numWordsB);
142 142
143 143
    for i in 0..maxWords {
144 144
        let wordA = a.bits[i] if i < numWordsA else 0;
145 145
        let wordB = b.bits[i] if i < numWordsB else 0;
146 -
        if wordA != wordB {
146 +
        if wordA <> wordB {
147 147
            return false;
148 148
        }
149 149
    }
150 150
    return true;
151 151
}
lib/std/lang/gen/regalloc/liveness.rad +2 -2
9 9
//!   REPEAT UNTIL changed == false
10 10
//!     changed = false
11 11
//!     FOR EACH BLOCK b IN POST-ORDER DO
12 12
//!       newOut = UNION(liveIn[succ] FOR EACH SUCCESSOR OF b)
13 13
//!       newIn = uses[b] | (newOut - defs[b])
14 -
//!       IF newIn != liveIn[b] OR newOut != liveOut[b] THEN
14 +
//!       IF newIn <> liveIn[b] OR newOut <> liveOut[b] THEN
15 15
//!         changed = true
16 16
//!         liveIn[b] = newIn
17 17
//!         liveOut[b] = newOut
18 18
//!
19 19
//! Usage:
147 147
) -> bool {
148 148
    let numWords = dst.bits.len;
149 149
    let mut changed = false;
150 150
    for i in 0..numWords {
151 151
        let newWord = uses.bits[i] | (liveOut.bits[i] & ~defs.bits[i]);
152 -
        if dst.bits[i] != newWord {
152 +
        if dst.bits[i] <> newWord {
153 153
            dst.bits[i] = newWord;
154 154
            changed = true;
155 155
        }
156 156
    }
157 157
    return changed;
lib/std/lang/lower.rad +34 -34
350 350
351 351
/// Append a data value to the builder.
352 352
fn dataBuilderPush(b: *mut DataValueBuilder, value: il::DataValue) {
353 353
    b.values.append(value, b.allocator);
354 354
355 -
    if value.item != il::DataItem::Undef {
355 +
    if value.item <> il::DataItem::Undef {
356 356
        b.allUndef = false;
357 357
    }
358 358
}
359 359
360 360
/// Return the accumulated values.
1662 1662
    }
1663 1663
}
1664 1664
1665 1665
/// Compare two data value slices for structural equality.
1666 1666
fn dataValuesEq(a: *[il::DataValue], b: *[il::DataValue]) -> bool {
1667 -
    if a.len != b.len {
1667 +
    if a.len <> b.len {
1668 1668
        return false;
1669 1669
    }
1670 1670
    for i in 0..a.len {
1671 -
        if a[i].count != b[i].count {
1671 +
        if a[i].count <> b[i].count {
1672 1672
            return false;
1673 1673
        }
1674 1674
        if not dataItemEq(a[i].item, b[i].item) {
1675 1675
            return false;
1676 1676
        }
1969 1969
    switchToBlock(self, target);
1970 1970
}
1971 1971
1972 1972
/// Emit a conditional branch based on `cond`.
1973 1973
fn emitBr(self: *mut FnLowerer, cond: il::Reg, thenBlock: BlockId, elseBlock: BlockId) throws (LowerError) {
1974 -
    assert thenBlock != elseBlock;
1974 +
    assert thenBlock <> elseBlock;
1975 1975
    emit(self, il::Instr::Br {
1976 1976
        op: il::CmpOp::Ne,
1977 1977
        typ: il::Type::W32,
1978 1978
        a: il::Val::Reg(cond),
1979 1979
        b: il::Val::Imm(0),
1994 1994
    a: il::Val,
1995 1995
    b: il::Val,
1996 1996
    thenBlock: BlockId,
1997 1997
    elseBlock: BlockId
1998 1998
) throws (LowerError) {
1999 -
    assert thenBlock != elseBlock;
1999 +
    assert thenBlock <> elseBlock;
2000 2000
    emit(self, il::Instr::Br {
2001 2001
        op, typ, a, b,
2002 2002
        thenTarget: *thenBlock, thenArgs: &mut [],
2003 2003
        elseTarget: *elseBlock, elseArgs: &mut [],
2004 2004
    });
2370 2370
2371 2371
/// Add a predecessor edge from `pred` to `target`.
2372 2372
/// Must be called before the target block is sealed. Duplicates are ignored.
2373 2373
fn addPredecessor(self: *mut FnLowerer, target: BlockId, pred: BlockId) {
2374 2374
    let blk = getBlockMut(self, target);
2375 -
    assert blk.sealState != Sealed::Yes, "addPredecessor: adding predecessor to sealed block";
2375 +
    assert blk.sealState <> Sealed::Yes, "addPredecessor: adding predecessor to sealed block";
2376 2376
    let preds = &mut blk.preds;
2377 2377
    for i in 0..preds.len {
2378 2378
        if preds[i] == *pred { // Avoid duplicate predecessor entries.
2379 2379
            return;
2380 2380
        }
2418 2418
    self.loopDepth += 1;
2419 2419
}
2420 2420
2421 2421
/// Exit the current loop context.
2422 2422
fn exitLoop(self: *mut FnLowerer) {
2423 -
    assert self.loopDepth != 0, "exitLoop: loopDepth is zero";
2423 +
    assert self.loopDepth <> 0, "exitLoop: loopDepth is zero";
2424 2424
    self.loopDepth -= 1;
2425 2425
}
2426 2426
2427 2427
/// Get the current loop context.
2428 2428
fn currentLoop(self: *mut FnLowerer) -> ?*mut LoopCtx {
2556 2556
) -> Var {
2557 2557
    let id = self.vars.len;
2558 2558
    self.vars.append(VarData { name, type, mutable, addressTaken: false }, self.allocator);
2559 2559
2560 2560
    let v = Var(id);
2561 -
    if self.currentBlock != nil {
2561 +
    if self.currentBlock <> nil {
2562 2562
        defVar(self, v, val);
2563 2563
    }
2564 2564
    return v;
2565 2565
}
2566 2566
2604 2604
        }
2605 2605
        // Single predecessor means no merge needed, variable is implicitly
2606 2606
        // available without a block parameter.
2607 2607
        if blk.preds.len == 1 {
2608 2608
            let pred = BlockId(blk.preds[0]);
2609 -
            if *pred != *block {
2609 +
            if *pred <> *block {
2610 2610
                let val = try useVarInBlock(self, pred, v);
2611 2611
                blk.vars[*v] = val; // Cache.
2612 2612
                return val;
2613 2613
            }
2614 2614
        }
2674 2674
///
2675 2675
/// This function creates a fresh register `%1` as a block parameter, then patches
2676 2676
/// each predecessor's jump to pass its value of `x` as an argument.
2677 2677
fn createBlockParam(self: *mut FnLowerer, block: BlockId, v: Var) -> il::Val throws (LowerError) {
2678 2678
    // Entry block must not have block parameters.
2679 -
    assert block != self.entryBlock, "createBlockParam: entry block must not have block parameters";
2679 +
    assert block <> self.entryBlock, "createBlockParam: entry block must not have block parameters";
2680 2680
    // Allocate a register to hold the merged value.
2681 2681
    let reg = nextReg(self);
2682 2682
    let type = getVar(self, v).type;
2683 2683
2684 2684
    // Create block parameter and add it to the block.
2744 2744
    for predId in blk.preds {
2745 2745
        let pred = BlockId(predId);
2746 2746
        // This may recursively trigger more block arg resolution if the
2747 2747
        // predecessor also needs to look up the variable from its predecessors.
2748 2748
        let val = try useVarInBlock(self, pred, v);
2749 -
        assert val != il::Val::Undef, "createBlockParam: predecessor provides undef value for block parameter";
2749 +
        assert val <> il::Val::Undef, "createBlockParam: predecessor provides undef value for block parameter";
2750 2750
        patchTerminatorArg(self, pred, *block, paramIdx, val);
2751 2751
    }
2752 2752
}
2753 2753
2754 2754
/// Check if a block parameter is trivial, i.e. all predecessors provide
2769 2769
        // itself. We skip self-references when checking for trivial phis.
2770 2770
        if let reg = paramReg {
2771 2771
            if val == reg {
2772 2772
                // Self-reference, skip this predecessor.
2773 2773
            } else if let sv = sameVal {
2774 -
                if val != sv {
2774 +
                if val <> sv {
2775 2775
                    // Multiple different values, not trivial.
2776 2776
                    return nil;
2777 2777
                }
2778 2778
            } else {
2779 2779
                sameVal = val;
2869 2869
    self: *mut FnLowerer,
2870 2870
    fnType: resolver::FnType,
2871 2871
    astParams: *mut [*ast::Node],
2872 2872
    receiverName: ?*ast::Node
2873 2873
) -> *[il::Param] throws (LowerError) {
2874 -
    let offset: u32 = 1 if self.returnReg != nil else 0;
2874 +
    let offset: u32 = 1 if self.returnReg <> nil else 0;
2875 2875
    let totalLen = fnType.paramTypes.len as u32 + offset;
2876 2876
    if totalLen == 0 {
2877 2877
        return &[];
2878 2878
    }
2879 2879
    assert fnType.paramTypes.len as u32 <= resolver::MAX_FN_PARAMS;
2984 2984
        case resolver::Type::Optional(_) => return tvalTagReg(self, reg),
2985 2985
        else => return reg,
2986 2986
    }
2987 2987
}
2988 2988
2989 -
/// Lower an optional nil check (`opt == nil` or `opt != nil`).
2989 +
/// Lower an optional nil check (`opt == nil` or `opt <> nil`).
2990 2990
fn lowerNilCheck(self: *mut FnLowerer, opt: *ast::Node, isEq: bool) -> il::Val throws (LowerError) {
2991 2991
    let optTy = try typeOf(self, opt);
2992 -
    // Handle `nil == nil` or `nil != nil`.
2992 +
    // Handle `nil == nil` or `nil <> nil`.
2993 2993
    if optTy == resolver::Type::Nil {
2994 2994
        return il::Val::Imm(1) if isEq else il::Val::Imm(0);
2995 2995
    }
2996 2996
    let val = try lowerExpr(self, opt);
2997 2997
    let cmpReg = try optionalNilReg(self, val, optTy);
3460 3460
        let prongScope = enterVarScope(self);
3461 3461
        let case ast::NodeValue::MatchProng(prong) = prongNode.value
3462 3462
            else panic "lowerMatch: expected match prong";
3463 3463
3464 3464
        let isLastArm = i + 1 == prongs.len;
3465 -
        let hasGuard = prong.guard != nil;
3465 +
        let hasGuard = prong.guard <> nil;
3466 3466
        let catchAll = resolver::isProngCatchAll(self.low.resolver, prongNode);
3467 3467
3468 3468
        // Entry block: guard block if present, otherwise the body block.
3469 3469
        // The guard block must be created before the body block so that
3470 3470
        // block indices are in reverse post-order (RPO), which the register
3510 3510
        }
3511 3511
3512 3512
        // Evaluate guard if present; can still fail to next arm.
3513 3513
        if let g = prong.guard {
3514 3514
            try emitCondBranch(self, g, bodyBlock, nextArm);
3515 -
        } else if *currentBlock(self) != *bodyBlock {
3515 +
        } else if *currentBlock(self) <> *bodyBlock {
3516 3516
            // Nested tests changed the current block. Create a new body block
3517 3517
            // after the nest blocks to maintain RPO ordering, and jump to it.
3518 3518
            bodyBlock = try createBlock(self, bodyLabel);
3519 3519
            try emitJmp(self, bodyBlock);
3520 3520
        }
3586 3586
) throws (LowerError) {
3587 3587
    // If guard present, pattern match jumps to @guard, then guard evaluation
3588 3588
    // jumps to `successBlock` or `failBlock`. Otherwise, jump directly to
3589 3589
    // `successBlock`.
3590 3590
    let mut targetBlock: BlockId = undefined;
3591 -
    if pat.guard != nil {
3591 +
    if pat.guard <> nil {
3592 3592
        targetBlock = try createBlock(self, "guard");
3593 3593
        *successBlock = try createBlock(self, successLabel);
3594 3594
    } else {
3595 3595
        targetBlock = *successBlock;
3596 3596
    }
3615 3615
    }
3616 3616
    // Handle guard: on success jump to `successBlock`, on failure jump to `failBlock`.
3617 3617
    if let g = pat.guard {
3618 3618
        try emitCondBranch(self, g, *successBlock, failBlock);
3619 3619
        try switchToAndSeal(self, *successBlock);
3620 -
    } else if *currentBlock(self) != *targetBlock {
3620 +
    } else if *currentBlock(self) <> *targetBlock {
3621 3621
        // Nested tests changed the current block. Create a new success block
3622 3622
        // after the nest blocks to maintain RPO ordering, and jump to it.
3623 3623
        *successBlock = try createBlock(self, successLabel);
3624 3624
3625 3625
        try emitJmp(self, *successBlock);
3879 3879
    };
3880 3880
    let case resolver::SymbolData::Variant { type: payloadType, index, .. } = sym.data else {
3881 3881
        return nil;
3882 3882
    };
3883 3883
    // Only void variants can use tag-only comparison.
3884 -
    if payloadType != resolver::Type::Void {
3884 +
    if payloadType <> resolver::Type::Void {
3885 3885
        return nil;
3886 3886
    }
3887 3887
    return index as i64;
3888 3888
}
3889 3889
3971 3971
    } else {
3972 3972
        emitStoreW64At(self, il::Val::Imm(tag), dst, TVAL_TAG_OFFSET);
3973 3973
    }
3974 3974
3975 3975
    if let val = payload {
3976 -
        if payloadType != resolver::Type::Void {
3976 +
        if payloadType <> resolver::Type::Void {
3977 3977
            try emitStore(self, dst, valOffset, payloadType, val);
3978 3978
        }
3979 3979
    }
3980 3980
    return il::Val::Reg(dst);
3981 3981
}
4264 4264
    let tagB = loadTag(self, b, offset + TVAL_TAG_OFFSET, il::Type::W8);
4265 4265
4266 4266
    // For simple inner types (no unions/nested optionals), use branchless comparison.
4267 4267
    // Unions and nested optionals may contain uninitialized payload bytes
4268 4268
    // when nil, so they need a guarded comparison.
4269 -
    let isUnion = unionInfoFromType(inner) != nil;
4269 +
    let isUnion = unionInfoFromType(inner) <> nil;
4270 4270
    let mut isOptional = false;
4271 4271
    if let case resolver::Type::Optional(_) = inner {
4272 4272
        isOptional = true;
4273 4273
    }
4274 4274
    if not isUnion and not isOptional {
4369 4369
    let tagBlock = try createBlock(self, "eq#tag");
4370 4370
4371 4371
    // Compare tags: if they differ, jump to merge with `false`; otherwise check payloads.
4372 4372
    let falseArgs = try allocVal(self, il::Val::Imm(0));
4373 4373
4374 -
    assert tagBlock != mergeBlock;
4374 +
    assert tagBlock <> mergeBlock;
4375 4375
4376 4376
    // TODO: Use the helper once the compiler supports more than eight function params.
4377 4377
    emit(self, il::Instr::Br {
4378 4378
        op: il::CmpOp::Eq, typ: il::Type::W8, a: tagA, b: tagB,
4379 4379
        thenTarget: *tagBlock, thenArgs: &mut [],
4650 4650
    let unionInfo = unionInfoFromType(unionTy) else {
4651 4651
        throw LowerError::MissingMetadata;
4652 4652
    };
4653 4653
    let valOffset = unionInfo.valOffset as i32;
4654 4654
    let mut payloadVal: ?il::Val = nil;
4655 -
    if payloadType != resolver::Type::Void {
4655 +
    if payloadType <> resolver::Type::Void {
4656 4656
        let case resolver::Type::Nominal(payloadNominal) = payloadType else {
4657 4657
            throw LowerError::MissingMetadata;
4658 4658
        };
4659 4659
        payloadVal = try lowerRecordCtor(self, payloadNominal, call.args);
4660 4660
    }
4723 4723
    // value. Otherwise, we have to compute it.
4724 4724
    let mut count = endVal;
4725 4725
4726 4726
    // Only compute range offset and count if the start value is not
4727 4727
    // statically known to be zero.
4728 -
    if startVal != il::Val::Imm(0) {
4728 +
    if startVal <> il::Val::Imm(0) {
4729 4729
        // Offset the data pointer by the start value.
4730 4730
        dataReg = emitElem(
4731 4731
            self, resolver::getTypeLayout(*info.itemType).size, dataReg, startVal
4732 4732
        );
4733 4733
        // Compute the count as `end - start`.
5385 5385
            let endVal = try lowerExpr(self, endExpr);
5386 5386
            let iterType = ilType(self.low, *valType);
5387 5387
            let valVar = newVar(self, bindingName, iterType, false, startVal);
5388 5388
5389 5389
            let mut indexVar: ?Var = nil;
5390 -
            if indexName != nil { // Optional index always starts at zero.
5390 +
            if indexName <> nil { // Optional index always starts at zero.
5391 5391
                indexVar = newVar(self, indexName, il::Type::W32, false, il::Val::Imm(0));
5392 5392
            }
5393 5393
            let iter = ForIter::Range {
5394 5394
                valVar, indexVar, endVal, valType: iterType,
5395 5395
                unsigned: isUnsignedType(*valType),
5412 5412
            // Declare index value binidng.
5413 5413
            let idxVar = newVar(self, indexName, il::Type::W32, false, il::Val::Imm(0));
5414 5414
5415 5415
            // Declare element value binding.
5416 5416
            let mut valVar: ?Var = nil;
5417 -
            if bindingName != nil {
5417 +
            if bindingName <> nil {
5418 5418
                valVar = newVar(
5419 5419
                    self,
5420 5420
                    bindingName,
5421 5421
                    ilType(self.low, *elemType),
5422 5422
                    false,
5679 5679
        }
5680 5680
    }
5681 5681
    // Lower operands.
5682 5682
    let a = try lowerExpr(self, binop.left);
5683 5683
    let b = try lowerExpr(self, binop.right);
5684 -
    let isComparison = cmpOpFrom(binop.op, false) != nil;
5684 +
    let isComparison = cmpOpFrom(binop.op, false) <> nil;
5685 5685
5686 5686
    // The result type for comparisons is always `bool`, while for arithmetic
5687 5687
    // operations, it's the operand type. We set this appropriately here.
5688 5688
    let nodeTy = try typeOf(self, node);
5689 5689
    let mut resultTy = nodeTy;
5913 5913
    }
5914 5914
}
5915 5915
5916 5916
/// Lower a `@sliceOf(ptr, len)` or `@sliceOf(ptr, len, cap)` builtin call.
5917 5917
fn lowerSliceOf(self: *mut FnLowerer, node: *ast::Node, args: *mut [*ast::Node]) -> il::Val throws (LowerError) {
5918 -
    if args.len != 2 and args.len != 3 {
5918 +
    if args.len <> 2 and args.len <> 3 {
5919 5919
        throw LowerError::InvalidArgCount;
5920 5920
    }
5921 5921
    let sliceTy = try typeOf(self, node);
5922 5922
    let case resolver::Type::Slice { item, mutable } = sliceTy else {
5923 5923
        throw LowerError::ExpectedSliceOrArray;
5987 5987
        // Extract the success payload. If the result type differs from the payload
5988 5988
        // type (e.g. `try?` wrapping `T` into `?T`), wrap the value.
5989 5989
        let payloadVal = tvalPayloadVal(self, base, okValueTy, RESULT_VAL_OFFSET);
5990 5990
        let mut okVal = payloadVal;
5991 5991
5992 -
        if t.returnsOptional and tryExprTy != okValueTy {
5992 +
        if t.returnsOptional and tryExprTy <> okValueTy {
5993 5993
            okVal = try wrapInOptional(self, payloadVal, tryExprTy);
5994 5994
        }
5995 5995
        try emitStore(self, slot, 0, tryExprTy, okVal);
5996 5996
    }
5997 5997
    // Jump to merge block if unterminated.
6011 6011
        // `try ... catch` -- handle the error.
6012 6012
        let firstNode = t.catches[0];
6013 6013
        let case ast::NodeValue::CatchClause(first) = firstNode.value
6014 6014
            else panic "lowerTry: expected CatchClause";
6015 6015
6016 -
        if first.typeNode != nil or t.catches.len > 1 {
6016 +
        if first.typeNode <> nil or t.catches.len > 1 {
6017 6017
            // Typed multi-catch: switch on global error tag.
6018 6018
            try lowerMultiCatch(self, t.catches, calleeInfo, base, tagReg, &mut mergeBlock);
6019 6019
        } else {
6020 6020
            // Single untyped catch clause.
6021 6021
            let savedVarsLen = enterVarScope(self);
6477 6477
            args,
6478 6478
        });
6479 6479
        return il::Val::Reg(dst);
6480 6480
    }
6481 6481
    let mut dst: ?il::Reg = nil;
6482 -
    if retTy != resolver::Type::Void {
6482 +
    if retTy <> resolver::Type::Void {
6483 6483
        dst = nextReg(self);
6484 6484
    }
6485 6485
    emit(self, il::Instr::Call {
6486 6486
        retTy: ilType(self.low, retTy),
6487 6487
        dst,
6587 6587
    }
6588 6588
}
6589 6589
6590 6590
/// Lower an ecall intrinsic: `ecall(num, a0, a1, a2, a3) -> i32`.
6591 6591
fn lowerEcall(self: *mut FnLowerer, call: ast::Call) -> il::Val throws (LowerError) {
6592 -
    if call.args.len != 5 {
6592 +
    if call.args.len <> 5 {
6593 6593
        throw LowerError::InvalidArgCount;
6594 6594
    }
6595 6595
    let num = try lowerExpr(self, call.args[0]);
6596 6596
    let a0 = try lowerExpr(self, call.args[1]);
6597 6597
    let a1 = try lowerExpr(self, call.args[2]);
6604 6604
    return il::Val::Reg(dst);
6605 6605
}
6606 6606
6607 6607
/// Lower an ebreak intrinsic: `ebreak()`.
6608 6608
fn lowerEbreak(self: *mut FnLowerer, call: ast::Call) -> il::Val throws (LowerError) {
6609 -
    if call.args.len != 0 {
6609 +
    if call.args.len <> 0 {
6610 6610
        throw LowerError::InvalidArgCount;
6611 6611
    }
6612 6612
    emit(self, il::Instr::Ebreak);
6613 6613
6614 6614
    return il::Val::Undef;
lib/std/lang/module.rad +1 -1
411 411
    if path.len < SOURCE_EXT.len {
412 412
        return nil;
413 413
    }
414 414
    let extStart = path.len - SOURCE_EXT.len;
415 415
    for ext, i in SOURCE_EXT {
416 -
        if path[extStart + i] != ext {
416 +
        if path[extStart + i] <> ext {
417 417
            return nil;
418 418
        }
419 419
    }
420 420
    return &path[..extStart];
421 421
}
lib/std/lang/parser.rad +7 -7
114 114
            return { op: ast::BinaryOp::BitXor, prec: 3 },
115 115
        case scanner::TokenKind::Pipe =>
116 116
            return { op: ast::BinaryOp::BitOr, prec: 2 },
117 117
        case scanner::TokenKind::EqualEqual =>
118 118
            return { op: ast::BinaryOp::Eq, prec: 1 },
119 -
        case scanner::TokenKind::BangEqual =>
119 +
        case scanner::TokenKind::LtGt =>
120 120
            return { op: ast::BinaryOp::Ne, prec: 1 },
121 121
        case scanner::TokenKind::Lt =>
122 122
            return { op: ast::BinaryOp::Lt, prec: 1 },
123 123
        case scanner::TokenKind::Gt =>
124 124
            return { op: ast::BinaryOp::Gt, prec: 1 },
392 392
fn parseCondExpr(p: *mut Parser, thenExpr: *ast::Node) -> *ast::Node
393 393
    throws (ParseError)
394 394
{
395 395
    // Only parse conditional expressions in normal context.
396 396
    // In conditional context, `if` is used for guards.
397 -
    if p.context != Context::Normal {
397 +
    if p.context <> Context::Normal {
398 398
        return thenExpr;
399 399
    }
400 400
    if not consume(p, scanner::TokenKind::If) {
401 401
        return thenExpr;
402 402
    }
477 477
                result = try parseSubscriptOrSlice(p, result);
478 478
            }
479 479
            case scanner::TokenKind::LParen => {
480 480
                result = try parseCall(p, result);
481 481
            }
482 -
            case scanner::TokenKind::LBrace if p.context != Context::Condition => {
482 +
            case scanner::TokenKind::LBrace if p.context <> Context::Condition => {
483 483
                result = try parseRecordLit(p, result);
484 484
            }
485 485
            else => {
486 486
                break;
487 487
            }
741 741
            return try parseRangeExpr(p, nil);
742 742
        }
743 743
        case scanner::TokenKind::LBrace => {
744 744
            // Anonymous record literal: { x: 1, y: 2 }.
745 745
            // Only allowed in normal context, not in conditions.
746 -
            if p.context != Context::Normal {
746 +
            if p.context <> Context::Normal {
747 747
                throw failParsing(p, "unexpected `{` in this context");
748 748
            }
749 749
            return try parseRecordLit(p, nil);
750 750
        }
751 751
        else => {
919 919
{
920 920
    // TODO: Why is `parseStmt` checking for attributes?
921 921
    // We should have a `parseDecl` which is top-level, and `parseStmt` which
922 922
    // is inside functions.
923 923
    let attrs = parseAttributes(p);
924 -
    if attrs != nil {
924 +
    if attrs <> nil {
925 925
        let allowed: bool =
926 926
            p.current.kind == scanner::TokenKind::Fn or
927 927
            p.current.kind == scanner::TokenKind::Union or
928 928
            p.current.kind == scanner::TokenKind::Record or
929 929
            p.current.kind == scanner::TokenKind::Mod or
1650 1650
1651 1651
                let field = try parseNameTypeValue(p);
1652 1652
                let type = field.type else {
1653 1653
                    throw failParsing(p, "expected type annotation in record field");
1654 1654
                };
1655 -
                if field.alignment != nil {
1655 +
                if field.alignment <> nil {
1656 1656
                    throw failParsing(p, "record fields cannot specify alignment");
1657 1657
                }
1658 -
                if field.value != nil and mode != RecordFieldMode::Labeled {
1658 +
                if field.value <> nil and mode <> RecordFieldMode::Labeled {
1659 1659
                    throw failParsing(p, "record fields cannot have initializers");
1660 1660
                }
1661 1661
                recordField = ast::NodeValue::RecordField {
1662 1662
                    field: field.name, type, value: field.value,
1663 1663
                };
lib/std/lang/parser/tests.rad +17 -22
426 426
@test fn testParseStringEscape() throws (testing::TestError) {
427 427
    // Tab and newline.
428 428
    let r1 = try! parseExprStr("\"hello\\tworld\\n\"");
429 429
    let case ast::NodeValue::String(s1) = r1.value if s1.len == 12
430 430
        else throw testing::TestError::Failed;
431 -
    if s1[5] != '\t' {
431 +
    if s1[5] <> '\t' {
432 432
        throw testing::TestError::Failed;
433 433
    }
434 -
    if s1[11] != '\n' {
434 +
    if s1[11] <> '\n' {
435 435
        throw testing::TestError::Failed;
436 436
    }
437 437
438 438
    // Escaped quote.
439 439
    let r2 = try! parseExprStr("\"\\\"\"");
440 440
    let case ast::NodeValue::String(s2) = r2.value if s2.len == 1
441 441
        else throw testing::TestError::Failed;
442 -
    if s2[0] != '"' {
442 +
    if s2[0] <> '"' {
443 443
        throw testing::TestError::Failed;
444 444
    }
445 445
446 446
    // Escaped backslash.
447 447
    let r3 = try! parseExprStr("\"\\\\\"");
448 448
    let case ast::NodeValue::String(s3) = r3.value if s3.len == 1
449 449
        else throw testing::TestError::Failed;
450 -
    if s3[0] != '\\' {
450 +
    if s3[0] <> '\\' {
451 451
        throw testing::TestError::Failed;
452 452
    }
453 453
454 454
    // Mixed escapes.
455 455
    let r4 = try! parseExprStr("\"a\\nb\\tc\"");
456 456
    let case ast::NodeValue::String(s4) = r4.value if s4.len == 5
457 457
        else throw testing::TestError::Failed;
458 -
    if s4[0] != 'a' {
458 +
    if s4[0] <> 'a' {
459 459
        throw testing::TestError::Failed;
460 460
    }
461 -
    if s4[1] != '\n' {
461 +
    if s4[1] <> '\n' {
462 462
        throw testing::TestError::Failed;
463 463
    }
464 -
    if s4[2] != 'b' {
464 +
    if s4[2] <> 'b' {
465 465
        throw testing::TestError::Failed;
466 466
    }
467 -
    if s4[3] != '\t' {
467 +
    if s4[3] <> '\t' {
468 468
        throw testing::TestError::Failed;
469 469
    }
470 -
    if s4[4] != 'c' {
470 +
    if s4[4] <> 'c' {
471 471
        throw testing::TestError::Failed;
472 472
    }
473 473
}
474 474
475 475
/// Test parsing placeholder/underscore.
709 709
@test fn testParseLetCaseElseWithGuard() throws (testing::TestError) {
710 710
    let root = try! parseStmtStr("let case Variant(x) = opt if x > 0 else { return };");
711 711
    let case ast::NodeValue::LetElse(letElse) = root.value
712 712
        else throw testing::TestError::Failed;
713 713
714 -
    try testing::expect(letElse.pattern.guard != nil);
714 +
    try testing::expect(letElse.pattern.guard <> nil);
715 715
716 716
    let guardNode = letElse.pattern.guard else throw testing::TestError::Failed;
717 717
    let case ast::NodeValue::BinOp(cmp) = guardNode.value
718 718
        else throw testing::TestError::Failed;
719 719
    try testing::expect(cmp.op == ast::BinaryOp::Gt);
1010 1010
        else throw testing::TestError::Failed;
1011 1011
    let case ast::TypeSig::Pointer { valueType: ptrTarget, mutable: _ } = p1
1012 1012
        else throw testing::TestError::Failed;
1013 1013
    try expectIntType(ptrTarget, 1, ast::Signedness::Unsigned);
1014 1014
1015 -
    try testing::expect(sig.returnType != nil);
1015 +
    try testing::expect(sig.returnType <> nil);
1016 1016
}
1017 1017
1018 1018
/// Test parsing a function type with a throws clause.
1019 1019
@test fn testParseTypeFnThrows() throws (testing::TestError) {
1020 1020
    let node = try! parseTypeStr("fn (i32) -> bool throws (Error, Other)");
2252 2252
    let case ast::NodeValue::BinOp(op5) = modOp.value
2253 2253
        else throw testing::TestError::Failed;
2254 2254
    try testing::expect(op5.op == ast::BinaryOp::Mod);
2255 2255
}
2256 2256
2257 -
/// Test parsing comparison binary operators (==, !=, <>).
2257 +
/// Test parsing comparison binary operators (==, <>).
2258 2258
@test fn testParseBinOpEq() throws (testing::TestError) {
2259 2259
    let eq = try! parseExprStr("a == b");
2260 2260
    let case ast::NodeValue::BinOp(op1) = eq.value
2261 2261
        else throw testing::TestError::Failed;
2262 2262
    try testing::expect(op1.op == ast::BinaryOp::Eq);
2263 2263
2264 -
    let ne = try! parseExprStr("x != y");
2264 +
    let ne = try! parseExprStr("x <> y");
2265 2265
    let case ast::NodeValue::BinOp(op2) = ne.value
2266 2266
        else throw testing::TestError::Failed;
2267 2267
    try testing::expect(op2.op == ast::BinaryOp::Ne);
2268 -
2269 -
    let altNe = try! parseExprStr("x <> y");
2270 -
    let case ast::NodeValue::BinOp(op3) = altNe.value
2271 -
        else throw testing::TestError::Failed;
2272 -
    try testing::expect(op3.op == ast::BinaryOp::Ne);
2273 2268
}
2274 2269
2275 2270
/// Test parsing comparison binary operators.
2276 2271
@test fn testParseBinOpGtLt() throws (testing::TestError) {
2277 2272
    let lt = try! parseExprStr("a < b");
2511 2506
    let case ast::NodeValue::UnionDeclVariant(var0) = v0.value
2512 2507
        else throw testing::TestError::Failed;
2513 2508
    try expectIdent(var0.name, "Ok");
2514 2509
    try testing::expect(var0.index == 0);
2515 2510
    try testing::expect(var0.type == nil);
2516 -
    try testing::expect(var0.value != nil);
2511 +
    try testing::expect(var0.value <> nil);
2517 2512
2518 2513
    let v1 = variants[1];
2519 2514
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2520 2515
        else throw testing::TestError::Failed;
2521 2516
    try expectIdent(var1.name, "Error");
2522 2517
    try testing::expect(var1.index == 1);
2523 -
    try testing::expect(var1.value != nil);
2518 +
    try testing::expect(var1.value <> nil);
2524 2519
2525 2520
    let v2 = variants[2];
2526 2521
    let case ast::NodeValue::UnionDeclVariant(var2) = v2.value
2527 2522
        else throw testing::TestError::Failed;
2528 2523
    try expectIdent(var2.name, "Pending");
2529 2524
    try testing::expect(var2.index == 2);
2530 -
    try testing::expect(var2.value != nil);
2525 +
    try testing::expect(var2.value <> nil);
2531 2526
}
2532 2527
2533 2528
/// Test parsing a union with payload and tag-only variants.
2534 2529
@test fn testParseEnumWithPayloads() throws (testing::TestError) {
2535 2530
    let node = try! parseStmtStr("union Result { Ok(bool), Error }");
2570 2565
2571 2566
    let v1 = variants[1];
2572 2567
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2573 2568
        else throw testing::TestError::Failed;
2574 2569
    try expectIdent(var1.name, "Some");
2575 -
    try testing::expect(var1.type != nil);
2570 +
    try testing::expect(var1.type <> nil);
2576 2571
}
2577 2572
2578 2573
/// Test parsing named record literals with named fields.
2579 2574
@test fn testParseNamedRecordLiteralNamed() throws (testing::TestError) {
2580 2575
    let r1 = try! parseExprStr("Point { x: 5, y: 10 }");
lib/std/lang/resolver.rad +43 -43
938 938
    // If our error list is full, just return an error without recording it.
939 939
    if self.errors.len >= self.errors.cap {
940 940
        return ResolveError::Failure;
941 941
    }
942 942
    // Don't record more than one error per node.
943 -
    if let n = node; errorForNode(self, n) != nil {
943 +
    if let n = node; errorForNode(self, n) <> nil {
944 944
        return ResolveError::Failure;
945 945
    }
946 946
    let idx = self.errors.len;
947 947
    self.errors = @sliceOf(self.errors.ptr, idx + 1, self.errors.cap);
948 948
    self.errors[idx] = Error { kind, node, moduleId: self.currentMod };
1035 1035
    assert self.loopDepth < MAX_LOOP_DEPTH, "visitLoop: loop nesting depth exceeded";
1036 1036
    self.loopStack[self.loopDepth] = LoopCtx { hasBreak: false };
1037 1037
    self.loopDepth += 1;
1038 1038
1039 1039
    let ty = try infer(self, body) catch {
1040 -
        assert self.loopDepth != 0, "visitLoop: loop depth underflow";
1040 +
        assert self.loopDepth <> 0, "visitLoop: loop depth underflow";
1041 1041
        self.loopDepth -= 1;
1042 1042
        throw ResolveError::Failure;
1043 1043
    };
1044 1044
    // Pop and check if break was encountered.
1045 1045
    self.loopDepth -= 1;
1485 1485
    let mut maxVarSize: u32 = 0;
1486 1486
    let mut maxVarAlign: u32 = 1;
1487 1487
    let mut isAllVoid: bool = true;
1488 1488
1489 1489
    for variant in variants {
1490 -
        if variant.valueType != Type::Void {
1490 +
        if variant.valueType <> Type::Void {
1491 1491
            isAllVoid = false;
1492 1492
            let payloadLayout = getTypeLayout(variant.valueType);
1493 1493
            maxVarSize = max(maxVarSize, payloadLayout.size);
1494 1494
            maxVarAlign = max(maxVarAlign, payloadLayout.alignment);
1495 1495
        }
1678 1678
    match to {
1679 1679
        case Type::Array(lhs) => {
1680 1680
            let case Type::Array(rhs) = from
1681 1681
                else return nil;
1682 1682
1683 -
            if lhs.length != rhs.length {
1683 +
            if lhs.length <> rhs.length {
1684 1684
                return nil;
1685 1685
            }
1686 1686
            // For array literals, check each element individually for
1687 1687
            // assignability.
1688 1688
            match rval.value {
1749 1749
                    return Coercion::TraitObject { traitInfo, inst };
1750 1750
                }
1751 1751
            }
1752 1752
            // Identity: same trait object.
1753 1753
            if let case Type::TraitObject { traitInfo: rhsTrait, mutable: rhsMutable } = from {
1754 -
                if traitInfo != rhsTrait {
1754 +
                if traitInfo <> rhsTrait {
1755 1755
                    return nil;
1756 1756
                }
1757 1757
                if lhsMutable and not rhsMutable {
1758 1758
                    return nil;
1759 1759
                }
1791 1791
                // For unsuffixed integer expressions (`Type::Int`), only
1792 1792
                // validate literals directly written by the programmer.
1793 1793
                // Folded results (e.g. `0 - 65`) may not fit the target
1794 1794
                // type but are valid wrapping arithmetic at runtime.
1795 1795
                if let value = constValueEntry(self, rval) {
1796 -
                    if from != Type::Int or isNumberLiteral(rval) {
1796 +
                    if from <> Type::Int or isNumberLiteral(rval) {
1797 1797
                        if validateConstIntRange(value, to) {
1798 1798
                            return Coercion::Identity;
1799 1799
                        }
1800 1800
                        return nil;
1801 1801
                    }
1818 1818
    return nil;
1819 1819
}
1820 1820
1821 1821
/// Check if two function type descriptors are structurally equivalent.
1822 1822
fn fnTypeEqual(a: *FnType, b: *FnType) -> bool {
1823 -
    if a.paramTypes.len != b.paramTypes.len {
1823 +
    if a.paramTypes.len <> b.paramTypes.len {
1824 1824
        return false;
1825 1825
    }
1826 -
    if a.throwList.len != b.throwList.len {
1826 +
    if a.throwList.len <> b.throwList.len {
1827 1827
        return false;
1828 1828
    }
1829 1829
    if not typesEqual(*a.returnType, *b.returnType) {
1830 1830
        return false;
1831 1831
    }
1978 1978
/// Check that a node's type is equal to the expected type.
1979 1979
fn checkEqual(self: *mut Resolver, node: *ast::Node, expected: Type) -> Type
1980 1980
    throws (ResolveError)
1981 1981
{
1982 1982
    let actualTy = try visit(self, node, expected);
1983 -
    if actualTy != expected {
1983 +
    if actualTy <> expected {
1984 1984
        throw emitTypeMismatch(self, node, TypeMismatch { expected, actual: actualTy });
1985 1985
    }
1986 1986
    return actualTy;
1987 1987
}
1988 1988
2309 2309
    node: *ast::Node,
2310 2310
    access: ast::Access,
2311 2311
    path: *[*[u8]],
2312 2312
    scope: *Scope
2313 2313
) -> *mut Symbol throws (ResolveError) {
2314 -
    assert path.len != 0, "resolvePath: empty path";
2314 +
    assert path.len <> 0, "resolvePath: empty path";
2315 2315
    // Start by finding the root of the path.
2316 2316
    let root = path[0];
2317 2317
    let sym = findInScopeRecursive(scope, root, isAnySymbol) else
2318 2318
        throw emitError(self, node, ErrorKind::UnresolvedSymbol(root));
2319 2319
    let suffix = &path[1..];
2730 2730
/// Ensure the `default` attribute is only applied to functions.
2731 2731
fn ensureDefaultAttrNotAllowed(self: *mut Resolver, node: *ast::Node, attrs: u32)
2732 2732
    throws (ResolveError)
2733 2733
{
2734 2734
    let defaultBit = ast::Attribute::Default as u32;
2735 -
    if (attrs & defaultBit) != 0 {
2735 +
    if (attrs & defaultBit) <> 0 {
2736 2736
        throw emitError(self, node, ErrorKind::DefaultAttrOnlyOnFn);
2737 2737
    }
2738 2738
}
2739 2739
2740 2740
/// Analyze a block node, allocating a nested lexical scope.
2784 2784
    if let a = decl.alignment {
2785 2785
        let case ast::NodeValue::Align { value } = a.value
2786 2786
            else panic "resolveLet: expected Align node";
2787 2787
        alignment = try checkSizeInt(self, value);
2788 2788
    }
2789 -
    assert bindingTy != Type::Unknown;
2789 +
    assert bindingTy <> Type::Unknown;
2790 2790
2791 2791
    // Alignment must be zero or a power of two.
2792 -
    if alignment != 0 and (alignment & (alignment - 1)) != 0 {
2792 +
    if alignment <> 0 and (alignment & (alignment - 1)) <> 0 {
2793 2793
        throw emitError(self, decl.value, ErrorKind::InvalidAlignmentValue(alignment));
2794 2794
    }
2795 2795
    let _ = try bindValueIdent(self, decl.ident, node, bindingTy, decl.mutable, alignment, 0);
2796 2796
    setNodeType(self, decl.value, bindingTy);
2797 2797
2967 2967
    }
2968 2968
}
2969 2969
2970 2970
/// Check that the argument count of a constructor pattern or call matches the record field count.
2971 2971
fn checkRecordArity(self: *mut Resolver, args: *mut [*ast::Node], recInfo: RecordType, pattern: *ast::Node) throws (ResolveError) {
2972 -
    if args.len != recInfo.fields.len {
2972 +
    if args.len <> recInfo.fields.len {
2973 2973
        throw emitError(self, pattern, ErrorKind::RecordFieldCountMismatch(CountMismatch {
2974 2974
            expected: recInfo.fields.len as u32,
2975 2975
            actual: args.len,
2976 2976
        }));
2977 2977
    }
3095 3095
3096 3096
        let bodyTy = try checkAssignable(self, body, Type::Void) catch e {
3097 3097
            exitFn(self);
3098 3098
            throw e;
3099 3099
        };
3100 -
        if retTy != Type::Void and bodyTy != Type::Never {
3100 +
        if retTy <> Type::Void and bodyTy <> Type::Never {
3101 3101
            exitFn(self);
3102 3102
            throw emitError(self, body, ErrorKind::FnMissingReturn);
3103 3103
        }
3104 3104
        exitFn(self);
3105 3105
    } else if not isExtern {
3311 3311
            else throw emitError(self, receiver, ErrorKind::TraitReceiverMismatch);
3312 3312
        let case ast::TypeSig::Nominal(nameNode) = innerSig
3313 3313
            else throw emitError(self, receiver, ErrorKind::TraitReceiverMismatch);
3314 3314
        let receiverTargetName = try nodeName(self, nameNode);
3315 3315
3316 -
        if receiverTargetName != traitType.name {
3316 +
        if receiverTargetName <> traitType.name {
3317 3317
            throw emitError(self, receiver, ErrorKind::TraitReceiverMismatch);
3318 3318
        }
3319 3319
        // Resolve parameter types and return type.
3320 3320
        let a = alloc::arenaAllocator(&mut self.arena);
3321 3321
        let mut paramTypes: *mut [*Type] = &mut [];
3475 3475
            mutable: receiverMut,
3476 3476
        };
3477 3477
3478 3478
        // Validate that the instance method's signature matches the
3479 3479
        // trait method's signature exactly (params, return type, throws).
3480 -
        if sig.params.len != tm.fnType.paramTypes.len {
3480 +
        if sig.params.len <> tm.fnType.paramTypes.len {
3481 3481
            throw emitError(self, methodNode, ErrorKind::FnArgCountMismatch(CountMismatch {
3482 3482
                expected: tm.fnType.paramTypes.len as u32,
3483 3483
                actual: sig.params.len,
3484 3484
            }));
3485 3485
        }
3502 3502
            throw emitTypeMismatch(self, methodNode, TypeMismatch {
3503 3503
                expected: *tm.fnType.returnType,
3504 3504
                actual: instanceRetTy,
3505 3505
            });
3506 3506
        }
3507 -
        if sig.throwList.len != tm.fnType.throwList.len {
3507 +
        if sig.throwList.len <> tm.fnType.throwList.len {
3508 3508
            throw emitError(self, methodNode, ErrorKind::FnThrowCountMismatch(CountMismatch {
3509 3509
                expected: tm.fnType.throwList.len as u32,
3510 3510
                actual: sig.throwList.len,
3511 3511
            }));
3512 3512
        }
3633 3633
    let retTy = *fnType.returnType;
3634 3634
    let bodyTy = try checkAssignable(self, body, Type::Void) catch e {
3635 3635
        exitFn(self);
3636 3636
        throw e;
3637 3637
    };
3638 -
    if retTy != Type::Void and bodyTy != Type::Never {
3638 +
    if retTy <> Type::Void and bodyTy <> Type::Never {
3639 3639
        exitFn(self);
3640 3640
        throw emitError(self, body, ErrorKind::FnMissingReturn);
3641 3641
    }
3642 3642
    exitFn(self);
3643 3643
}
4054 4054
                } else => {}
4055 4055
            }
4056 4056
        }
4057 4057
        case Type::Array(arrayInfo) => {
4058 4058
            if let case ast::NodeValue::ArrayLit(items) = pattern.value {
4059 -
                if items.len as u32 != arrayInfo.length {
4059 +
                if items.len as u32 <> arrayInfo.length {
4060 4060
                    throw emitError(self, pattern, ErrorKind::RecordFieldCountMismatch(
4061 4061
                        CountMismatch { expected: arrayInfo.length, actual: items.len as u32 }
4062 4062
                    ));
4063 4063
                }
4064 4064
                let elemTy = *arrayInfo.item;
4324 4324
    matchBy: MatchBy
4325 4325
) -> Type throws (ResolveError) {
4326 4326
    // Whether this prong is catch-all.
4327 4327
    let mut isCatchAll = false;
4328 4328
4329 -
    if prong.guard != nil {
4329 +
    if prong.guard <> nil {
4330 4330
        state.isConst = false;
4331 4331
    } else {
4332 4332
        match prong.arm {
4333 4333
            case ast::ProngArm::Binding(_),
4334 4334
                 ast::ProngArm::Else => isCatchAll = true,
4639 4639
        throw emitError(self, pattern, ErrorKind::Internal);
4640 4640
    };
4641 4641
    let variant = &unionType.variants[index];
4642 4642
    // If this variant has a payload, throw an error, since the user hasn't
4643 4643
    // provided one.
4644 -
    if variant.valueType != Type::Void {
4644 +
    if variant.valueType <> Type::Void {
4645 4645
        throw emitError(self, pattern, ErrorKind::UnionVariantPayloadMissing(variant.name));
4646 4646
    }
4647 4647
}
4648 4648
4649 4649
/// Validate and bind a union constructor call used as a `match` pattern.
4661 4661
    };
4662 4662
    let variant = &unionType.variants[index];
4663 4663
    // Copy variant index to the pattern node for the lowerer.
4664 4664
    setVariantInfo(self, pattern, index, tag);
4665 4665
4666 -
    if variant.valueType != Type::Void {
4666 +
    if variant.valueType <> Type::Void {
4667 4667
        try bindUnionPatternPayload(self, pattern, call, variant.name, variant.valueType, matchBy);
4668 4668
    } else {
4669 4669
        throw emitError(self, pattern, ErrorKind::UnionVariantPayloadUnexpected(variant.name));
4670 4670
    }
4671 4671
}
4860 4860
    kind: ast::Builtin,
4861 4861
    args: *mut [*ast::Node]
4862 4862
) -> Type throws (ResolveError) {
4863 4863
    // Handle `@sliceOf(ptr, len)` and `@sliceOf(ptr, len, cap)`.
4864 4864
    if kind == ast::Builtin::SliceOf {
4865 -
        if args.len != 2 and args.len != 3 {
4865 +
        if args.len <> 2 and args.len <> 3 {
4866 4866
            throw emitError(self, node, ErrorKind::BuiltinArgCountMismatch(CountMismatch {
4867 4867
                expected: 2,
4868 4868
                actual: args.len as u32,
4869 4869
            }));
4870 4870
        }
4876 4876
        if args.len == 3 {
4877 4877
            let _ = try checkAssignable(self, args[2], Type::U32);
4878 4878
        }
4879 4879
        return setNodeType(self, node, Type::Slice { item: target, mutable });
4880 4880
    }
4881 -
    if args.len != 1 {
4881 +
    if args.len <> 1 {
4882 4882
        throw emitError(self, node, ErrorKind::BuiltinArgCountMismatch(CountMismatch {
4883 4883
            expected: 1,
4884 4884
            actual: args.len as u32,
4885 4885
        }));
4886 4886
    }
4923 4923
    throws (ResolveError)
4924 4924
{
4925 4925
    if ctx == CallCtx::Normal and info.throwList.len > 0 {
4926 4926
        throw emitError(self, node, ErrorKind::MissingTry);
4927 4927
    }
4928 -
    if call.args.len != info.paramTypes.len as u32 {
4928 +
    if call.args.len <> info.paramTypes.len as u32 {
4929 4929
        throw emitError(self, node, ErrorKind::FnArgCountMismatch(CountMismatch {
4930 4930
            expected: info.paramTypes.len as u32,
4931 4931
            actual: call.args.len,
4932 4932
        }));
4933 4933
    }
5054 5054
    mutable: bool
5055 5055
) -> Type throws (ResolveError) {
5056 5056
    if not mutable {
5057 5057
        throw emitError(self, parent, ErrorKind::ImmutableBinding);
5058 5058
    }
5059 -
    if args.len != 2 {
5059 +
    if args.len <> 2 {
5060 5060
        throw emitError(self, node, ErrorKind::FnArgCountMismatch(CountMismatch {
5061 5061
            expected: 2,
5062 5062
            actual: args.len as u32,
5063 5063
        }));
5064 5064
    }
5083 5083
    mutable: bool
5084 5084
) -> Type throws (ResolveError) {
5085 5085
    if not mutable {
5086 5086
        throw emitError(self, parent, ErrorKind::ImmutableBinding);
5087 5087
    }
5088 -
    if args.len != 1 {
5088 +
    if args.len <> 1 {
5089 5089
        throw emitError(self, node, ErrorKind::FnArgCountMismatch(CountMismatch {
5090 5090
            expected: 1,
5091 5091
            actual: args.len as u32,
5092 5092
        }));
5093 5093
    }
5128 5128
                else => throw emitError(self, container, ErrorKind::ExpectedIndexable),
5129 5129
            }
5130 5130
            // RHS is either a fill value or a source slice.
5131 5131
            let rhsTy = try infer(self, assign.right);
5132 5132
            if let case Type::Slice { item: srcItem, .. } = rhsTy {
5133 -
                if *srcItem != *item {
5133 +
                if *srcItem <> *item {
5134 5134
                    throw emitTypeMismatch(self, assign.right, TypeMismatch { expected: *item, actual: *srcItem });
5135 5135
                }
5136 5136
            } else {
5137 5137
                try checkAssignable(self, assign.right, *item);
5138 5138
            }
5272 5272
    // Associate variant index with `call` node for the lowerer.
5273 5273
    setVariantInfo(self, node, index, tag);
5274 5274
5275 5275
    // Check if this variant expects a payload.
5276 5276
    let payloadType = variant.valueType;
5277 -
    if payloadType != Type::Void {
5277 +
    if payloadType <> Type::Void {
5278 5278
        let recInfo = getRecord(payloadType)
5279 5279
            else panic "resolveUnionVariantConstructor: payload is not a record";
5280 5280
        try checkRecordConstructorArgs(self, node, call.args, recInfo);
5281 5281
    } else {
5282 5282
        if call.args.len > 0 {
5390 5390
            else panic "resolveRecordLit: expected labeled field";
5391 5391
        let fieldName = try nodeName(self, label);
5392 5392
        let expected = recordType.fields[idx];
5393 5393
        let expectedName = expected.name else panic;
5394 5394
5395 -
        if fieldName != expectedName {
5395 +
        if fieldName <> expectedName {
5396 5396
            throw emitError(self, fieldNode, ErrorKind::RecordFieldOutOfOrder {
5397 5397
                field: fieldName,
5398 5398
                prev: expectedName,
5399 5399
            });
5400 5400
        }
5424 5424
    let targetInfo = hintInfo else {
5425 5425
        throw emitError(self, node, ErrorKind::CannotInferType);
5426 5426
    };
5427 5427
5428 5428
    // Check field count.
5429 -
    if lit.fields.len != targetInfo.fields.len {
5429 +
    if lit.fields.len <> targetInfo.fields.len {
5430 5430
        if lit.fields.len < targetInfo.fields.len {
5431 5431
            let missingName = targetInfo.fields[lit.fields.len].name else panic;
5432 5432
            throw emitError(self, node, ErrorKind::RecordFieldMissing(missingName));
5433 5433
        } else {
5434 5434
            throw emitError(self, node, ErrorKind::RecordFieldCountMismatch(CountMismatch {
5446 5446
            else panic "resolveAnonRecordLit: expected labeled field";
5447 5447
        let fieldName = try nodeName(self, label);
5448 5448
        let expected = targetInfo.fields[idx];
5449 5449
        let expectedName = expected.name else panic;
5450 5450
5451 -
        if fieldName != expectedName {
5451 +
        if fieldName <> expectedName {
5452 5452
            throw emitError(self, fieldNode, ErrorKind::RecordFieldOutOfOrder {
5453 5453
                field: fieldName,
5454 5454
                prev: expectedName,
5455 5455
            });
5456 5456
        }
5477 5477
            expectedTy = *ary.item;
5478 5478
        }
5479 5479
    };
5480 5480
    for itemNode in items {
5481 5481
        let itemTy = try visit(self, itemNode, expectedTy);
5482 -
        assert itemTy != Type::Unknown;
5482 +
        assert itemTy <> Type::Unknown;
5483 5483
5484 5484
        // Set the expected type to the first type we encounter.
5485 5485
        if expectedTy == Type::Unknown {
5486 5486
            expectedTy = itemTy;
5487 5487
        } else {
5914 5914
    throws (ResolveError)
5915 5915
{
5916 5916
    let targetTy = try infer(self, expr.type);
5917 5917
    let sourceTy = try visit(self, expr.value, targetTy);
5918 5918
5919 -
    assert sourceTy != Type::Unknown;
5920 -
    assert targetTy != Type::Unknown;
5919 +
    assert sourceTy <> Type::Unknown;
5920 +
    assert targetTy <> Type::Unknown;
5921 5921
5922 5922
    if isValidCast(sourceTy, targetTy) {
5923 5923
        // Propagate constant value through the cast, adjusting integer
5924 5924
        // metadata to match the target type.
5925 5925
        if let value = constValueEntry(self, expr.value) {
5955 5955
        if let e = range.end {
5956 5956
            let endTy = try checkNumeric(self, e);
5957 5957
            let mut resolvedTy = startTy;
5958 5958
5959 5959
            // Infer unsuffixed integer literals from the opposite bound.
5960 -
            if startTy == Type::Int and endTy != Type::Int {
5960 +
            if startTy == Type::Int and endTy <> Type::Int {
5961 5961
                let _ = try checkAssignable(self, s, endTy);
5962 5962
                resolvedTy = endTy;
5963 -
            } else if endTy == Type::Int and startTy != Type::Int {
5963 +
            } else if endTy == Type::Int and startTy <> Type::Int {
5964 5964
                let _ = try checkAssignable(self, e, startTy);
5965 5965
                resolvedTy = startTy;
5966 5966
            } else {
5967 5967
                let _ = try checkAssignable(self, e, startTy);
5968 5968
            }
6039 6039
/// Check that a `catch` body is assignable to the expected result type, but only
6040 6040
/// in expression context (`hint` is neither `Unknown` nor `Void`).
6041 6041
fn checkCatchBody(self: *mut Resolver, body: *ast::Node, resultTy: Type, hint: Type)
6042 6042
    throws (ResolveError)
6043 6043
{
6044 -
    if hint != Type::Unknown and hint != Type::Void {
6044 +
    if hint <> Type::Unknown and hint <> Type::Void {
6045 6045
        try checkAssignable(self, body, resultTy);
6046 6046
    }
6047 6047
}
6048 6048
6049 6049
/// Resolve catch clauses for a `try ... catch` expression.
6062 6062
    let firstNode = catches[0];
6063 6063
    let case ast::NodeValue::CatchClause(first) = firstNode.value else
6064 6064
        throw emitError(self, node, ErrorKind::UnexpectedNode(firstNode));
6065 6065
6066 6066
    // Typed catches: dispatch to dedicated handler.
6067 -
    if first.typeNode != nil {
6067 +
    if first.typeNode <> nil {
6068 6068
        return try resolveTypedCatches(self, node, catches, calleeInfo, resultTy, hint);
6069 6069
    }
6070 6070
    // Single untyped catch clause.
6071 6071
    if let binding = first.binding {
6072 6072
        if calleeInfo.throwList.len > 1 {
6182 6182
        else throw emitError(self, node, ErrorKind::UnexpectedReturn);
6183 6183
    let expected = *f.returnType;
6184 6184
6185 6185
    if let val = retVal {
6186 6186
        let _actualTy = try checkAssignable(self, val, expected);
6187 -
    } else if expected != Type::Void {
6187 +
    } else if expected <> Type::Void {
6188 6188
        throw emitTypeMismatch(self, node, TypeMismatch { expected, actual: Type::Void });
6189 6189
    }
6190 6190
    // In throwing functions, return values are wrapped in the success variant.
6191 6191
    if f.throwList.len > 0 {
6192 6192
        setNodeCoercion(self, node, Coercion::ResultWrap);
6245 6245
            return ConstValue::Int(ConstInt {
6246 6246
                magnitude: left.magnitude >> right.magnitude, bits, signed, negative: left.negative,
6247 6247
            });
6248 6248
        },
6249 6249
        case ast::BinaryOp::Eq  => return ConstValue::Bool(l == r),
6250 -
        case ast::BinaryOp::Ne  => return ConstValue::Bool(l != r),
6250 +
        case ast::BinaryOp::Ne  => return ConstValue::Bool(l <> r),
6251 6251
        case ast::BinaryOp::Lt  => return ConstValue::Bool(l < r),
6252 6252
        case ast::BinaryOp::Gt  => return ConstValue::Bool(l > r),
6253 6253
        case ast::BinaryOp::Lte => return ConstValue::Bool(l <= r),
6254 6254
        case ast::BinaryOp::Gte => return ConstValue::Bool(l >= r),
6255 6255
        case ast::BinaryOp::Add => return ConstValue::Int(constIntFromSigned(l + r, bits, signed)),
6298 6298
            match binop.op {
6299 6299
                case ast::BinaryOp::And => setNodeConstValue(self, node, ConstValue::Bool(l and r)),
6300 6300
                case ast::BinaryOp::Or => setNodeConstValue(self, node, ConstValue::Bool(l or r)),
6301 6301
                case ast::BinaryOp::Eq => setNodeConstValue(self, node, ConstValue::Bool(l == r)),
6302 6302
                case ast::BinaryOp::Ne,
6303 -
                     ast::BinaryOp::Xor => setNodeConstValue(self, node, ConstValue::Bool(l != r)),
6303 +
                     ast::BinaryOp::Xor => setNodeConstValue(self, node, ConstValue::Bool(l <> r)),
6304 6304
                else => {}
6305 6305
            }
6306 6306
        }
6307 6307
    }
6308 6308
}
lib/std/lang/resolver/tests.rad +5 -5
278 278
    throws (testing::TestError)
279 279
{
280 280
    let actual = super::typeFor(self, expr)
281 281
        else throw testing::TestError::Failed;
282 282
283 -
    if actual != expected {
283 +
    if actual <> expected {
284 284
        throw testing::TestError::Failed;
285 285
    }
286 286
}
287 287
288 288
/// Verify that an error represents a specific type mismatch.
1979 1979
    let nominalTy = try getTypeInScopeOf(&a, result.root, "R");
1980 1980
    let case super::NominalType::Record(recordType) = *nominalTy
1981 1981
        else throw testing::TestError::Failed;
1982 1982
    try testing::expect(recordType.labeled);
1983 1983
    try testing::expect(recordType.fields.len == 2);
1984 -
    try testing::expect(recordType.fields[0].name != nil);
1985 -
    try testing::expect(recordType.fields[1].name != nil);
1984 +
    try testing::expect(recordType.fields[0].name <> nil);
1985 +
    try testing::expect(recordType.fields[1].name <> nil);
1986 1986
}
1987 1987
1988 1988
@test fn testResolveRecordFieldAccessValid() throws (testing::TestError) {
1989 1989
    let mut a = testResolver();
1990 1990
    let program = "record Pt { x: i32, y: u8 } let p = Pt { x: 1, y: 2 }; p.y;";
2424 2424
        let result = try resolveExprStr(&mut a, "5 == 5");
2425 2425
        try expectNoErrors(&result);
2426 2426
        try expectType(&a, result.root, super::Type::Bool);
2427 2427
    } {
2428 2428
        let mut a = testResolver();
2429 -
        let result = try resolveExprStr(&mut a, "5 != 10");
2429 +
        let result = try resolveExprStr(&mut a, "5 <> 10");
2430 2430
        try expectNoErrors(&result);
2431 2431
        try expectType(&a, result.root, super::Type::Bool);
2432 2432
    } {
2433 2433
        let mut a = testResolver();
2434 2434
        let result = try resolveExprStr(&mut a, "5 < 10");
2756 2756
    let case super::NominalType::Union(unionType) = *ty
2757 2757
        else throw testing::TestError::Failed;
2758 2758
    try testing::expect(unionType.variants.len == 2);
2759 2759
    try testing::expect(mem::eq(unionType.variants[0].name, "Ok"));
2760 2760
    try testing::expect(mem::eq(unionType.variants[1].name, "Error"));
2761 -
    if getUnionVariantPayload(ty, "Ok") != super::Type::Void {
2761 +
    if getUnionVariantPayload(ty, "Ok") <> super::Type::Void {
2762 2762
        throw testing::TestError::Failed;
2763 2763
    }
2764 2764
    let stmt = try getBlockStmt(result.root, 1);
2765 2765
    try expectExprStmtType(&a, stmt, super::Type::Nominal(ty));
2766 2766
    try expectNoErrors(&result);
lib/std/lang/scanner.rad +5 -10
39 39
    Caret,      // ^
40 40
    Tilde,      // ~
41 41
    Underscore, // _
42 42
    Question,   // ?
43 43
    Bang,       // !
44 -
    BangEqual,  // != or <>
44 +
    LtGt,       // <>
45 45
    Equal,      // =
46 46
    EqualEqual, // ==
47 47
    Gt,         // >
48 48
    GtEqual,    // >=
49 49
    Lt,         // <
285 285
    while let ch = current(s) {
286 286
        match ch {
287 287
            case ' ', '\n', '\r', '\t' => advance(s),
288 288
            case '/' => {
289 289
                if let c = peek(s); c == '/' {
290 -
                    while let ch = current(s); ch != '\n' {
290 +
                    while let ch = current(s); ch <> '\n' {
291 291
                        advance(s);
292 292
                    }
293 293
                } else {
294 294
                    return;
295 295
                }
376 376
    }
377 377
    return tok(s, TokenKind::Number);
378 378
}
379 379
380 380
fn scanDelimited(s: *mut Scanner, delim: u8, kind: TokenKind) -> ?Token {
381 -
    while let ch = current(s); ch != delim {
381 +
    while let ch = current(s); ch <> delim {
382 382
        if not isPrint(ch) {
383 383
            return invalid(s.token, "invalid character");
384 384
        }
385 385
        consume(s, '\\'); // Consume escapes
386 386
        advance(s);
538 538
                return tok(s, TokenKind::CaretEqual);
539 539
            }
540 540
            return tok(s, TokenKind::Caret);
541 541
        }
542 542
        case '~' => return tok(s, TokenKind::Tilde),
543 -
        case '!' => {
544 -
            if consume(s, '=') {
545 -
                return tok(s, TokenKind::BangEqual);
546 -
            }
547 -
            return tok(s, TokenKind::Bang);
548 -
        }
543 +
        case '!' => return tok(s, TokenKind::Bang),
549 544
        case '=' => {
550 545
            if consume(s, '>') {
551 546
                return tok(s, TokenKind::FatArrow);
552 547
            }
553 548
            if consume(s, '=') {
555 550
            }
556 551
            return tok(s, TokenKind::Equal);
557 552
        }
558 553
        case '<' => {
559 554
            if consume(s, '>') {
560 -
                return tok(s, TokenKind::BangEqual);
555 +
                return tok(s, TokenKind::LtGt);
561 556
            }
562 557
            if consume(s, '<') {
563 558
                if consume(s, '=') {
564 559
                    return tok(s, TokenKind::LtLtEqual);
565 560
                }
lib/std/lang/scanner/tests.rad +2 -3
164 164
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
165 165
}
166 166
167 167
@test fn testScanDoubleCharTokens() throws (testing::TestError) {
168 168
    let mut s = testScanner(
169 -
        "== != <> <= >= < > >> << -> =>"
169 +
        "== <> <= >= < > >> << -> =>"
170 170
    );
171 171
    try testing::expect(super::next(&mut s).kind == super::TokenKind::EqualEqual);
172 -
    try testing::expect(super::next(&mut s).kind == super::TokenKind::BangEqual);
173 -
    try testing::expect(super::next(&mut s).kind == super::TokenKind::BangEqual);
172 +
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LtGt);
174 173
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LtEqual);
175 174
    try testing::expect(super::next(&mut s).kind == super::TokenKind::GtEqual);
176 175
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Lt);
177 176
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Gt);
178 177
    try testing::expect(super::next(&mut s).kind == super::TokenKind::GtGt);
lib/std/lang/sexpr.rad +5 -5
138 138
        case Expr::List { head, tail, multiline } => {
139 139
            write(out, "(");
140 140
            write(out, head);
141 141
            if multiline {
142 142
                for i in 0..tail.len {
143 -
                    if tail[i] != Expr::Null {
143 +
                    if tail[i] <> Expr::Null {
144 144
                        write(out, "\n");
145 145
                        indentTo(out, depth + 1);
146 146
                        printTo(tail[i], depth + 1, out);
147 147
                    }
148 148
                }
149 149
            } else {
150 150
                let mut first = head.len == 0;
151 151
                for i in 0..tail.len {
152 -
                    if tail[i] != Expr::Null {
152 +
                    if tail[i] <> Expr::Null {
153 153
                        if first {
154 154
                            first = false;
155 155
                        } else {
156 156
                            write(out, " ");
157 157
                        }
162 162
            write(out, ")");
163 163
        }
164 164
        case Expr::Vec { items } => {
165 165
            write(out, "[");
166 166
            for item, i in items {
167 -
                if item != Expr::Null {
167 +
                if item <> Expr::Null {
168 168
                    if i > 0 {
169 169
                        write(out, " ");
170 170
                    }
171 171
                    printTo(item, depth, out);
172 172
                }
175 175
        }
176 176
        case Expr::Block { name, items, children } => {
177 177
            write(out, "(");
178 178
            write(out, name);
179 179
            for i in 0..items.len {
180 -
                if items[i] != Expr::Null {
180 +
                if items[i] <> Expr::Null {
181 181
                    write(out, " ");
182 182
                    printTo(items[i], depth, out);
183 183
                }
184 184
            }
185 185
            for i in 0..children.len {
186 -
                if children[i] != Expr::Null {
186 +
                if children[i] <> Expr::Null {
187 187
                    write(out, "\n");
188 188
                    indentTo(out, depth + 1);
189 189
                    printTo(children[i], depth + 1, out);
190 190
                }
191 191
            }
lib/std/mem.rad +4 -4
23 23
    }
24 24
    if prefix.len > input.len {
25 25
        return nil;
26 26
    }
27 27
    for i in 0..prefix.len {
28 -
        if prefix[i] != input[i] {
28 +
        if prefix[i] <> input[i] {
29 29
            return nil;
30 30
        }
31 31
    }
32 32
    return &input[prefix.len..];
33 33
}
44 44
45 45
/// Count number of set bits in a 32-bit value.
46 46
export fn popCount(x: u32) -> i32 {
47 47
    let mut n = x;
48 48
    let mut count: i32 = 0;
49 -
    while n != 0 {
49 +
    while n <> 0 {
50 50
        count += (n & 1) as i32;
51 51
        n >>= 1;
52 52
    }
53 53
    return count;
54 54
}
55 55
56 56
/// Check whether two byte slices have the same length and contents.
57 57
export fn eq(a: *[u8], b: *[u8]) -> bool {
58 -
    if a.len != b.len {
58 +
    if a.len <> b.len {
59 59
        return false;
60 60
    }
61 61
    for i in 0..a.len {
62 -
        if a[i] != b[i] {
62 +
        if a[i] <> b[i] {
63 63
            return false;
64 64
        }
65 65
    }
66 66
    return true;
67 67
}
test/runner.rad +4 -4
51 51
/// Strip comment from a line. Returns sub-slice up to ';', trimmed of trailing whitespace.
52 52
fn stripLine(line: *[u8]) -> *[u8] {
53 53
    let mut end: u32 = 0;
54 54
    let mut i: u32 = 0;
55 55
56 -
    while i < line.len and line[i] != ';' {
57 -
        if line[i] != ' ' and line[i] != '\t' {
56 +
    while i < line.len and line[i] <> ';' {
57 +
        if line[i] <> ' ' and line[i] <> '\t' {
58 58
            end = i + 1;
59 59
        }
60 60
        i += 1;
61 61
    }
62 62
    return &line[..end];
65 65
/// Get next line from string at offset. Returns the line and updates offset past newline.
66 66
fn nextLine(s: *[u8], offset: *mut u32) -> *[u8] {
67 67
    let start = *offset;
68 68
    let mut i = start;
69 69
70 -
    while i < s.len and s[i] != '\n' {
70 +
    while i < s.len and s[i] <> '\n' {
71 71
        i += 1;
72 72
    }
73 73
    let line = &s[start..i];
74 74
    if i < s.len {
75 75
        *offset = i + 1;
218 218
219 219
/// Run a single test specified as an argument.
220 220
@default fn main(env: *sys::Env) -> i32 {
221 221
    let args = env.args;
222 222
223 -
    if args.len != 2 {
223 +
    if args.len <> 2 {
224 224
        io::printError("error: expected test file path as argument");
225 225
        return 1;
226 226
    }
227 227
    let sourcePath = args[1];
228 228
    io::print("test ");
test/tests/abi.sizes.rad +9 -9
142 142
    return 0;
143 143
}
144 144
145 145
@default fn main() -> i32 {
146 146
    let r1 = testByte();
147 -
    if r1 != 0 {
147 +
    if r1 <> 0 {
148 148
        return 10 + r1;
149 149
    }
150 150
151 151
    let r2 = testShort();
152 -
    if r2 != 0 {
152 +
    if r2 <> 0 {
153 153
        return 20 + r2;
154 154
    }
155 155
156 156
    let r3 = testWord();
157 -
    if r3 != 0 {
157 +
    if r3 <> 0 {
158 158
        return 30 + r3;
159 159
    }
160 160
161 161
    let r4 = testPair();
162 -
    if r4 != 0 {
162 +
    if r4 <> 0 {
163 163
        return 40 + r4;
164 164
    }
165 165
166 166
    let r5 = testTriple();
167 -
    if r5 != 0 {
167 +
    if r5 <> 0 {
168 168
        return 50 + r5;
169 169
    }
170 170
171 171
    let r6 = testIdentity();
172 -
    if r6 != 0 {
172 +
    if r6 <> 0 {
173 173
        return 60 + r6;
174 174
    }
175 175
176 176
    let r7 = testAddPairs();
177 -
    if r7 != 0 {
177 +
    if r7 <> 0 {
178 178
        return 70 + r7;
179 179
    }
180 180
181 181
    let r8 = testDoublePair();
182 -
    if r8 != 0 {
182 +
    if r8 <> 0 {
183 183
        return 80 + r8;
184 184
    }
185 185
186 186
    let r9 = testMultipleReturns();
187 -
    if r9 != 0 {
187 +
    if r9 <> 0 {
188 188
        return 90 + r9;
189 189
    }
190 190
    return 0;
191 191
}
test/tests/aggregate.return.rad +8 -8
133 133
    return 0;
134 134
}
135 135
136 136
@default fn main() -> i32 {
137 137
    let r1: i32 = testReturnDoesNotCorruptLocals();
138 -
    if r1 != 0 {
138 +
    if r1 <> 0 {
139 139
        return 10 + r1;
140 140
    }
141 141
142 142
    let r2: i32 = testMultipleReturns();
143 -
    if r2 != 0 {
143 +
    if r2 <> 0 {
144 144
        return 20 + r2;
145 145
    }
146 146
147 147
    let r3: i32 = testMutateReturnedAggregate();
148 -
    if r3 != 0 {
148 +
    if r3 <> 0 {
149 149
        return 30 + r3;
150 150
    }
151 151
152 152
    let r4: i32 = testAggregateReturnInLoop();
153 -
    if r4 != 0 {
153 +
    if r4 <> 0 {
154 154
        return 40 + r4;
155 155
    }
156 156
157 157
    let r5: i32 = testThrowingAggregateReturn();
158 -
    if r5 != 0 {
158 +
    if r5 <> 0 {
159 159
        return 50 + r5;
160 160
    }
161 161
162 162
    let r6: i32 = testThrowingAggregateCatch();
163 -
    if r6 != 0 {
163 +
    if r6 <> 0 {
164 164
        return 60 + r6;
165 165
    }
166 166
167 167
    let r7: i32 = testTripleReturn();
168 -
    if r7 != 0 {
168 +
    if r7 <> 0 {
169 169
        return 70 + r7;
170 170
    }
171 171
172 172
    let r8: i32 = testInterleavedCalls();
173 -
    if r8 != 0 {
173 +
    if r8 <> 0 {
174 174
        return 80 + r8;
175 175
    }
176 176
    return 0;
177 177
}
test/tests/arith.subword.rad +15 -15
6 6
fn testI8Overflow() -> bool {
7 7
    let a: i8 = 120;
8 8
    let b: i8 = 10;
9 9
    let result: i8 = a + b;
10 10
    // 120 + 10 = 130, which wraps to -126 in i8
11 -
    if result != -126 {
11 +
    if result <> -126 {
12 12
        return false;
13 13
    }
14 14
    return true;
15 15
}
16 16
17 17
fn testU8Overflow() -> bool {
18 18
    let a: u8 = 250;
19 19
    let b: u8 = 10;
20 20
    let result: u8 = a + b;
21 21
    // 250 + 10 = 260, which wraps to 4 in u8
22 -
    if result != 4 {
22 +
    if result <> 4 {
23 23
        return false;
24 24
    }
25 25
    return true;
26 26
}
27 27
28 28
fn testI8Subtraction() -> bool {
29 29
    let a: i8 = -100;
30 30
    let b: i8 = 50;
31 31
    let result: i8 = a - b;
32 32
    // -100 - 50 = -150, which wraps to 106 in i8
33 -
    if result != 106 {
33 +
    if result <> 106 {
34 34
        return false;
35 35
    }
36 36
    return true;
37 37
}
38 38
39 39
fn testU8Subtraction() -> bool {
40 40
    let a: u8 = 5;
41 41
    let b: u8 = 10;
42 42
    let result: u8 = a - b;
43 43
    // 5 - 10 = -5, which wraps to 251 in u8
44 -
    if result != 251 {
44 +
    if result <> 251 {
45 45
        return false;
46 46
    }
47 47
    return true;
48 48
}
49 49
50 50
fn testI16Overflow() -> bool {
51 51
    let a: i16 = 32000;
52 52
    let b: i16 = 1000;
53 53
    let result: i16 = a + b;
54 54
    // 32000 + 1000 = 33000, which wraps to -32536 in i16
55 -
    if result != -32536 {
55 +
    if result <> -32536 {
56 56
        return false;
57 57
    }
58 58
    return true;
59 59
}
60 60
61 61
fn testU16Overflow() -> bool {
62 62
    let a: u16 = 65530;
63 63
    let b: u16 = 10;
64 64
    let result: u16 = a + b;
65 65
    // 65530 + 10 = 65540, which wraps to 4 in u16
66 -
    if result != 4 {
66 +
    if result <> 4 {
67 67
        return false;
68 68
    }
69 69
    return true;
70 70
}
71 71
72 72
fn testI8Multiply() -> bool {
73 73
    let a: i8 = 15;
74 74
    let b: i8 = 10;
75 75
    let result: i8 = a * b;
76 76
    // 15 * 10 = 150, which wraps to -106 in i8
77 -
    if result != -106 {
77 +
    if result <> -106 {
78 78
        return false;
79 79
    }
80 80
    return true;
81 81
}
82 82
83 83
fn testU8Multiply() -> bool {
84 84
    let a: u8 = 20;
85 85
    let b: u8 = 15;
86 86
    let result: u8 = a * b;
87 87
    // 20 * 15 = 300, which wraps to 44 in u8
88 -
    if result != 44 {
88 +
    if result <> 44 {
89 89
        return false;
90 90
    }
91 91
    return true;
92 92
}
93 93
96 96
    let b: i8 = a + 1;
97 97
    // b should be -128 after overflow
98 98
    if b >= 0 {
99 99
        return false;
100 100
    }
101 -
    if b != -128 {
101 +
    if b <> -128 {
102 102
        return false;
103 103
    }
104 104
    return true;
105 105
}
106 106
107 107
fn testU8Comparison() -> bool {
108 108
    let a: u8 = 255;
109 109
    let b: u8 = a + 1 as u8;
110 110
    // b should be 0 after overflow
111 -
    if b != 0 {
111 +
    if b <> 0 {
112 112
        return false;
113 113
    }
114 114
    return true;
115 115
}
116 116
117 117
fn testNarrowingCast() -> bool {
118 118
    let x: i32 = 1000;
119 119
    let narrow: u8 = x as u8;
120 120
    // 1000 = 0x3E8, lower byte = 0xE8 = 232
121 -
    if narrow != 232 {
121 +
    if narrow <> 232 {
122 122
        return false;
123 123
    }
124 124
    return true;
125 125
}
126 126
127 127
fn testW32ShiftRight() -> bool {
128 128
    let max: u32 = 0xFFFFFFFF;
129 129
    let shifted: u32 = max >> 16;
130 130
    // Should be 0xFFFF = 65535
131 -
    if shifted != 65535 {
131 +
    if shifted <> 65535 {
132 132
        return false;
133 133
    }
134 134
    return true;
135 135
}
136 136
137 137
fn testI8NegOverflow() -> bool {
138 138
    let min: i8 = -128;
139 139
    let negated: i8 = -min;
140 140
    // RV64 should preserve i8 wrap behavior: -(-128) == -128
141 -
    if negated != -128 {
141 +
    if negated <> -128 {
142 142
        return false;
143 143
    }
144 144
    return true;
145 145
}
146 146
147 147
fn testU8BitNot() -> bool {
148 148
    let x: u8 = 0;
149 149
    let inverted: u8 = ~x;
150 150
    // 8-bit not of 0 is 0xFF.
151 -
    if inverted != 255 {
151 +
    if inverted <> 255 {
152 152
        return false;
153 153
    }
154 154
    return true;
155 155
}
156 156
157 157
fn testW32ShiftLargeImmediate() -> bool {
158 158
    let x: u32 = 1;
159 159
    let shifted: u32 = x << 40;
160 160
    // Shift amount should be masked to 5 bits for 32-bit shifts: 40 % 32 = 8.
161 -
    if shifted != 256 {
161 +
    if shifted <> 256 {
162 162
        return false;
163 163
    }
164 164
    return true;
165 165
}
166 166
test/tests/arith.w64.rad +19 -19
5 5
6 6
fn testI64Add() -> bool {
7 7
    let a: i64 = 100;
8 8
    let b: i64 = 200;
9 9
    let result: i64 = a + b;
10 -
    if result != 300 {
10 +
    if result <> 300 {
11 11
        return false;
12 12
    }
13 13
    return true;
14 14
}
15 15
16 16
fn testU64Add() -> bool {
17 17
    let a: u64 = 100;
18 18
    let b: u64 = 200;
19 19
    let result: u64 = a + b;
20 -
    if result != 300 {
20 +
    if result <> 300 {
21 21
        return false;
22 22
    }
23 23
    return true;
24 24
}
25 25
26 26
fn testI64Sub() -> bool {
27 27
    let a: i64 = 500;
28 28
    let b: i64 = 300;
29 29
    let result: i64 = a - b;
30 -
    if result != 200 {
30 +
    if result <> 200 {
31 31
        return false;
32 32
    }
33 33
    return true;
34 34
}
35 35
36 36
fn testI64Mul() -> bool {
37 37
    let a: i64 = 1000;
38 38
    let b: i64 = 2000;
39 39
    let result: i64 = a * b;
40 -
    if result != 2000000 {
40 +
    if result <> 2000000 {
41 41
        return false;
42 42
    }
43 43
    return true;
44 44
}
45 45
46 46
fn testI64Div() -> bool {
47 47
    let a: i64 = 1000;
48 48
    let b: i64 = 10;
49 49
    let result: i64 = a / b;
50 -
    if result != 100 {
50 +
    if result <> 100 {
51 51
        return false;
52 52
    }
53 53
    return true;
54 54
}
55 55
56 56
fn testU64Div() -> bool {
57 57
    let a: u64 = 1000;
58 58
    let b: u64 = 10;
59 59
    let result: u64 = a / b;
60 -
    if result != 100 {
60 +
    if result <> 100 {
61 61
        return false;
62 62
    }
63 63
    return true;
64 64
}
65 65
66 66
fn testI64Neg() -> bool {
67 67
    let a: i64 = 42;
68 68
    let result: i64 = -a;
69 -
    if result != -42 {
69 +
    if result <> -42 {
70 70
        return false;
71 71
    }
72 72
    return true;
73 73
}
74 74
75 75
fn testI64Shift() -> bool {
76 76
    let a: i64 = 1;
77 77
    let result: i64 = a << 40;
78 -
    if result != 1099511627776 {
78 +
    if result <> 1099511627776 {
79 79
        return false;
80 80
    }
81 81
    let back: i64 = result >> 40;
82 -
    if back != 1 {
82 +
    if back <> 1 {
83 83
        return false;
84 84
    }
85 85
    return true;
86 86
}
87 87
88 88
fn testU64Shift() -> bool {
89 89
    let a: u64 = 1;
90 90
    let shifted: u64 = a << 32;
91 91
    // Shift by 32 should NOT wrap like u32 would.
92 92
    let back: u64 = shifted >> 32;
93 -
    if back != 1 {
93 +
    if back <> 1 {
94 94
        return false;
95 95
    }
96 96
    return true;
97 97
}
98 98
99 99
fn testI64Bitwise() -> bool {
100 100
    let a: i64 = 0xFF00;
101 101
    let b: i64 = 0x0FF0;
102 102
    let andResult: i64 = a & b;
103 -
    if andResult != 0x0F00 {
103 +
    if andResult <> 0x0F00 {
104 104
        return false;
105 105
    }
106 106
    let orResult: i64 = a | b;
107 -
    if orResult != 0xFFF0 {
107 +
    if orResult <> 0xFFF0 {
108 108
        return false;
109 109
    }
110 110
    let xorResult: i64 = a ^ b;
111 -
    if xorResult != 0xF0F0 {
111 +
    if xorResult <> 0xF0F0 {
112 112
        return false;
113 113
    }
114 114
    return true;
115 115
}
116 116
117 117
fn testWidenI32ToI64() -> bool {
118 118
    let a: i32 = -42;
119 119
    let b: i64 = a as i64;
120 -
    if b != -42 {
120 +
    if b <> -42 {
121 121
        return false;
122 122
    }
123 123
    return true;
124 124
}
125 125
127 127
    let a: u32 = 0xFFFFFFFF;
128 128
    let b: u64 = a as u64;
129 129
    // Should zero-extend, not sign-extend.
130 130
    // If sign-extended, this would be a very large negative number in i64.
131 131
    let c: u64 = b >> 32;
132 -
    if c != 0 {
132 +
    if c <> 0 {
133 133
        return false;
134 134
    }
135 135
    return true;
136 136
}
137 137
138 138
fn testNarrowI64ToI32() -> bool {
139 139
    let a: i64 = 42;
140 140
    let b: i32 = a as i32;
141 -
    if b != 42 {
141 +
    if b <> 42 {
142 142
        return false;
143 143
    }
144 144
    return true;
145 145
}
146 146
147 147
fn testNarrowU64ToU32() -> bool {
148 148
    let a: u64 = 42;
149 149
    let b: u32 = a as u32;
150 -
    if b != 42 {
150 +
    if b <> 42 {
151 151
        return false;
152 152
    }
153 153
    return true;
154 154
}
155 155
179 179
180 180
fn testI64Modulo() -> bool {
181 181
    let a: i64 = 17;
182 182
    let b: i64 = 5;
183 183
    let result: i64 = a % b;
184 -
    if result != 2 {
184 +
    if result <> 2 {
185 185
        return false;
186 186
    }
187 187
    return true;
188 188
}
189 189
190 190
fn testU64Modulo() -> bool {
191 191
    let a: u64 = 17;
192 192
    let b: u64 = 5;
193 193
    let result: u64 = a % b;
194 -
    if result != 2 {
194 +
    if result <> 2 {
195 195
        return false;
196 196
    }
197 197
    return true;
198 198
}
199 199
test/tests/array.repeat.edge.rad +1 -1
3 3
4 4
/// Test large array initialization with repeat syntax.
5 5
fn testLargeArray() -> bool {
6 6
    let arr: [i32; 256] = [7; 256];
7 7
    for x in arr {
8 -
        if x != 7 {
8 +
        if x <> 7 {
9 9
            return false;
10 10
        }
11 11
    }
12 12
    return true;
13 13
}
test/tests/assert.basic.rad +1 -1
6 6
7 7
    // Assert with comparison.
8 8
    let x: i32 = 42;
9 9
    assert x == 42;
10 10
    assert x > 0;
11 -
    assert x != 0;
11 +
    assert x <> 0;
12 12
13 13
    // Assert with message.
14 14
    assert x == 42, "x should be 42";
15 15
16 16
    // Assert with block form.
test/tests/assign.mutable.rad +10 -10
182 182
           (level4.age + level4.score);
183 183
    // (11+21) + (12+22) + (13+23) + (14+24) = 32+34+36+38 = 140
184 184
}
185 185
186 186
@default fn main() -> i32 {
187 -
    if (testBasicAliasing() != 35) {
187 +
    if (testBasicAliasing() <> 35) {
188 188
        return 1; // Failure
189 189
    }
190 -
    if (testStructAliasing() != 155) {
190 +
    if (testStructAliasing() <> 155) {
191 191
        return 1; // Failure
192 192
    }
193 -
    if (testArrayAliasing() != 33) {
193 +
    if (testArrayAliasing() <> 33) {
194 194
        return 1; // Failure
195 195
    }
196 -
    if (testNestedStructArrayMutation() != 122) {
196 +
    if (testNestedStructArrayMutation() <> 122) {
197 197
        return 1; // Failure
198 198
    }
199 -
    if (testVariableOverwriting() != 160) {
199 +
    if (testVariableOverwriting() <> 160) {
200 200
        return 1; // Failure
201 201
    }
202 -
    if (testArrayOfStructsAliasing() != 152) {
202 +
    if (testArrayOfStructsAliasing() <> 152) {
203 203
        return 1; // Failure
204 204
    }
205 -
    if (testMutationChain() != 17) {
205 +
    if (testMutationChain() <> 17) {
206 206
        return 1; // Failure
207 207
    }
208 -
    if (testStructFieldReassignment() != 140) {
208 +
    if (testStructFieldReassignment() <> 140) {
209 209
        return 1; // Failure
210 210
    }
211 -
    if (testArrayIndexMutation() != 195) {
211 +
    if (testArrayIndexMutation() <> 195) {
212 212
        return 1; // Failure
213 213
    }
214 -
    if (testMultipleAssignmentLevels() != 140) {
214 +
    if (testMultipleAssignmentLevels() <> 140) {
215 215
        return 1; // Failure
216 216
    }
217 217
    return 0; // Success
218 218
}
test/tests/binop.cmp.rad +2 -2
3 3
    let a: i32 = 5;
4 4
    let b: i32 = 5;
5 5
    let c: i32 = 6;
6 6
7 7
    assert (a == b);
8 -
    assert a != c;
8 +
    assert a <> c;
9 9
10 10
    assert a == b;
11 -
    assert (a != c);
11 +
    assert (a <> c);
12 12
13 13
    assert (a < c);
14 14
    assert a >= b;
15 15
    assert c >= a;
16 16
test/tests/bool.comparison.array.rad +2 -2
9 9
10 10
fn arrayNotEqual() -> bool {
11 11
    let a1: [u32; 3] = [42, 8, 3];
12 12
    let a2: [u32; 3] = [42, 9, 3];
13 13
14 -
    return a1 != a2;
14 +
    return a1 <> a2;
15 15
}
16 16
17 17
fn arrayPointerNotEqual() -> bool {
18 18
    // Same array values, but different addresses.
19 19
    let a1: [u32; 3] = [9, 42, 3];
20 20
    let a2: [u32; 3] = [9, 42, 3];
21 21
22 -
    return &a1 != &a2;
22 +
    return &a1 <> &a2;
23 23
}
24 24
25 25
fn arrayPointerEqual() -> bool {
26 26
    let a1: [u32; 3] = [9, 42, 3];
27 27
test/tests/bool.comparison.nested.gen.rad +2 -2
30 30
    };
31 31
    let c2: Circle = Circle {
32 32
        center: Point { x: 15, y: 20 },
33 33
        radius: 5,
34 34
    };
35 -
    return c1 != c2;
35 +
    return c1 <> c2;
36 36
}
37 37
38 38
fn testNestedNotEqualRadius() -> bool {
39 39
    let c1: Circle = Circle {
40 40
        center: Point { x: 10, y: 20 },
42 42
    };
43 43
    let c2: Circle = Circle {
44 44
        center: Point { x: 10, y: 20 },
45 45
        radius: 10,
46 46
    };
47 -
    return c1 != c2;
47 +
    return c1 <> c2;
48 48
}
49 49
50 50
@default fn main() -> i32 {
51 51
    assert testNestedEqual();
52 52
    assert testNestedNotEqualCenter();
test/tests/bool.comparison.opt.rad +6 -6
4 4
    let opt1: ?i32 = 42;
5 5
    let opt2: ?u8 = 9;
6 6
    let opt3: ?bool = nil;
7 7
8 8
    return
9 -
        nil != opt1 and
10 -
        opt1 != nil and
11 -
        nil != opt2 and
12 -
        opt2 != nil and
9 +
        nil <> opt1 and
10 +
        opt1 <> nil and
11 +
        nil <> opt2 and
12 +
        opt2 <> nil and
13 13
        nil == opt3 and
14 14
        opt3 == nil;
15 15
}
16 16
17 17
fn testSelfComparisons() -> bool {
28 28
    let opt2: ?u8 = 9;
29 29
30 30
    return
31 31
        opt1 == 42 and
32 32
        opt2 == 9 and
33 -
        opt1 != 9 and
34 -
        opt2 != 42;
33 +
        opt1 <> 9 and
34 +
        opt2 <> 42;
35 35
}
36 36
37 37
fn testValueEqOpt() -> bool {
38 38
    let opt1: ?i32 = 42;
39 39
    let opt2: ?u8 = 9;
test/tests/bool.comparison.record.gen.rad +3 -3
19 19
20 20
fn testPointNotEqualX() -> bool {
21 21
    let p1: Point = Point { x: 10, y: 20 };
22 22
    let p2: Point = Point { x: 15, y: 20 };
23 23
24 -
    return p1 != p2;
24 +
    return p1 <> p2;
25 25
}
26 26
27 27
fn testPointNotEqualY() -> bool {
28 28
    let p1: Point = Point { x: 10, y: 20 };
29 29
    let p2: Point = Point { x: 10, y: 25 };
30 30
31 -
    return p1 != p2;
31 +
    return p1 <> p2;
32 32
}
33 33
34 34
fn testRectEqual() -> bool {
35 35
    let r1: Rect = Rect { width: 100, height: 50 };
36 36
    let r2: Rect = Rect { width: 100, height: 50 };
40 40
41 41
fn testRectNotEqual() -> bool {
42 42
    let r1: Rect = Rect { width: 100, height: 50 };
43 43
    let r2: Rect = Rect { width: 100, height: 60 };
44 44
45 -
    return r1 != r2;
45 +
    return r1 <> r2;
46 46
}
47 47
48 48
@default fn main() -> i32 {
49 49
    assert testPointEqual();
50 50
    assert testPointNotEqualX();
test/tests/bool.comparison.record.rad +2 -2
24 24
25 25
fn packedStructNotEqual() -> bool {
26 26
    let mut s1: Packed = Packed { x: 39, y: 189 };
27 27
    let mut s2: Packed = Packed { x: 39, y: 289 };
28 28
29 -
    return s1 != s2;
29 +
    return s1 <> s2;
30 30
}
31 31
32 32
fn paddedStructEqual() -> bool {
33 33
    let mut s1: Padded = Padded { a: 48, b: 183, c: 493, d: 8192, e: 99 };
34 34
    let mut s2: Padded = Padded { a: 48, b: 183, c: 493, d: 8192, e: 99 };
38 38
39 39
fn paddedStructNotEqual() -> bool {
40 40
    let mut s1: Padded = Padded { a: 48, b: 183, c: 493, d: 8192, e: 99 };
41 41
    let mut s2: Padded = Padded { a: 48, b: 283, c: 493, d: 8192, e: 99 };
42 42
43 -
    return s1 != s2;
43 +
    return s1 <> s2;
44 44
}
45 45
46 46
@default fn main() -> bool {
47 47
    return packedStructEqual()
48 48
       and packedStructNotEqual()
test/tests/bool.comparison.slice.rad +14 -14
1 1
//! returns: 0
2 2
fn memEq(a: *[u8], b: *[u8]) -> bool {
3 -
    if a.len != b.len {
3 +
    if a.len <> b.len {
4 4
        return false;
5 5
    }
6 6
    for i in 0..a.len {
7 -
        if a[i] != b[i] {
7 +
        if a[i] <> b[i] {
8 8
            return false;
9 9
        }
10 10
    }
11 11
    return true;
12 12
}
18 18
fn sliceI32(input: *[i32]) -> *[i32] {
19 19
    return input;
20 20
}
21 21
22 22
fn sliceEqualU32(a: *[u32], b: *[u32]) -> bool {
23 -
    if a.len != b.len {
23 +
    if a.len <> b.len {
24 24
        return false;
25 25
    }
26 26
    for i in 0..a.len {
27 -
        if a[i] != b[i] {
27 +
        if a[i] <> b[i] {
28 28
            return false;
29 29
        }
30 30
    }
31 31
    return true;
32 32
}
33 33
34 34
fn sliceEqualI32(a: *[i32], b: *[i32]) -> bool {
35 -
    if a.len != b.len {
35 +
    if a.len <> b.len {
36 36
        return false;
37 37
    }
38 38
    for i in 0..a.len {
39 -
        if a[i] != b[i] {
39 +
        if a[i] <> b[i] {
40 40
            return false;
41 41
        }
42 42
    }
43 43
    return true;
44 44
}
83 83
    let a1: [u32; 3] = [42, 8, 3];
84 84
85 85
    let s1: *[u32] = &a1[..2];
86 86
    let s2: *[u32] = &a1[1..3];
87 87
88 -
    return s1 != s2 and not sliceEqualU32(s1, s2);
88 +
    return s1 <> s2 and not sliceEqualU32(s1, s2);
89 89
}
90 90
91 91
fn sliceNotEqualSameArray2() -> bool {
92 92
    let a1: [u32; 3] = [42, 8, 3];
93 93
94 94
    let s1: *[u32] = &a1[..2];
95 95
    let s2: *[u32] = &a1[..3];
96 96
97 -
    return s1 != s2 and not sliceEqualU32(s1, s2);
97 +
    return s1 <> s2 and not sliceEqualU32(s1, s2);
98 98
}
99 99
100 100
fn sliceEqualDifferentArray() -> bool {
101 101
    let a1: [u32; 3] = [42, 8, 3];
102 102
    let a2: [u32; 3] = [42, 8, 3];
103 103
104 104
    let s1: *[u32] = &a1[..];
105 105
    let s2: *[u32] = &a2[..];
106 106
107 -
    return sliceEqualU32(s1, s2) and s1 != s2;
107 +
    return sliceEqualU32(s1, s2) and s1 <> s2;
108 108
}
109 109
110 110
fn sliceEqualString1() -> bool {
111 111
    let s1: *[u8] = "ABC";
112 112
    let s2: *[u8] = "ABC";
163 163
fn sliceNotEqualU16() -> bool {
164 164
    let a: [u16; 3] = [1, 2, 3];
165 165
    let b: [u16; 3] = [1, 2, 4];
166 166
    let s: *[u16] = &[1, 2, 3];
167 167
168 -
    return s != &[1, 2, 4]
169 -
       and s != &[1, 0, 3]
170 -
       and &a[..] != &a[1..]
171 -
       and &a[..] != &b[..]
172 -
       and &a[..] != &[1, 3, 3];
168 +
    return s <> &[1, 2, 4]
169 +
       and s <> &[1, 0, 3]
170 +
       and &a[..] <> &a[1..]
171 +
       and &a[..] <> &b[..]
172 +
       and &a[..] <> &[1, 3, 3];
173 173
}
174 174
175 175
fn sliceReturnEqual() -> bool {
176 176
    return memEq(sliceU8("ABC"), "ABC")
177 177
       and sliceEqualI32(sliceI32(&[1, 2, 3]), &[1, 2, 3]);
test/tests/bool.comparison.slice.record.gen.rad +2 -2
8 8
record Line {
9 9
    points: *[Point],
10 10
}
11 11
12 12
fn pointsEqual(a: *[Point], b: *[Point]) -> bool {
13 -
    if a.len != b.len {
13 +
    if a.len <> b.len {
14 14
        return false;
15 15
    }
16 16
    for i in 0..a.len {
17 -
        if a[i].x != b[i].x or a[i].y != b[i].y {
17 +
        if a[i].x <> b[i].x or a[i].y <> b[i].y {
18 18
            return false;
19 19
        }
20 20
    }
21 21
    return true;
22 22
}
test/tests/bool.comparison.slice.union.gen.rad +4 -4
14 14
    points(*[Point]),
15 15
    sizes(*[Size]),
16 16
}
17 17
18 18
fn pointsEqual(a: *[Point], b: *[Point]) -> bool {
19 -
    if a.len != b.len {
19 +
    if a.len <> b.len {
20 20
        return false;
21 21
    }
22 22
    for i in 0..a.len {
23 -
        if a[i].x != b[i].x or a[i].y != b[i].y {
23 +
        if a[i].x <> b[i].x or a[i].y <> b[i].y {
24 24
            return false;
25 25
        }
26 26
    }
27 27
    return true;
28 28
}
29 29
30 30
fn sizesEqual(a: *[Size], b: *[Size]) -> bool {
31 -
    if a.len != b.len {
31 +
    if a.len <> b.len {
32 32
        return false;
33 33
    }
34 34
    for i in 0..a.len {
35 -
        if a[i].width != b[i].width or a[i].height != b[i].height {
35 +
        if a[i].width <> b[i].width or a[i].height <> b[i].height {
36 36
            return false;
37 37
        }
38 38
    }
39 39
    return true;
40 40
}
test/tests/bool.comparison.union.gen.rad +3 -3
15 15
16 16
fn testDifferentVariants() -> bool {
17 17
    let a: Status = Status::pending;
18 18
    let b: Status = Status::running(42);
19 19
20 -
    return a != b;
20 +
    return a <> b;
21 21
}
22 22
23 23
fn testSameVariantSamePayload() -> bool {
24 24
    let a: Status = Status::running(42);
25 25
    let b: Status = Status::running(42);
29 29
30 30
fn testSameVariantDifferentPayload() -> bool {
31 31
    let a: Status = Status::running(42);
32 32
    let b: Status = Status::running(99);
33 33
34 -
    return a != b;
34 +
    return a <> b;
35 35
}
36 36
37 37
fn testBoolPayloadSame() -> bool {
38 38
    let a: Status = Status::completed(true);
39 39
    let b: Status = Status::completed(true);
43 43
44 44
fn testBoolPayloadDifferent() -> bool {
45 45
    let a: Status = Status::completed(true);
46 46
    let b: Status = Status::completed(false);
47 47
48 -
    return a != b;
48 +
    return a <> b;
49 49
}
50 50
51 51
@default fn main() -> i32 {
52 52
    assert testSameVariantNoPayload();
53 53
    assert testDifferentVariants();
test/tests/bool.comparison.union.record.gen.rad +3 -3
23 23
}
24 24
25 25
fn testDifferentVariant() -> bool {
26 26
    let s1: Shape = Shape::circle(10);
27 27
    let s2: Shape = Shape::point(Point { x: 5, y: 5 });
28 -
    return s1 != s2;
28 +
    return s1 <> s2;
29 29
}
30 30
31 31
fn testSameVariantStructEqual() -> bool {
32 32
    let s1: Shape = Shape::point(Point { x: 10, y: 20 });
33 33
    let s2: Shape = Shape::point(Point { x: 10, y: 20 });
35 35
}
36 36
37 37
fn testSameVariantStructNotEqual() -> bool {
38 38
    let s1: Shape = Shape::point(Point { x: 10, y: 20 });
39 39
    let s2: Shape = Shape::point(Point { x: 10, y: 25 });
40 -
    return s1 != s2;
40 +
    return s1 <> s2;
41 41
}
42 42
43 43
fn testRectVariantEqual() -> bool {
44 44
    let s1: Shape = Shape::rect(Size { width: 100, height: 50 });
45 45
    let s2: Shape = Shape::rect(Size { width: 100, height: 50 });
47 47
}
48 48
49 49
fn testRectVariantNotEqual() -> bool {
50 50
    let s1: Shape = Shape::rect(Size { width: 100, height: 50 });
51 51
    let s2: Shape = Shape::rect(Size { width: 100, height: 60 });
52 -
    return s1 != s2;
52 +
    return s1 <> s2;
53 53
}
54 54
55 55
@default fn main() -> i32 {
56 56
    assert testSameVariantPrimitive();
57 57
    assert testDifferentVariant();
test/tests/bool.comparison.union.simple.gen.rad +1 -1
10 10
    let r1: Color = Color::red;
11 11
    let r2: Color = Color::red;
12 12
    let g: Color = Color::green;
13 13
14 14
    assert r1 == r2;
15 -
    assert r1 != g;
15 +
    assert r1 <> g;
16 16
    return 0;
17 17
}
test/tests/bool.operators.complex.rad +1 -1
6 6
    let b: i32 = 10;
7 7
    let c: i32 = 15;
8 8
9 9
    let expr1: bool = (a < b) and (b < c);
10 10
    let expr2: bool = (a < b) or (b > c);
11 -
    let expr3: bool = (a == b) or (b != c);
11 +
    let expr3: bool = (a == b) or (b <> c);
12 12
    let expr4: bool = (a >= b) and (b <= c);
13 13
14 14
    return expr1 and expr2 and expr3 and not expr4;
15 15
}
test/tests/cast.same.size.rad +2 -2
33 33
    // Eq/Ne used as values must compare at the declared width.
34 34
    let eqU8: bool = a == 255;
35 35
    assert eqU8;
36 36
    let eqI8: bool = b == -1;
37 37
    assert eqI8;
38 -
    let neU8: bool = a != 255;
38 +
    let neU8: bool = a <> 255;
39 39
    assert not neU8;
40 -
    let neI8: bool = b != -1;
40 +
    let neI8: bool = b <> -1;
41 41
    assert not neI8;
42 42
    return 0;
43 43
}
test/tests/cmp.rel.rad +1 -1
3 3
    return a == b;
4 4
}
5 5
6 6
/// Returns true when the arguments are not equal.
7 7
fn cmpNe(a: i32, b: i32) -> bool {
8 -
    return a != b;
8 +
    return a <> b;
9 9
}
10 10
11 11
/// Returns true when the first argument is less than the second.
12 12
fn cmpLt(a: i32, b: i32) -> bool {
13 13
    return a < b;
test/tests/cmp.unsigned.rad +1 -1
3 3
    return a == b;
4 4
}
5 5
6 6
/// Returns true when the arguments are not equal.
7 7
fn cmpNe(a: u32, b: u32) -> bool {
8 -
    return a != b;
8 +
    return a <> b;
9 9
}
10 10
11 11
/// Returns true when the first argument is less than the second.
12 12
fn cmpLt(a: u32, b: u32) -> bool {
13 13
    return a < b;
test/tests/cond.expr.aggregate.rad +2 -2
53 53
    return 0;
54 54
}
55 55
56 56
@default fn main() -> i32 {
57 57
    let r1 = testUnion();
58 -
    if r1 != 0 {
58 +
    if r1 <> 0 {
59 59
        return r1;
60 60
    }
61 61
    let r2 = testOptional();
62 -
    if r2 != 0 {
62 +
    if r2 <> 0 {
63 63
        return r2;
64 64
    }
65 65
    return 0;
66 66
}
test/tests/cond.expr.rad +5 -5
64 64
    return 0;
65 65
}
66 66
67 67
@default fn main() -> i32 {
68 68
    let r1 = testScalar();
69 -
    if r1 != 0 {
69 +
    if r1 <> 0 {
70 70
        return r1;
71 71
    }
72 72
    let r2 = testMin();
73 -
    if r2 != 0 {
73 +
    if r2 <> 0 {
74 74
        return r2;
75 75
    }
76 76
    let r3 = testFnArg();
77 -
    if r3 != 0 {
77 +
    if r3 <> 0 {
78 78
        return r3;
79 79
    }
80 80
    let r4 = testEnum();
81 -
    if r4 != 0 {
81 +
    if r4 <> 0 {
82 82
        return r4;
83 83
    }
84 84
    let r5 = testNested();
85 -
    if r5 != 0 {
85 +
    if r5 <> 0 {
86 86
        return r5;
87 87
    }
88 88
    return 0;
89 89
}
test/tests/cond.if.rad +1 -1
31 31
    if a == a {
32 32
        // Ignore.
33 33
    } else {
34 34
        return 7;
35 35
    }
36 -
    if a != b {
36 +
    if a <> b {
37 37
        // Ignore.
38 38
    } else {
39 39
        return 8;
40 40
    }
41 41
test/tests/const-expr-array-size.rad +1 -1
9 9
10 10
static DATA: [i32; TOTAL] = undefined;
11 11
12 12
@default fn main() -> i32 {
13 13
    // Verify the array has the expected length.
14 -
    if DATA.len != 12 { return 1; }
14 +
    if DATA.len <> 12 { return 1; }
15 15
    return 0;
16 16
}
test/tests/const-expr-refs.rad +10 -10
15 15
constant J: i32 = A ^ B;
16 16
constant K: i32 = A << 2;
17 17
constant L: i32 = B >> 1;
18 18
19 19
@default fn main() -> i32 {
20 -
    if C != 30 { return 1; }
21 -
    if D != 60 { return 2; }
22 -
    if E != 50 { return 3; }
23 -
    if F != 10 { return 4; }
24 -
    if G != 1 { return 5; }
25 -
    if H != 30 { return 6; }
26 -
    if I != 0 { return 7; }
27 -
    if J != 30 { return 8; }
28 -
    if K != 40 { return 9; }
29 -
    if L != 10 { return 10; }
20 +
    if C <> 30 { return 1; }
21 +
    if D <> 60 { return 2; }
22 +
    if E <> 50 { return 3; }
23 +
    if F <> 10 { return 4; }
24 +
    if G <> 1 { return 5; }
25 +
    if H <> 30 { return 6; }
26 +
    if I <> 0 { return 7; }
27 +
    if J <> 30 { return 8; }
28 +
    if K <> 40 { return 9; }
29 +
    if L <> 10 { return 10; }
30 30
    return 0;
31 31
}
test/tests/ecall.i64.rad +1 -1
9 9
10 10
    // Write to stdout. The pointer is passed as i64.
11 11
    let n = ecall(64, 1, msg.ptr as i64, msg.len as i64, 0);
12 12
13 13
    // Return value should be 3 (bytes written).
14 -
    if n != 3 {
14 +
    if n <> 3 {
15 15
        return 1;
16 16
    }
17 17
    return 0;
18 18
}
test/tests/edge.cases.4.rad +1 -1
51 51
        else return 40;
52 52
53 53
    let case TypeSig::Integer { width: w2, .. } = sig
54 54
        else return 41;
55 55
56 -
    if w2 != 4 {
56 +
    if w2 <> 4 {
57 57
        return w2 as i32;
58 58
    }
59 59
    return 0;
60 60
}
test/tests/edge.cases.6.rad +3 -3
91 91
    ANALYZER.entries[idx] = entry;
92 92
    ANALYZER.len = idx + 1;
93 93
}
94 94
95 95
fn checkHeader(expected: *[Entry]) -> i32 {
96 -
    if ANALYZER.entries.ptr != expected.ptr or ANALYZER.entries.len != expected.len {
96 +
    if ANALYZER.entries.ptr <> expected.ptr or ANALYZER.entries.len <> expected.len {
97 97
        // Slice header got clobbered instead of the backing storage.
98 98
        return 1;
99 99
    }
100 -
    if ANALYZER.len != 1 {
100 +
    if ANALYZER.len <> 1 {
101 101
        // Bookkeeping field was overwritten by the bad store.
102 102
        return 2;
103 103
    }
104 104
    assert ANALYZER.pad0 == 0xDEADAAA0 and ANALYZER.pad1 == 0xDEADAAA1;
105 105
106 106
    let stored = STORAGE[0];
107 -
    if stored.a != 0xAAAA1111 or stored.b != 0xBBBB2222 or stored.c != 0xCCCC3333 or stored.d != 0xDDDD4444 or stored.e != 0xEEEE5555 or stored.f != 0x12345601 or stored.j != 0x12345605 or stored.t != 0x1234560F {
107 +
    if stored.a <> 0xAAAA1111 or stored.b <> 0xBBBB2222 or stored.c <> 0xCCCC3333 or stored.d <> 0xDDDD4444 or stored.e <> 0xEEEE5555 or stored.f <> 0x12345601 or stored.j <> 0x12345605 or stored.t <> 0x1234560F {
108 108
        // The write never hit the backing buffer.
109 109
        return 3;
110 110
    }
111 111
    return 0;
112 112
}
test/tests/error.catch.rad +1 -1
34 34
    let ptrErr: ?*i32 = try? returnsPtrErr();
35 35
    assert ptrErr == nil;
36 36
37 37
    // try? on success
38 38
    let optOk: ?u32 = try? returnsOk();
39 -
    assert optOk != nil;
39 +
    assert optOk <> nil;
40 40
    if let v = optOk {
41 41
        assert v == 21;
42 42
    }
43 43
44 44
    // try? on error
test/tests/error.multi.try.optional.rad +1 -1
17 17
    let r1 = try? failA();
18 18
    assert r1 == nil;
19 19
20 20
    // try? on success should produce the value.
21 21
    let r2 = try? succeed();
22 -
    assert r2 != nil;
22 +
    assert r2 <> nil;
23 23
    let val = r2 else {
24 24
        return 3;
25 25
    };
26 26
    assert val == 77;
27 27
    return 0;
test/tests/error.try.optional.rad +3 -3
36 36
}
37 37
38 38
@default fn main() -> i32 {
39 39
    // Test 1: try? on success returns Some(value)
40 40
    let result1: ?u32 = try? returnsOk();
41 -
    assert result1 != nil;
41 +
    assert result1 <> nil;
42 42
    if let x = result1 {
43 43
        assert x == 42;
44 44
    }
45 45
46 46
    // Test 2: try? on error returns nil
59 59
        return 6;
60 60
    }
61 61
62 62
    // Test 5: try? in non-throwing function
63 63
    let result5: ?u32 = nonThrowingCaller();
64 -
    assert result5 != nil;
64 +
    assert result5 <> nil;
65 65
    if let x = result5 {
66 66
        assert x == 42;
67 67
    }
68 68
69 69
    // Test 6: try? with record return type
70 70
    let result8: ?Point = try? returnsOkPoint();
71 -
    assert result8 != nil;
71 +
    assert result8 <> nil;
72 72
    if let p = result8 {
73 73
        assert p.x == 10;
74 74
        assert p.y == 20;
75 75
    }
76 76
test/tests/for.else.continue.rad +1 -1
11 11
        let name = fields[i].name
12 12
            else continue;
13 13
        if name.len == target.len {
14 14
            let mut eq = true;
15 15
            for j in 0..name.len {
16 -
                if name[j] != target[j] {
16 +
                if name[j] <> target[j] {
17 17
                    eq = false;
18 18
                }
19 19
            }
20 20
            if eq {
21 21
                return fields[i].value;
test/tests/if-let-mut.rad +6 -6
11 11
fn testIfLetMut() -> i32 {
12 12
    let opt = getOptional(10);
13 13
14 14
    if let mut v = opt {
15 15
        v = v + 5;
16 -
        if v != 15 {
16 +
        if v <> 15 {
17 17
            return 1;
18 18
        }
19 19
    } else {
20 20
        return 2;
21 21
    }
37 37
38 38
    let mut v = opt else {
39 39
        return 4;
40 40
    };
41 41
    v = v + 8;
42 -
    if v != 50 {
42 +
    if v <> 50 {
43 43
        return 5;
44 44
    }
45 45
    return 0;
46 46
}
47 47
55 55
    return 6;
56 56
}
57 57
58 58
@default fn main() -> i32 {
59 59
    let r1 = testIfLetMut();
60 -
    if r1 != 0 {
60 +
    if r1 <> 0 {
61 61
        return r1;
62 62
    }
63 63
    let r2 = testIfLetMutNil();
64 -
    if r2 != 0 {
64 +
    if r2 <> 0 {
65 65
        return r2;
66 66
    }
67 67
    let r3 = testLetMutElse();
68 -
    if r3 != 0 {
68 +
    if r3 <> 0 {
69 69
        return r3;
70 70
    }
71 71
    let r4 = testLetMutElseNil();
72 -
    if r4 != 0 {
72 +
    if r4 <> 0 {
73 73
        return r4;
74 74
    }
75 75
    return 0;
76 76
}
test/tests/index.u8.rad +5 -5
3 3
@default fn main() -> i32 {
4 4
    let arr: [i32; 4] = [10, 20, 42, 30];
5 5
6 6
    // u8 index.
7 7
    let idx8: u8 = 2;
8 -
    if arr[idx8] != 42 {
8 +
    if arr[idx8] <> 42 {
9 9
        return 1;
10 10
    }
11 11
    // u16 index.
12 12
    let idx16: u16 = 3;
13 -
    if arr[idx16] != 30 {
13 +
    if arr[idx16] <> 30 {
14 14
        return 2;
15 15
    }
16 16
    // u32 index (already worked).
17 17
    let idx32: u32 = 0;
18 -
    if arr[idx32] != 10 {
18 +
    if arr[idx32] <> 10 {
19 19
        return 3;
20 20
    }
21 21
    // Unsuffixed integer literal index.
22 -
    if arr[1] != 20 {
22 +
    if arr[1] <> 20 {
23 23
        return 4;
24 24
    }
25 25
    // u8 index into slice.
26 26
    let s = &arr[..];
27 27
    let si: u8 = 1;
28 -
    if s[si] != 20 {
28 +
    if s[si] <> 20 {
29 29
        return 5;
30 30
    }
31 31
    return 0;
32 32
}
test/tests/integer.bitwise.basic.rad +6 -6
8 8
    let xorResult:    i32 = a ^ b;  // 0b01001
9 9
    let notResult:    i32 = ~a;     // 0b00011
10 10
    let lshiftResult: i32 = a << 1; // 0b11000
11 11
    let rshiftResult: i32 = a >> 2; // 0b00011
12 12
13 -
    if andResult    != 4   { return (1) - 42; }
14 -
    if orResult     != 13  { return (1) - 42; }
15 -
    if xorResult    != 9   { return (1) - 42; }
16 -
    if notResult    != -13 { return (1) - 42; }
17 -
    if lshiftResult != 24  { return (1) - 42; }
18 -
    if rshiftResult != 3   { return (1) - 42; }
13 +
    if andResult    <> 4   { return (1) - 42; }
14 +
    if orResult     <> 13  { return (1) - 42; }
15 +
    if xorResult    <> 9   { return (1) - 42; }
16 +
    if notResult    <> -13 { return (1) - 42; }
17 +
    if lshiftResult <> 24  { return (1) - 42; }
18 +
    if rshiftResult <> 3   { return (1) - 42; }
19 19
20 20
    return (42) - 42;
21 21
}
test/tests/large.blit.store.rad +3 -3
66 66
    return 0;
67 67
}
68 68
69 69
@default fn main() -> i32 {
70 70
    let r1 = storeLargeOffset();
71 -
    if r1 != 0 {
71 +
    if r1 <> 0 {
72 72
        return 10 + r1;
73 73
    }
74 74
75 75
    let r2 = copyBig();
76 -
    if r2 != 0 {
76 +
    if r2 <> 0 {
77 77
        return 20 + r2;
78 78
    }
79 79
80 80
    let r3 = copyIndependence();
81 -
    if r3 != 0 {
81 +
    if r3 <> 0 {
82 82
        return 30 + r3;
83 83
    }
84 84
85 85
    return 0;
86 86
}
test/tests/literal.w64.rad +9 -9
5 5
fn testU64MaxLiteral() -> bool {
6 6
    let x: u64 = 18446744073709551615;
7 7
    // Check low and high bits.
8 8
    let lo: u64 = x & 0xFFFFFFFF;
9 9
    let hi: u64 = x >> 32;
10 -
    if lo != 0xFFFFFFFF {
10 +
    if lo <> 0xFFFFFFFF {
11 11
        return false;
12 12
    }
13 -
    if hi != 0xFFFFFFFF {
13 +
    if hi <> 0xFFFFFFFF {
14 14
        return false;
15 15
    }
16 16
    return true;
17 17
}
18 18
19 19
fn testI64MaxLiteral() -> bool {
20 20
    let x: i64 = 9223372036854775807;
21 21
    let shifted: i64 = x >> 32;
22 -
    if shifted != 0x7FFFFFFF {
22 +
    if shifted <> 0x7FFFFFFF {
23 23
        return false;
24 24
    }
25 25
    return true;
26 26
}
27 27
29 29
    let x: i64 = -9223372036854775808;
30 30
    if x >= 0 {
31 31
        return false;
32 32
    }
33 33
    let shifted: i64 = x >> 63;
34 -
    if shifted != -1 {
34 +
    if shifted <> -1 {
35 35
        return false;
36 36
    }
37 37
    return true;
38 38
}
39 39
40 40
fn testHexW64Literal() -> bool {
41 41
    let x: u64 = 0xDEADBEEFCAFEBABE;
42 42
    let lo: u32 = x as u32;
43 43
    let hi: u32 = (x >> 32) as u32;
44 -
    if lo != 0xCAFEBABE {
44 +
    if lo <> 0xCAFEBABE {
45 45
        return false;
46 46
    }
47 -
    if hi != 0xDEADBEEF {
47 +
    if hi <> 0xDEADBEEF {
48 48
        return false;
49 49
    }
50 50
    return true;
51 51
}
52 52
53 53
fn testLargeI64Arith() -> bool {
54 54
    let a: i64 = 1000000000000;
55 55
    let b: i64 = 2000000000000;
56 56
    let result: i64 = a + b;
57 -
    if result != 3000000000000 {
57 +
    if result <> 3000000000000 {
58 58
        return false;
59 59
    }
60 60
    return true;
61 61
}
62 62
63 63
fn testU64Overflow32() -> bool {
64 64
    // 2^32 + 1 = 4294967297
65 65
    let x: u64 = 4294967297;
66 66
    let lo: u32 = x as u32;
67 67
    let hi: u32 = (x >> 32) as u32;
68 -
    if lo != 1 {
68 +
    if lo <> 1 {
69 69
        return false;
70 70
    }
71 -
    if hi != 1 {
71 +
    if hi <> 1 {
72 72
        return false;
73 73
    }
74 74
    return true;
75 75
}
76 76
test/tests/load.u32.high.rad +3 -3
25 25
    // Shift right by 1: if correctly zero-extended (0x80000000),
26 26
    // u32 shift gives 0x40000000.
27 27
    // If sign-extended to 64-bit and then shifted as u32 via `srliw`,
28 28
    // the *w variant only looks at low 32 bits, so this still works.
29 29
    let shifted = val >> 1;
30 -
    if shifted != 0x40000000 {
30 +
    if shifted <> 0x40000000 {
31 31
        return false;
32 32
    }
33 33
    return true;
34 34
}
35 35
39 39
    let val = arr[0];
40 40
41 41
    // If lw sign-extends, val in register is 0xFFFFFFFFFFFFFFFF.
42 42
    // Adding 1 as u32 (via addw): 0xFFFFFFFF + 1 = 0 (wraps). OK either way.
43 43
    // But comparing: val should equal 0xFFFFFFFF as u32.
44 -
    if val != 0xFFFFFFFF {
44 +
    if val <> 0xFFFFFFFF {
45 45
        return false;
46 46
    }
47 47
48 48
    // The key test: widening to u64 should give 0x00000000FFFFFFFF,
49 49
    // not 0xFFFFFFFFFFFFFFFF.
50 50
    let wide: u64 = val as u64;
51 -
    if wide != 0xFFFFFFFF {
51 +
    if wide <> 0xFFFFFFFF {
52 52
        return false;
53 53
    }
54 54
55 55
    return true;
56 56
}
test/tests/match.value.copy.rad +3 -3
75 75
    return 0;
76 76
}
77 77
78 78
@default fn main() -> i32 {
79 79
    let r1 = testLetCase();
80 -
    if r1 != 0 {
80 +
    if r1 <> 0 {
81 81
        return r1;
82 82
    }
83 83
    let r2 = testIfLetCase();
84 -
    if r2 != 0 {
84 +
    if r2 <> 0 {
85 85
        return r2;
86 86
    }
87 87
    let r3 = testMatch();
88 -
    if r3 != 0 {
88 +
    if r3 <> 0 {
89 89
        return r3;
90 90
    }
91 91
    return 0;
92 92
}
test/tests/memzero.result.bug.rad +1 -1
21 21
    try fallible(false) catch {
22 22
        guard = 0xDEAD;
23 23
    };
24 24
    guard = 0xDEADBEEF;
25 25
26 -
    if guard != 0xDEADBEEF {
26 +
    if guard <> 0xDEADBEEF {
27 27
        return 1; // Guard was clobbered by an overzealous memzero.
28 28
    }
29 29
    return 0;
30 30
}
test/tests/mutref.scalar.rad +1 -1
4 4
}
5 5
6 6
fn test() -> i32 {
7 7
    let mut x: i32 = 0;
8 8
    let r: bool = modify(&mut x, false);
9 -
    if x != 1 {
9 +
    if x <> 1 {
10 10
        return 1;
11 11
    }
12 12
    return 0;
13 13
}
test/tests/nil.cmp.rad +6 -6
3 3
// nil == nil is always true
4 4
fn nilEqNil() -> bool {
5 5
    return nil == nil;
6 6
}
7 7
8 -
// nil != nil is always false
8 +
// nil <> nil is always false
9 9
fn nilNeNil() -> bool {
10 -
    return nil != nil;
10 +
    return nil <> nil;
11 11
}
12 12
13 13
// nil == opt (reversed order, pointer optional)
14 14
fn nilEqOptPtr(a: ?*i32) -> bool {
15 15
    return nil == a;
16 16
}
17 17
18 -
// nil != opt (reversed order, pointer optional)
18 +
// nil <> opt (reversed order, pointer optional)
19 19
fn nilNeOptPtr(a: ?*i32) -> bool {
20 -
    return nil != a;
20 +
    return nil <> a;
21 21
}
22 22
23 23
// nil == opt (reversed order, aggregate optional)
24 24
fn nilEqOptAgg(a: ?i32) -> bool {
25 25
    return nil == a;
26 26
}
27 27
28 -
// nil != opt (reversed order, aggregate optional)
28 +
// nil <> opt (reversed order, aggregate optional)
29 29
fn nilNeOptAgg(a: ?i32) -> bool {
30 -
    return nil != a;
30 +
    return nil <> a;
31 31
}
test/tests/opt.nil.check.rad +4 -4
17 17
    let p = makeAlignedPtr();
18 18
    let opt: ?*u8 = p;
19 19
20 20
    // The pointer is not nil, but its low byte is 0x00.
21 21
    // A W8 comparison would wrongly say it's nil.
22 -
    assert opt != nil;
22 +
    assert opt <> nil;
23 23
    if let v = opt {
24 24
        // Good: correctly identified as non-nil.
25 25
        return 0;
26 26
    }
27 27
    return 2;
34 34
    let offset: u64 = 256 - (base % 256);
35 35
    // Create a slice starting at an address whose low byte is 0.
36 36
    let s: *[u8] = &arr[offset as u32 ..];
37 37
38 38
    let opt: ?*[u8] = s;
39 -
    assert opt != nil;
39 +
    assert opt <> nil;
40 40
    if let v = opt {
41 41
        return 0;
42 42
    }
43 43
    return 2;
44 44
}
45 45
46 46
@default fn main() -> i32 {
47 47
    let r1 = testOptionalPtrNilCheck();
48 -
    if r1 != 0 {
48 +
    if r1 <> 0 {
49 49
        return r1;
50 50
    }
51 51
    let r2 = testOptionalSliceNilCheck();
52 -
    if r2 != 0 {
52 +
    if r2 <> 0 {
53 53
        return 10 + r2;
54 54
    }
55 55
    return 0;
56 56
}
test/tests/opt.record.eq.rad +2 -2
12 12
13 13
@default fn main() -> bool {
14 14
    let outerA = Outer { item: Inner { start: 3, end: 9 } };
15 15
    let outerB = Outer { item: Inner { start: 3, end: 9 } };
16 16
17 -
    if outerA != outerB {
17 +
    if outerA <> outerB {
18 18
        return false;
19 19
    }
20 20
21 21
    let outerC = Outer { item: Inner { start: 4, end: 6 } };
22 22
    if outerA == outerC {
30 30
31 31
    optA = outerA;
32 32
    optB = outerB;
33 33
    optDiff = outerC;
34 34
35 -
    if optA != optB {
35 +
    if optA <> optB {
36 36
        return false;
37 37
    }
38 38
    if optA == optDiff {
39 39
        return false;
40 40
    }
test/tests/opt.slice.npo.rad +12 -12
21 21
fn checkWrap() -> u8 {
22 22
    let arr: [u8; 3] = [1, 2, 3];
23 23
    let s = &arr[..];
24 24
    let opt: ?*[u8] = s;
25 25
26 -
    assert opt != nil;
26 +
    assert opt <> nil;
27 27
    return 0;
28 28
}
29 29
30 30
fn checkIfLet() -> u8 {
31 31
    let arr: [u8; 3] = [10, 20, 30];
70 70
71 71
fn checkReturn() -> u8 {
72 72
    let a = returnNil();
73 73
    assert a == nil;
74 74
    let b = returnSome();
75 -
    assert b != nil;
75 +
    assert b <> nil;
76 76
    if let val = b {
77 77
        assert val[0] == 42;
78 78
    } else {
79 79
        return 53;
80 80
    }
112 112
113 113
    let arr: [u8; 2] = [1, 2];
114 114
    let s = &arr[..];
115 115
    let c: ?*[u8] = s;
116 116
117 -
    // some != nil
118 -
    assert c != a;
117 +
    // some <> nil
118 +
    assert c <> a;
119 119
120 120
    // some == some (same pointer)
121 121
    let d: ?*[u8] = s;
122 122
    assert c == d;
123 123
124 124
    return 0;
125 125
}
126 126
127 127
@default fn main() -> u8 {
128 128
    let r1 = checkSizes();
129 -
    if r1 != 0 {
129 +
    if r1 <> 0 {
130 130
        return r1;
131 131
    }
132 132
    let r2 = checkNil();
133 -
    if r2 != 0 {
133 +
    if r2 <> 0 {
134 134
        return r2;
135 135
    }
136 136
    let r3 = checkWrap();
137 -
    if r3 != 0 {
137 +
    if r3 <> 0 {
138 138
        return r3;
139 139
    }
140 140
    let r4 = checkIfLet();
141 -
    if r4 != 0 {
141 +
    if r4 <> 0 {
142 142
        return r4;
143 143
    }
144 144
    let r5 = checkLetElse();
145 -
    if r5 != 0 {
145 +
    if r5 <> 0 {
146 146
        return r5;
147 147
    }
148 148
    let r6 = checkReturn();
149 -
    if r6 != 0 {
149 +
    if r6 <> 0 {
150 150
        return r6;
151 151
    }
152 152
    let r7 = checkMatch();
153 -
    if r7 != 0 {
153 +
    if r7 <> 0 {
154 154
        return r7;
155 155
    }
156 156
    let r8 = checkEq();
157 -
    if r8 != 0 {
157 +
    if r8 <> 0 {
158 158
        return r8;
159 159
    }
160 160
    return 0;
161 161
}
test/tests/optional.ptr.eq.rad +2 -2
3 3
fn optPtrEq(a: ?*i32, b: ?*i32) -> bool {
4 4
    return a == b;
5 5
}
6 6
7 7
fn optPtrNeq(a: ?*i32, b: ?*i32) -> bool {
8 -
    return a != b;
8 +
    return a <> b;
9 9
}
10 10
11 11
fn optPtrEqNil(a: ?*i32) -> bool {
12 12
    return a == nil;
13 13
}
14 14
15 15
fn optPtrNeqNil(a: ?*i32) -> bool {
16 -
    return a != nil;
16 +
    return a <> nil;
17 17
}
test/tests/prog.ackermann.rad +5 -5
146 146
            limit = 8;
147 147
        }
148 148
        while n <= limit {
149 149
            let r: i32 = ack(m, n);
150 150
            let memoR: i32 = ackMemo(m, n);
151 -
            if r != memoR {
151 +
            if r <> memoR {
152 152
                return (m * 20 + n) as i32 + 1;
153 153
            }
154 154
            n += 1;
155 155
        }
156 156
        m += 1;
190 190
    return 0;
191 191
}
192 192
193 193
@default fn main() -> i32 {
194 194
    let r1: i32 = testSmallRecursive();
195 -
    if r1 != 0 {
195 +
    if r1 <> 0 {
196 196
        return 10 + r1;
197 197
    }
198 198
199 199
    let r2: i32 = testMemoized();
200 -
    if r2 != 0 {
200 +
    if r2 <> 0 {
201 201
        return 30 + r2;
202 202
    }
203 203
204 204
    let r3: i32 = testCrossCheck();
205 -
    if r3 != 0 {
205 +
    if r3 <> 0 {
206 206
        return 50 + r3;
207 207
    }
208 208
209 209
    let r4: i32 = testMonotonicity();
210 -
    if r4 != 0 {
210 +
    if r4 <> 0 {
211 211
        return 70 + r4;
212 212
    }
213 213
214 214
    return 0;
215 215
}
test/tests/prog.bignum.rad +8 -8
383 383
    return 0;
384 384
}
385 385
386 386
@default fn main() -> i32 {
387 387
    let r1: i32 = testAdd();
388 -
    if r1 != 0 {
388 +
    if r1 <> 0 {
389 389
        return 10 + r1;
390 390
    }
391 391
392 392
    let r2: i32 = testSub();
393 -
    if r2 != 0 {
393 +
    if r2 <> 0 {
394 394
        return 20 + r2;
395 395
    }
396 396
397 397
    let r3: i32 = testMul();
398 -
    if r3 != 0 {
398 +
    if r3 <> 0 {
399 399
        return 30 + r3;
400 400
    }
401 401
402 402
    let r4: i32 = testAddSubIdentity();
403 -
    if r4 != 0 {
403 +
    if r4 <> 0 {
404 404
        return 40 + r4;
405 405
    }
406 406
407 407
    let r5: i32 = testShift();
408 -
    if r5 != 0 {
408 +
    if r5 <> 0 {
409 409
        return 50 + r5;
410 410
    }
411 411
412 412
    let r6: i32 = testLargeMultiply();
413 -
    if r6 != 0 {
413 +
    if r6 <> 0 {
414 414
        return 60 + r6;
415 415
    }
416 416
417 417
    let r7: i32 = testFibonacci();
418 -
    if r7 != 0 {
418 +
    if r7 <> 0 {
419 419
        return 70 + r7;
420 420
    }
421 421
422 422
    let r8: i32 = testCompare();
423 -
    if r8 != 0 {
423 +
    if r8 <> 0 {
424 424
        return 80 + r8;
425 425
    }
426 426
427 427
    return 0;
428 428
}
test/tests/prog.binsearch.rad +4 -4
76 76
fn testAllPresent(data: *[i32]) -> i32 {
77 77
    for value, index in data {
78 78
        let found = binarySearch(data, value) else {
79 79
            return index as i32 + 1;
80 80
        };
81 -
        if found != index {
81 +
        if found <> index {
82 82
            return index as i32 + 1;
83 83
        }
84 84
    }
85 85
    return 0;
86 86
}
90 90
        3, 7, 11, 15, 22, 30, 35, 41, 50, 58,
91 91
        63, 70, 77, 84, 90, 95, 100, 108, 115, 120
92 92
    ];
93 93
94 94
    let r1 = testPresent(&sorted[..]);
95 -
    if r1 != 0 {
95 +
    if r1 <> 0 {
96 96
        return 10 + r1;
97 97
    }
98 98
99 99
    let r2 = testAbsent(&sorted[..]);
100 -
    if r2 != 0 {
100 +
    if r2 <> 0 {
101 101
        return 20 + r2;
102 102
    }
103 103
104 104
    let r3 = testAllPresent(&sorted[..]);
105 -
    if r3 != 0 {
105 +
    if r3 <> 0 {
106 106
        return 30 + r3;
107 107
    }
108 108
    return 0;
109 109
}
test/tests/prog.bubblesort.rad +1 -1
78 78
    let sumAfter = sum(&data[..]);
79 79
    assert sumBefore == sumAfter;
80 80
81 81
    // Check specific element positions.
82 82
    let r = verifyPositions(&data[..]);
83 -
    if r != 0 {
83 +
    if r <> 0 {
84 84
        return 10 + r;
85 85
    }
86 86
    return 0;
87 87
}
test/tests/prog.cordic.rad +7 -7
89 89
90 90
/// Fixed-point multiply: (a * b) >> 16, using half-word decomposition
91 91
/// to avoid 32-bit overflow.
92 92
fn fpmul(a: i32, b: i32) -> i32 {
93 93
    // Determine sign and work with magnitudes.
94 -
    let neg: bool = (a < 0) != (b < 0);
94 +
    let neg: bool = (a < 0) <> (b < 0);
95 95
    let mut ua: u32 = a as u32;
96 96
    if a < 0 {
97 97
        ua = (0 - a) as u32;
98 98
    }
99 99
    let mut ub: u32 = b as u32;
234 234
        4,      // atan(2^-14)
235 235
        2       // atan(2^-15)
236 236
    ];
237 237
238 238
    let r1: i32 = testZero(&atanTable[..]);
239 -
    if r1 != 0 {
239 +
    if r1 <> 0 {
240 240
        return 10 + r1;
241 241
    }
242 242
243 243
    let r2: i32 = testHalfPi(&atanTable[..]);
244 -
    if r2 != 0 {
244 +
    if r2 <> 0 {
245 245
        return 20 + r2;
246 246
    }
247 247
248 248
    let r3: i32 = testPi(&atanTable[..]);
249 -
    if r3 != 0 {
249 +
    if r3 <> 0 {
250 250
        return 30 + r3;
251 251
    }
252 252
253 253
    let r4: i32 = testPythagorean(&atanTable[..]);
254 -
    if r4 != 0 {
254 +
    if r4 <> 0 {
255 255
        return 40 + r4;
256 256
    }
257 257
258 258
    let r5: i32 = testSymmetry(&atanTable[..]);
259 -
    if r5 != 0 {
259 +
    if r5 <> 0 {
260 260
        return 50 + r5;
261 261
    }
262 262
263 263
    let r6: i32 = testPiThird(&atanTable[..]);
264 -
    if r6 != 0 {
264 +
    if r6 <> 0 {
265 265
        return 60 + r6;
266 266
    }
267 267
268 268
    return 0;
269 269
}
test/tests/prog.crc32.rad +4 -4
71 71
        i += 1;
72 72
    }
73 73
    let crcFull = crc32(table, &buf[..]);
74 74
75 75
    // CRC should be non-zero and deterministic.
76 -
    assert crcFull != 0;
76 +
    assert crcFull <> 0;
77 77
78 78
    // Recompute and verify it's the same.
79 79
    assert crc32(table, &buf[..]) == crcFull;
80 80
81 81
    // Known value for bytes 0..31: 0x91267E8A
86 86
@default fn main() -> i32 {
87 87
    let mut table: [u32; 256] = [0; 256];
88 88
    buildTable(&mut table[..]);
89 89
90 90
    let r1 = testTable(&table[..]);
91 -
    if r1 != 0 {
91 +
    if r1 <> 0 {
92 92
        return 10 + r1;
93 93
    }
94 94
95 95
    let r2 = testKnownCRC(&table[..]);
96 -
    if r2 != 0 {
96 +
    if r2 <> 0 {
97 97
        return 20 + r2;
98 98
    }
99 99
100 100
    let r3 = testIncremental(&table[..]);
101 -
    if r3 != 0 {
101 +
    if r3 <> 0 {
102 102
        return 30 + r3;
103 103
    }
104 104
    return 0;
105 105
}
test/tests/prog.dijkstra.rad +11 -11
128 128
        }
129 129
        g.visited[u] = true;
130 130
131 131
        let mut v: u32 = 0;
132 132
        while v < g.numNodes {
133 -
            if g.adj[u][v] != INF and not g.visited[v] {
133 +
            if g.adj[u][v] <> INF and not g.visited[v] {
134 134
                let newDist: u32 = g.dist[u] + g.adj[u][v];
135 135
                if newDist < g.dist[v] {
136 136
                    g.dist[v] = newDist;
137 137
                    g.prev[v] = u as i32;
138 138
                    heapPush(g, newDist, v);
179 179
180 180
    dijkstra(g, 0);
181 181
182 182
    let expected: [u32; 5] = [0, 10, 20, 30, 40];
183 183
    for exp, i in expected {
184 -
        if g.dist[i] != exp {
184 +
        if g.dist[i] <> exp {
185 185
            return i as i32 + 1;
186 186
        }
187 187
    }
188 188
189 189
    let mut path: [u32; 16] = [0; 16];
226 226
227 227
    dijkstra(g, 0);
228 228
229 229
    let expected: [u32; 5] = [0, 1, 3, 4, 4];
230 230
    for exp, i in expected {
231 -
        if g.dist[i] != exp {
231 +
        if g.dist[i] <> exp {
232 232
            return i as i32 + 1;
233 233
        }
234 234
    }
235 235
236 236
    return 0;
241 241
242 242
    let mut i: u32 = 0;
243 243
    while i < 8 {
244 244
        let mut j: u32 = 0;
245 245
        while j < 8 {
246 -
            if i != j {
246 +
            if i <> j {
247 247
                let mut diff: u32 = j - i;
248 248
                if i > j {
249 249
                    diff = i - j;
250 250
                }
251 251
                addEdge(g, i, j, diff * 3 + 1);
258 258
    dijkstra(g, 0);
259 259
260 260
    let mut k: u32 = 1;
261 261
    while k < 8 {
262 262
        let expected: u32 = k * 3 + 1;
263 -
        if g.dist[k] != expected {
263 +
        if g.dist[k] <> expected {
264 264
            return k as i32;
265 265
        }
266 266
        k += 1;
267 267
    }
268 268
329 329
        heap: &mut heap[..],
330 330
        heapSize: 0,
331 331
    };
332 332
333 333
    let r1: i32 = testLinear(&mut g);
334 -
    if r1 != 0 {
334 +
    if r1 <> 0 {
335 335
        return 10 + r1;
336 336
    }
337 337
338 338
    let r2: i32 = testShortcut(&mut g);
339 -
    if r2 != 0 {
339 +
    if r2 <> 0 {
340 340
        return 20 + r2;
341 341
    }
342 342
343 343
    let r3: i32 = testBidirectional(&mut g);
344 -
    if r3 != 0 {
344 +
    if r3 <> 0 {
345 345
        return 30 + r3;
346 346
    }
347 347
348 348
    let r4: i32 = testComplete(&mut g);
349 -
    if r4 != 0 {
349 +
    if r4 <> 0 {
350 350
        return 40 + r4;
351 351
    }
352 352
353 353
    let r5: i32 = testDisconnected(&mut g);
354 -
    if r5 != 0 {
354 +
    if r5 <> 0 {
355 355
        return 50 + r5;
356 356
    }
357 357
358 358
    let r6: i32 = testDiamond(&mut g);
359 -
    if r6 != 0 {
359 +
    if r6 <> 0 {
360 360
        return 60 + r6;
361 361
    }
362 362
363 363
    return 0;
364 364
}
test/tests/prog.eval.rad +7 -7
198 198
199 199
@default fn main() -> i32 {
200 200
    let mut pool: Pool = Pool { nodes: [Expr::Num(0); 64], count: 0 };
201 201
202 202
    let r1 = testSimpleAdd(&mut pool);
203 -
    if r1 != 0 {
203 +
    if r1 <> 0 {
204 204
        return 10 + r1;
205 205
    }
206 206
207 207
    let r2 = testNested(&mut pool);
208 -
    if r2 != 0 {
208 +
    if r2 <> 0 {
209 209
        return 20 + r2;
210 210
    }
211 211
212 212
    let r3 = testComplex(&mut pool);
213 -
    if r3 != 0 {
213 +
    if r3 <> 0 {
214 214
        return 30 + r3;
215 215
    }
216 216
217 217
    let r4 = testNeg(&mut pool);
218 -
    if r4 != 0 {
218 +
    if r4 <> 0 {
219 219
        return 40 + r4;
220 220
    }
221 221
222 222
    let r5 = testDeep(&mut pool);
223 -
    if r5 != 0 {
223 +
    if r5 <> 0 {
224 224
        return 50 + r5;
225 225
    }
226 226
227 227
    let r6 = testMixed(&mut pool);
228 -
    if r6 != 0 {
228 +
    if r6 <> 0 {
229 229
        return 60 + r6;
230 230
    }
231 231
232 232
    let r7 = testSingleNum(&mut pool);
233 -
    if r7 != 0 {
233 +
    if r7 <> 0 {
234 234
        return 70 + r7;
235 235
    }
236 236
    return 0;
237 237
}
test/tests/prog.hanoi.rad +3 -3
140 140
141 141
    // Solve: move all disks from peg 0 to peg 1 using peg 2.
142 142
    hanoi(&mut ml, NUM_DISKS, 0, 1, 2);
143 143
144 144
    let r1 = testMoveCount(&ml);
145 -
    if r1 != 0 {
145 +
    if r1 <> 0 {
146 146
        return 10 + r1;
147 147
    }
148 148
149 149
    let r2 = testSpecificMoves(&ml);
150 -
    if r2 != 0 {
150 +
    if r2 <> 0 {
151 151
        return 20 + r2;
152 152
    }
153 153
154 154
    let r3 = testSimulate(&ml);
155 -
    if r3 != 0 {
155 +
    if r3 <> 0 {
156 156
        return 30 + r3;
157 157
    }
158 158
    return 0;
159 159
}
test/tests/prog.huffman.rad +9 -9
148 148
        case HNodeKind::Leaf(sym) => {
149 149
            s.codeBits[sym] = code;
150 150
            s.codeLen[sym] = depth;
151 151
        }
152 152
        case HNodeKind::Interior => {
153 -
            if s.nodes[nodeIdx].left != NIL {
153 +
            if s.nodes[nodeIdx].left <> NIL {
154 154
                generateCodes(s, s.nodes[nodeIdx].left, code << 1, depth + 1);
155 155
            }
156 -
            if s.nodes[nodeIdx].right != NIL {
156 +
            if s.nodes[nodeIdx].right <> NIL {
157 157
                generateCodes(s, s.nodes[nodeIdx].right, (code << 1) | 1, depth + 1);
158 158
            }
159 159
        }
160 160
    }
161 161
}
239 239
    generateCodes(s, root, 0, 0);
240 240
241 241
    // All symbols should have non-zero code lengths.
242 242
    let mut i: u32 = 0;
243 243
    while i < 5 {
244 -
        assert s.codeLen[i] != 0;
244 +
        assert s.codeLen[i] <> 0;
245 245
        i += 1;
246 246
    }
247 247
248 248
    // No two symbols at the same depth should have the same code.
249 249
    let mut a: u32 = 0;
250 250
    while a < 5 {
251 251
        let mut b: u32 = a + 1;
252 252
        while b < 5 {
253 253
            if s.codeLen[a] == s.codeLen[b] {
254 -
                assert s.codeBits[a] != s.codeBits[b];
254 +
                assert s.codeBits[a] <> s.codeBits[b];
255 255
            }
256 256
            b += 1;
257 257
        }
258 258
        a += 1;
259 259
    }
276 276
277 277
    assert count == 16;
278 278
279 279
    // Verify round-trip.
280 280
    for expected, i in msg {
281 -
        if decoded[i] != expected {
281 +
        if decoded[i] <> expected {
282 282
            return i as i32 + 2;
283 283
        }
284 284
    }
285 285
286 286
    return 0;
368 368
        bitstream: &mut bitstream[..],
369 369
        bitCount: 0,
370 370
    };
371 371
372 372
    let r1: i32 = testBasic(&mut s);
373 -
    if r1 != 0 {
373 +
    if r1 <> 0 {
374 374
        return 10 + r1;
375 375
    }
376 376
377 377
    let r2: i32 = testRoundTrip(&mut s);
378 -
    if r2 != 0 {
378 +
    if r2 <> 0 {
379 379
        return 20 + r2;
380 380
    }
381 381
382 382
    let r3: i32 = testSkewed(&mut s);
383 -
    if r3 != 0 {
383 +
    if r3 <> 0 {
384 384
        return 30 + r3;
385 385
    }
386 386
387 387
    let r4: i32 = testUniform(&mut s);
388 -
    if r4 != 0 {
388 +
    if r4 <> 0 {
389 389
        return 40 + r4;
390 390
    }
391 391
392 392
    return 0;
393 393
}
test/tests/prog.hybridsort.rad +5 -5
35 35
            if data[j] < data[minIdx] {
36 36
                minIdx = j;
37 37
            }
38 38
            j += 1;
39 39
        }
40 -
        if minIdx != i {
40 +
        if minIdx <> i {
41 41
            let tmp = data[i];
42 42
            data[i] = data[minIdx];
43 43
            data[minIdx] = tmp;
44 44
        }
45 45
        i += 1;
70 70
}
71 71
72 72
/// Compare two arrays element by element.
73 73
fn arraysEqual(a: *[i32], b: *[i32]) -> i32 {
74 74
    for val, i in a {
75 -
        if val != b[i] {
75 +
        if val <> b[i] {
76 76
            return i as i32 + 1;
77 77
        }
78 78
    }
79 79
    return 0;
80 80
}
84 84
    // Sorted: 2 3 6 8 10 14 19 25 27 33 39 41 45 48 53 56 62 67 72 74 81 88 91 97
85 85
    let expected: [i32; 6] = [2, 3, 6, 41, 91, 97];
86 86
    let indices: [u32; 6] = [0, 1, 2, 11, 22, 23];
87 87
88 88
    for exp, i in expected {
89 -
        if data[indices[i]] != exp {
89 +
        if data[indices[i]] <> exp {
90 90
            return i as i32 + 1;
91 91
        }
92 92
    }
93 93
    return 0;
94 94
}
117 117
    assert isSorted(&b[..]);
118 118
    assert sum(&b[..]) == origSum;
119 119
120 120
    // Both algorithms must produce the same result.
121 121
    let r = arraysEqual(&a[..], &b[..]);
122 -
    if r != 0 {
122 +
    if r <> 0 {
123 123
        return 10 + r;
124 124
    }
125 125
126 126
    // Verify specific sorted positions.
127 127
    let r2 = verifyPositions(&a[..]);
128 -
    if r2 != 0 {
128 +
    if r2 <> 0 {
129 129
        return 40 + r2;
130 130
    }
131 131
    return 0;
132 132
}
test/tests/prog.linkedlist.rad +7 -7
146 146
}
147 147
148 148
/// Test find.
149 149
fn testFind(list: *mut List) -> i32 {
150 150
    // 20 should be found.
151 -
    assert find(list, 20) != nil;
151 +
    assert find(list, 20) <> nil;
152 152
    // 10 should be found.
153 -
    assert find(list, 10) != nil;
153 +
    assert find(list, 10) <> nil;
154 154
    // 30 was popped, should not be found.
155 155
    assert find(list, 30) == nil;
156 156
    // 99 never inserted.
157 157
    assert find(list, 99) == nil;
158 158
    return 0;
248 248
        free: 0,
249 249
        head: nil,
250 250
    };
251 251
252 252
    let r1 = testPushLength(&mut list);
253 -
    if r1 != 0 {
253 +
    if r1 <> 0 {
254 254
        return 10 + r1;
255 255
    }
256 256
257 257
    let r2 = testPop(&mut list);
258 -
    if r2 != 0 {
258 +
    if r2 <> 0 {
259 259
        return 20 + r2;
260 260
    }
261 261
262 262
    let r3 = testFind(&mut list);
263 -
    if r3 != 0 {
263 +
    if r3 <> 0 {
264 264
        return 30 + r3;
265 265
    }
266 266
267 267
    let r4 = testReverse(&mut list);
268 -
    if r4 != 0 {
268 +
    if r4 <> 0 {
269 269
        return 40 + r4;
270 270
    }
271 271
272 272
    let r5 = testLargerList(&mut list);
273 -
    if r5 != 0 {
273 +
    if r5 <> 0 {
274 274
        return 50 + r5;
275 275
    }
276 276
    return 0;
277 277
}
test/tests/prog.lzw.rad +9 -9
79 79
    let mut i: u32 = 1;
80 80
81 81
    while i < data.len {
82 82
        let c: u8 = data[i];
83 83
        let wc: u32 = dictLookup(s, w, c);
84 -
        if wc != 0xFFFFFFFF {
84 +
        if wc <> 0xFFFFFFFF {
85 85
            w = wc;
86 86
        } else {
87 87
            emitCode(s, w);
88 88
            dictAdd(s, w, c);
89 89
            w = c as u32;
95 95
}
96 96
97 97
fn decodeString(s: *mut LzwState, code: u32) -> u32 {
98 98
    let mut len: u32 = 0;
99 99
    let mut c: u32 = code;
100 -
    while c != 0xFFFF and c < s.decDictSize {
100 +
    while c <> 0xFFFF and c < s.decDictSize {
101 101
        s.temp[len] = s.decDict[c].suffix;
102 102
        len += 1;
103 103
        c = s.decDict[c].prefix;
104 104
    }
105 105
    let mut a: u32 = 0;
114 114
    return len;
115 115
}
116 116
117 117
fn firstByte(s: *LzwState, code: u32) -> u8 {
118 118
    let mut c: u32 = code;
119 -
    while s.decDict[c].prefix != 0xFFFF and s.decDict[c].prefix < s.decDictSize {
119 +
    while s.decDict[c].prefix <> 0xFFFF and s.decDict[c].prefix < s.decDictSize {
120 120
        c = s.decDict[c].prefix;
121 121
    }
122 122
    return s.decDict[c].suffix;
123 123
}
124 124
285 285
        decLen: 0,
286 286
        temp: &mut temp[..],
287 287
    };
288 288
289 289
    let r1: i32 = testSimple(&mut s);
290 -
    if r1 != 0 { return 10 + r1; }
290 +
    if r1 <> 0 { return 10 + r1; }
291 291
292 292
    let r2: i32 = testDistinct(&mut s);
293 -
    if r2 != 0 { return 20 + r2; }
293 +
    if r2 <> 0 { return 20 + r2; }
294 294
295 295
    let r3: i32 = testRepetitive(&mut s);
296 -
    if r3 != 0 { return 30 + r3; }
296 +
    if r3 <> 0 { return 30 + r3; }
297 297
298 298
    let r4: i32 = testMixed(&mut s);
299 -
    if r4 != 0 { return 40 + r4; }
299 +
    if r4 <> 0 { return 40 + r4; }
300 300
301 301
    let r5: i32 = testEmpty(&mut s);
302 -
    if r5 != 0 { return 50 + r5; }
302 +
    if r5 <> 0 { return 50 + r5; }
303 303
304 304
    let r6: i32 = testSingle(&mut s);
305 -
    if r6 != 0 { return 60 + r6; }
305 +
    if r6 <> 0 { return 60 + r6; }
306 306
307 307
    return 0;
308 308
}
test/tests/prog.matmul.rad +3 -3
33 33
fn verifyResult(c: *Mat4, expected: *Mat4) -> i32 {
34 34
    let mut i: u32 = 0;
35 35
    while i < N {
36 36
        let mut j: u32 = 0;
37 37
        while j < N {
38 -
            if c.rows[i][j] != expected.rows[i][j] {
38 +
            if c.rows[i][j] <> expected.rows[i][j] {
39 39
                return (i * N + j) as i32 + 1;
40 40
            }
41 41
            j += 1;
42 42
        }
43 43
        i += 1;
110 110
111 111
    let mut c = Mat4 { rows: [[0; 4]; 4] };
112 112
    matmul(&mut c, &a, &b);
113 113
114 114
    let r1 = verifyResult(&c, &expected);
115 -
    if r1 != 0 {
115 +
    if r1 <> 0 {
116 116
        return 10 + r1;
117 117
    }
118 118
119 119
    let r2 = testRepeatedMultiply(&mut c, &a, &b);
120 -
    if r2 != 0 {
120 +
    if r2 <> 0 {
121 121
        return 30 + r2;
122 122
    }
123 123
    return 0;
124 124
}
test/tests/prog.mersenne.rad +13 -13
119 119
    mtInit(s, 42);
120 120
121 121
    i = 0;
122 122
    while i < 10 {
123 123
        let v: u32 = mtNext(s);
124 -
        if v != first[i] { return i as i32 + 1; }
124 +
        if v <> first[i] { return i as i32 + 1; }
125 125
        i += 1;
126 126
    }
127 127
128 128
    return 0;
129 129
}
136 136
    let b: u32 = mtNext(s);
137 137
138 138
    mtInit(s, 3);
139 139
    let c: u32 = mtNext(s);
140 140
141 -
    assert a != b;
142 -
    assert b != c;
143 -
    assert a != c;
141 +
    assert a <> b;
142 +
    assert b <> c;
143 +
    assert a <> c;
144 144
145 145
    return 0;
146 146
}
147 147
148 148
fn testChiSquared(s: *mut MtState) -> i32 {
174 174
175 175
    assert chi2Scaled <= 5000;
176 176
177 177
    b = 0;
178 178
    while b < NUM_BINS {
179 -
        assert bins[b] != 0;
179 +
        assert bins[b] <> 0;
180 180
        b += 1;
181 181
    }
182 182
183 183
    b = 0;
184 184
    while b < NUM_BINS {
213 213
    i = 0;
214 214
    while i < 700 {
215 215
        more = mtNext(s);
216 216
        i += 1;
217 217
    }
218 -
    assert more != 0;
218 +
    assert more <> 0;
219 219
220 220
    return 0;
221 221
}
222 222
223 223
fn testBitCoverage(s: *mut MtState) -> i32 {
233 233
        andAll &= v;
234 234
        i += 1;
235 235
    }
236 236
237 237
    assert orAll == 0xFFFFFFFF;
238 -
    assert andAll != 0xFFFFFFFF;
238 +
    assert andAll <> 0xFFFFFFFF;
239 239
    assert andAll == 0;
240 240
241 241
    return 0;
242 242
}
243 243
247 247
        mt: &mut mt[..],
248 248
        mti: 625,
249 249
    };
250 250
251 251
    let r1: i32 = testKnownSequence(&mut s);
252 -
    if r1 != 0 { return 10 + r1; }
252 +
    if r1 <> 0 { return 10 + r1; }
253 253
254 254
    let r2: i32 = testDeterminism(&mut s);
255 -
    if r2 != 0 { return 20 + r2; }
255 +
    if r2 <> 0 { return 20 + r2; }
256 256
257 257
    let r3: i32 = testDifferentSeeds(&mut s);
258 -
    if r3 != 0 { return 30 + r3; }
258 +
    if r3 <> 0 { return 30 + r3; }
259 259
260 260
    let r4: i32 = testChiSquared(&mut s);
261 -
    if r4 != 0 { return 40 + r4; }
261 +
    if r4 <> 0 { return 40 + r4; }
262 262
263 263
    let r5: i32 = testRegeneration(&mut s);
264 -
    if r5 != 0 { return 50 + r5; }
264 +
    if r5 <> 0 { return 50 + r5; }
265 265
266 266
    let r6: i32 = testBitCoverage(&mut s);
267 -
    if r6 != 0 { return 60 + r6; }
267 +
    if r6 <> 0 { return 60 + r6; }
268 268
269 269
    return 0;
270 270
}
test/tests/prog.nqueens.rad +8 -8
63 63
fn testAllSizes(b: *mut Board) -> i32 {
64 64
    let expected: [u32; 9] = [0, 1, 0, 0, 2, 10, 4, 40, 92];
65 65
    let mut n: u32 = 1;
66 66
    while n <= 8 {
67 67
        let count: u32 = solveNQueens(b, n);
68 -
        if count != expected[n] {
68 +
        if count <> expected[n] {
69 69
            return n as i32;
70 70
        }
71 71
        n += 1;
72 72
    }
73 73
    return 0;
78 78
79 79
    let mut i: u32 = 0;
80 80
    while i < 8 {
81 81
        let mut j: u32 = i + 1;
82 82
        while j < 8 {
83 -
            assert solution[i] != solution[j];
83 +
            assert solution[i] <> solution[j];
84 84
            let rowDiff: i32 = j as i32 - i as i32;
85 85
            let colDiff: i32 = solution[j] - solution[i];
86 -
            assert colDiff != rowDiff and colDiff != 0 - rowDiff;
86 +
            assert colDiff <> rowDiff and colDiff <> 0 - rowDiff;
87 87
            j += 1;
88 88
        }
89 89
        i += 1;
90 90
    }
91 91
117 117
fn testProperties() -> i32 {
118 118
    let expected: [u32; 9] = [0, 1, 0, 0, 2, 10, 4, 40, 92];
119 119
120 120
    let mut n: u32 = 4;
121 121
    while n <= 8 {
122 -
        assert expected[n] != 0;
122 +
        assert expected[n] <> 0;
123 123
        n += 1;
124 124
    }
125 125
126 126
    assert expected[2] == 0;
127 127
    assert expected[3] == 0;
138 138
        solutionCount: 0,
139 139
        boardSize: 0,
140 140
    };
141 141
142 142
    let r1: i32 = testAllSizes(&mut b);
143 -
    if r1 != 0 { return 10 + r1; }
143 +
    if r1 <> 0 { return 10 + r1; }
144 144
145 145
    let r2: i32 = testKnownSolution();
146 -
    if r2 != 0 { return 20 + r2; }
146 +
    if r2 <> 0 { return 20 + r2; }
147 147
148 148
    let r3: i32 = testDeterminism(&mut b);
149 -
    if r3 != 0 { return 30 + r3; }
149 +
    if r3 <> 0 { return 30 + r3; }
150 150
151 151
    let r4: i32 = testProperties();
152 -
    if r4 != 0 { return 40 + r4; }
152 +
    if r4 <> 0 { return 40 + r4; }
153 153
154 154
    return 0;
155 155
}
test/tests/prog.rbtree.rad +12 -12
32 32
}
33 33
34 34
fn rotateLeft(t: *mut RBTree, x: u32) {
35 35
    let y: u32 = t.pool[x].right;
36 36
    t.pool[x].right = t.pool[y].left;
37 -
    if t.pool[y].left != NIL {
37 +
    if t.pool[y].left <> NIL {
38 38
        t.pool[t.pool[y].left].parent = x;
39 39
    }
40 40
    t.pool[y].parent = t.pool[x].parent;
41 41
    if t.pool[x].parent == NIL {
42 42
        t.root = y;
50 50
}
51 51
52 52
fn rotateRight(t: *mut RBTree, x: u32) {
53 53
    let y: u32 = t.pool[x].left;
54 54
    t.pool[x].left = t.pool[y].right;
55 -
    if t.pool[y].right != NIL {
55 +
    if t.pool[y].right <> NIL {
56 56
        t.pool[t.pool[y].right].parent = x;
57 57
    }
58 58
    t.pool[y].parent = t.pool[x].parent;
59 59
    if t.pool[x].parent == NIL {
60 60
        t.root = y;
110 110
fn insert(t: *mut RBTree, key: i32) {
111 111
    let z: u32 = allocNode(t, key);
112 112
    let mut y: u32 = NIL;
113 113
    let mut x: u32 = t.root;
114 114
115 -
    while x != NIL {
115 +
    while x <> NIL {
116 116
        y = x;
117 117
        if key < t.pool[x].key {
118 118
            x = t.pool[x].left;
119 119
        } else {
120 120
            x = t.pool[x].right;
133 133
    insertFixup(t, z);
134 134
}
135 135
136 136
fn search(t: *RBTree, key: i32) -> bool {
137 137
    let mut x: u32 = t.root;
138 -
    while x != NIL {
138 +
    while x <> NIL {
139 139
        if key == t.pool[x].key {
140 140
            return true;
141 141
        } else if key < t.pool[x].key {
142 142
            x = t.pool[x].left;
143 143
        } else {
172 172
    let rightBH: i32 = blackHeight(t, t.pool[x].right);
173 173
174 174
    if leftBH == -1 or rightBH == -1 {
175 175
        return -1;
176 176
    }
177 -
    if leftBH != rightBH {
177 +
    if leftBH <> rightBH {
178 178
        return -1;
179 179
    }
180 180
181 181
    if t.pool[x].color == BLACK {
182 182
        return leftBH + 1;
224 224
225 225
    assert countNodes(t, t.root) == 32;
226 226
    assert t.pool[t.root].color == BLACK;
227 227
228 228
    let bh: i32 = blackHeight(t, t.root);
229 -
    assert bh != -1;
229 +
    assert bh <> -1;
230 230
231 231
    assert noRedRed(t, t.root);
232 232
233 233
    t.inorderCount = 0;
234 234
    inorderWalk(t, t.root);
253 253
        }
254 254
        i -= 1;
255 255
    }
256 256
257 257
    assert countNodes(t, t.root) == 32;
258 -
    assert blackHeight(t, t.root) != -1;
258 +
    assert blackHeight(t, t.root) <> -1;
259 259
    assert noRedRed(t, t.root);
260 260
261 261
    t.inorderCount = 0;
262 262
    inorderWalk(t, t.root);
263 263
    let mut j: u32 = 0;
285 285
            count += 1;
286 286
        }
287 287
    }
288 288
289 289
    assert countNodes(t, t.root) == 48;
290 -
    assert blackHeight(t, t.root) != -1;
290 +
    assert blackHeight(t, t.root) <> -1;
291 291
    assert noRedRed(t, t.root);
292 292
293 293
    let mut i: i32 = 0;
294 294
    while i < 48 {
295 295
        assert search(t, i);
339 339
        inorder: &mut inorder[..],
340 340
        inorderCount: 0,
341 341
    };
342 342
343 343
    let r1: i32 = testAscending(&mut t);
344 -
    if r1 != 0 { return 10 + r1; }
344 +
    if r1 <> 0 { return 10 + r1; }
345 345
346 346
    let r2: i32 = testDescending(&mut t);
347 -
    if r2 != 0 { return 20 + r2; }
347 +
    if r2 <> 0 { return 20 + r2; }
348 348
349 349
    let r3: i32 = testRandom(&mut t);
350 -
    if r3 != 0 { return 30 + r3; }
350 +
    if r3 <> 0 { return 30 + r3; }
351 351
352 352
    let r4: i32 = testHeight(&mut t);
353 -
    if r4 != 0 { return 50 + r4; }
353 +
    if r4 <> 0 { return 50 + r4; }
354 354
355 355
    return 0;
356 356
}
test/tests/prog.regex.rad +9 -9
100 100
        changed = false;
101 101
        let mut s: u32 = 0;
102 102
        while s < nfa.stateCount {
103 103
            if setHas(nfa.closure, s) {
104 104
                let mut t: u32 = nfa.stateFirst[s];
105 -
                while t != NIL {
105 +
                while t <> NIL {
106 106
                    if nfa.trans[t].kind == TRANS_EPSILON {
107 107
                        if not setHas(nfa.closure, nfa.trans[t].to) {
108 108
                            setAdd(nfa.closure, nfa.trans[t].to);
109 109
                            changed = true;
110 110
                        }
247 247
248 248
        let mut s: u32 = 0;
249 249
        while s < nfa.stateCount {
250 250
            if setHas(nfa.current, s) {
251 251
                let mut t: u32 = nfa.stateFirst[s];
252 -
                while t != NIL {
252 +
                while t <> NIL {
253 253
                    if nfa.trans[t].kind == TRANS_CHAR and nfa.trans[t].ch == ch {
254 254
                        setAdd(nfa.nextSet, nfa.trans[t].to);
255 255
                    } else if nfa.trans[t].kind == TRANS_DOT {
256 256
                        setAdd(nfa.nextSet, nfa.trans[t].to);
257 257
                    }
371 371
        fragStack: &mut fragStack[..],
372 372
        fragTop: 0,
373 373
    };
374 374
375 375
    let r1: i32 = testLiteral(&mut nfa);
376 -
    if r1 != 0 { return 10 + r1; }
376 +
    if r1 <> 0 { return 10 + r1; }
377 377
378 378
    let r2: i32 = testStar(&mut nfa);
379 -
    if r2 != 0 { return 20 + r2; }
379 +
    if r2 <> 0 { return 20 + r2; }
380 380
381 381
    let r3: i32 = testPlus(&mut nfa);
382 -
    if r3 != 0 { return 30 + r3; }
382 +
    if r3 <> 0 { return 30 + r3; }
383 383
384 384
    let r4: i32 = testQuestion(&mut nfa);
385 -
    if r4 != 0 { return 40 + r4; }
385 +
    if r4 <> 0 { return 40 + r4; }
386 386
387 387
    let r5: i32 = testDot(&mut nfa);
388 -
    if r5 != 0 { return 50 + r5; }
388 +
    if r5 <> 0 { return 50 + r5; }
389 389
390 390
    let r6: i32 = testComplex(&mut nfa);
391 -
    if r6 != 0 { return 60 + r6; }
391 +
    if r6 <> 0 { return 60 + r6; }
392 392
393 393
    let r7: i32 = testDotStar(&mut nfa);
394 -
    if r7 != 0 { return 70 + r7; }
394 +
    if r7 <> 0 { return 70 + r7; }
395 395
396 396
    return 0;
397 397
}
test/tests/prog.sha256.rad +3 -3
233 233
    ];
234 234
235 235
    let mut s: Sha256 = Sha256 { h: INIT_H, w: [0; 64] };
236 236
237 237
    let r1 = testHelpers();
238 -
    if r1 != 0 {
238 +
    if r1 <> 0 {
239 239
        return 10 + r1;
240 240
    }
241 241
242 242
    let r2 = testEmpty(&mut s, &k[..]);
243 -
    if r2 != 0 {
243 +
    if r2 <> 0 {
244 244
        return 20 + r2;
245 245
    }
246 246
247 247
    let r3 = testAbc(&mut s, &k[..]);
248 -
    if r3 != 0 {
248 +
    if r3 <> 0 {
249 249
        return 30 + r3;
250 250
    }
251 251
    return 0;
252 252
}
test/tests/prog.sieve.rad +2 -2
106 106
@default fn main() -> i32 {
107 107
    let mut sieve: [bool; 256] = [false; 256];
108 108
    runSieve(&mut sieve[..]);
109 109
110 110
    let r1 = verifyKnownPrimes(&sieve[..]);
111 -
    if r1 != 0 {
111 +
    if r1 <> 0 {
112 112
        return 10 + r1;
113 113
    }
114 114
115 115
    // There are 54 primes <= 255 (2, 3, 5, ..., 251).
116 116
    assert countPrimes(&sieve[..]) == 54;
117 117
118 118
    let r3 = verifyCollected(&sieve[..]);
119 -
    if r3 != 0 {
119 +
    if r3 <> 0 {
120 120
        return 40 + r3;
121 121
    }
122 122
    return 0;
123 123
}
test/tests/prog.symtab.rad +13 -13
80 80
81 81
        // Remove from hash chain.
82 82
        tab.buckets[bucket] = sym.next;
83 83
84 84
        // Restore shadowed symbol if any.
85 -
        if sym.shadow != NIL {
85 +
        if sym.shadow <> NIL {
86 86
            // The shadowed symbol is still in the symbols array;
87 87
            // re-link it into the hash chain.
88 88
            let shadowIdx = sym.shadow;
89 89
            tab.symbols[shadowIdx].next = tab.buckets[bucket];
90 90
            tab.buckets[bucket] = shadowIdx;
98 98
    let bucket = h % HASH_SIZE;
99 99
100 100
    // Check for shadowed symbol with same name.
101 101
    let mut shadowIdx: u32 = NIL;
102 102
    let mut cur = tab.buckets[bucket];
103 -
    while cur != NIL {
103 +
    while cur <> NIL {
104 104
        if tab.symbols[cur].nameHash == h {
105 105
            // Found existing symbol with same hash - shadow it.
106 106
            // Remove it from hash chain first.
107 107
            shadowIdx = cur;
108 108
            // Remove the shadowed symbol from the bucket chain.
131 131
fn lookup(tab: *SymTab, name: *[u8]) -> ?i32 {
132 132
    let h = hashName(name);
133 133
    let bucket = h % HASH_SIZE;
134 134
    let mut cur = tab.buckets[bucket];
135 135
136 -
    while cur != NIL {
136 +
    while cur <> NIL {
137 137
        if tab.symbols[cur].nameHash == h {
138 138
            return tab.symbols[cur].value;
139 139
        }
140 140
        cur = tab.symbols[cur].next;
141 141
    }
146 146
fn update(tab: *mut SymTab, name: *[u8], newValue: i32) -> bool {
147 147
    let h = hashName(name);
148 148
    let bucket = h % HASH_SIZE;
149 149
    let mut cur = tab.buckets[bucket];
150 150
151 -
    while cur != NIL {
151 +
    while cur <> NIL {
152 152
        if tab.symbols[cur].nameHash == h {
153 153
            tab.symbols[cur].value = newValue;
154 154
            return true;
155 155
        }
156 156
        cur = tab.symbols[cur].next;
377 377
    for name, i in queries {
378 378
        let result = lookup(tab, name);
379 379
        if let exp = expected[i] {
380 380
            // We expect a value.
381 381
            if let r = result {
382 -
                if r != exp {
382 +
                if r <> exp {
383 383
                    failures += 1;
384 384
                }
385 385
            } else {
386 386
                failures += 1;
387 387
            }
391 391
                failures += 1;
392 392
            }
393 393
        }
394 394
    }
395 395
396 -
    if failures != 0 {
396 +
    if failures <> 0 {
397 397
        return failures as i32;
398 398
    }
399 399
400 400
    popScope(tab);
401 401
    popScope(tab);
414 414
        scopeDepth: 0,
415 415
        buckets: &mut buckets[..],
416 416
    };
417 417
418 418
    let r1 = testBasic(&mut tab);
419 -
    if r1 != 0 {
419 +
    if r1 <> 0 {
420 420
        return 10 + r1;
421 421
    }
422 422
423 423
    let r2 = testShadowing(&mut tab);
424 -
    if r2 != 0 {
424 +
    if r2 <> 0 {
425 425
        return 20 + r2;
426 426
    }
427 427
428 428
    let r3 = testDeepNesting(&mut tab);
429 -
    if r3 != 0 {
429 +
    if r3 <> 0 {
430 430
        return 30 + r3;
431 431
    }
432 432
433 433
    let r4 = testMultipleSymbols(&mut tab);
434 -
    if r4 != 0 {
434 +
    if r4 <> 0 {
435 435
        return 40 + r4;
436 436
    }
437 437
438 438
    let r5 = testUpdate(&mut tab);
439 -
    if r5 != 0 {
439 +
    if r5 <> 0 {
440 440
        return 50 + r5;
441 441
    }
442 442
443 443
    let r6 = testScopeIsolation(&mut tab);
444 -
    if r6 != 0 {
444 +
    if r6 <> 0 {
445 445
        return 60 + r6;
446 446
    }
447 447
448 448
    let r7 = testInterleaved(&mut tab);
449 -
    if r7 != 0 {
449 +
    if r7 <> 0 {
450 450
        return 70 + r7;
451 451
    }
452 452
453 453
    return 0;
454 454
}
test/tests/prog.tokenizer.rad +11 -11
503 503
@default fn main() -> i32 {
504 504
    let mut tokenBuf: [Token; 128] = [Token::Eof; 128];
505 505
    let mut exprBuf: [Expr; 128] = [Expr::Num(0); 128];
506 506
507 507
    let r1 = testNumber(&mut tokenBuf[..], &mut exprBuf[..]);
508 -
    if r1 != 0 {
508 +
    if r1 <> 0 {
509 509
        return 10 + r1;
510 510
    }
511 511
512 512
    let r2 = testAdd(&mut tokenBuf[..], &mut exprBuf[..]);
513 -
    if r2 != 0 {
513 +
    if r2 <> 0 {
514 514
        return 20 + r2;
515 515
    }
516 516
517 517
    let r3 = testPrecedence(&mut tokenBuf[..], &mut exprBuf[..]);
518 -
    if r3 != 0 {
518 +
    if r3 <> 0 {
519 519
        return 30 + r3;
520 520
    }
521 521
522 522
    let r4 = testParens(&mut tokenBuf[..], &mut exprBuf[..]);
523 -
    if r4 != 0 {
523 +
    if r4 <> 0 {
524 524
        return 40 + r4;
525 525
    }
526 526
527 527
    let r5 = testNeg(&mut tokenBuf[..], &mut exprBuf[..]);
528 -
    if r5 != 0 {
528 +
    if r5 <> 0 {
529 529
        return 50 + r5;
530 530
    }
531 531
532 532
    let r6 = testComplex(&mut tokenBuf[..], &mut exprBuf[..]);
533 -
    if r6 != 0 {
533 +
    if r6 <> 0 {
534 534
        return 60 + r6;
535 535
    }
536 536
537 537
    let r7 = testChained(&mut tokenBuf[..], &mut exprBuf[..]);
538 -
    if r7 != 0 {
538 +
    if r7 <> 0 {
539 539
        return 70 + r7;
540 540
    }
541 541
542 542
    let r8 = testTokenCount(&mut tokenBuf[..], &mut exprBuf[..]);
543 -
    if r8 != 0 {
543 +
    if r8 <> 0 {
544 544
        return 80 + r8;
545 545
    }
546 546
547 547
    let r9 = testDivision(&mut tokenBuf[..], &mut exprBuf[..]);
548 -
    if r9 != 0 {
548 +
    if r9 <> 0 {
549 549
        return 90 + r9;
550 550
    }
551 551
552 552
    let r10 = testDeepNesting(&mut tokenBuf[..], &mut exprBuf[..]);
553 -
    if r10 != 0 {
553 +
    if r10 <> 0 {
554 554
        return 100 + r10;
555 555
    }
556 556
557 557
    let r11 = testNodeCount(&mut tokenBuf[..], &mut exprBuf[..]);
558 -
    if r11 != 0 {
558 +
    if r11 <> 0 {
559 559
        return 110 + r11;
560 560
    }
561 561
562 562
    return 0;
563 563
}
test/tests/prog.vm.rad +13 -13
516 516
    let mut stackBuf: [i32; 64] = [0; 64];
517 517
    let mut localsBuf: [i32; 128] = [0; 128];
518 518
    let mut framesBuf: [Frame; 8] = [Frame { returnAddr: 0, localBase: 0 }; 8];
519 519
520 520
    let r1 = testArith(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
521 -
    if r1 != 0 {
521 +
    if r1 <> 0 {
522 522
        return 10 + r1;
523 523
    }
524 524
525 525
    let r2 = testLocals(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
526 -
    if r2 != 0 {
526 +
    if r2 <> 0 {
527 527
        return 20 + r2;
528 528
    }
529 529
530 530
    let r3 = testConditional(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
531 -
    if r3 != 0 {
531 +
    if r3 <> 0 {
532 532
        return 30 + r3;
533 533
    }
534 534
535 535
    let r4 = testLoop(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
536 -
    if r4 != 0 {
536 +
    if r4 <> 0 {
537 537
        return 40 + r4;
538 538
    }
539 539
540 540
    let r5 = testCall(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
541 -
    if r5 != 0 {
541 +
    if r5 <> 0 {
542 542
        return 50 + r5;
543 543
    }
544 544
545 545
    let r6 = testDivByZero(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
546 -
    if r6 != 0 {
546 +
    if r6 <> 0 {
547 547
        return 60 + r6;
548 548
    }
549 549
550 550
    let r7 = testNegAndEq(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
551 -
    if r7 != 0 {
551 +
    if r7 <> 0 {
552 552
        return 70 + r7;
553 553
    }
554 554
555 555
    let r8 = testFactorial(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
556 -
    if r8 != 0 {
556 +
    if r8 <> 0 {
557 557
        return 80 + r8;
558 558
    }
559 559
560 560
    let r9 = testDup(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
561 -
    if r9 != 0 {
561 +
    if r9 <> 0 {
562 562
        return 90 + r9;
563 563
    }
564 564
565 565
    let r10 = testStackUnderflow(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
566 -
    if r10 != 0 {
566 +
    if r10 <> 0 {
567 567
        return 100 + r10;
568 568
    }
569 569
570 570
    let r11 = testSuccessNoCatch(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
571 -
    if r11 != 0 {
571 +
    if r11 <> 0 {
572 572
        return 110 + r11;
573 573
    }
574 574
575 575
    let r12 = testCallOverflow(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
576 -
    if r12 != 0 {
576 +
    if r12 <> 0 {
577 577
        return 120 + r12;
578 578
    }
579 579
580 580
    let r13 = testCatchNoBinding(&mut stackBuf[..], &mut localsBuf[..], &mut framesBuf[..]);
581 -
    if r13 != 0 {
581 +
    if r13 <> 0 {
582 582
        return 130 + r13;
583 583
    }
584 584
585 585
    return 0;
586 586
}
test/tests/range.arithmetic.rad +10 -10
4 4
    let arr: [i32; 6] = [10, 20, 30, 40, 50, 60];
5 5
    let len: u32 = 6;
6 6
7 7
    // Arithmetic in range start (no parens needed).
8 8
    let s = &arr[len - 3..len];
9 -
    if s.len != 3 { return 1; }
10 -
    if s[0] != 40 { return 2; }
11 -
    if s[2] != 60 { return 3; }
9 +
    if s.len <> 3 { return 1; }
10 +
    if s[0] <> 40 { return 2; }
11 +
    if s[2] <> 60 { return 3; }
12 12
13 13
    // Arithmetic in range end.
14 14
    let s2 = &arr[0..len - 2];
15 -
    if s2.len != 4 { return 4; }
16 -
    if s2[3] != 40 { return 5; }
15 +
    if s2.len <> 4 { return 4; }
16 +
    if s2[3] <> 40 { return 5; }
17 17
18 18
    // Arithmetic in both.
19 19
    let s3 = &arr[len - 4..len - 1];
20 -
    if s3.len != 3 { return 6; }
21 -
    if s3[0] != 30 { return 7; }
22 -
    if s3[2] != 50 { return 8; }
20 +
    if s3.len <> 3 { return 6; }
21 +
    if s3[0] <> 30 { return 7; }
22 +
    if s3[2] <> 50 { return 8; }
23 23
24 24
    // Arithmetic in subscript.
25 -
    if arr[len - 1] != 60 { return 9; }
26 -
    if arr[len - 6] != 10 { return 10; }
25 +
    if arr[len - 1] <> 60 { return 9; }
26 +
    if arr[len - 6] <> 10 { return 10; }
27 27
28 28
    return 0;
29 29
}
test/tests/record.copy.rad +5 -5
94 94
95 95
@default fn main() -> i32 {
96 96
    let s: S = S { x: 561, y: 938, z: 102 };
97 97
98 98
    let r1: i32 = func1(s);
99 -
    if r1 != 0 {
99 +
    if r1 <> 0 {
100 100
        return 10 + r1;
101 101
    }
102 102
    assert s.x == 561;
103 103
    assert s.y == 938;
104 104
    assert s.z == 102;
105 105
106 106
    let r2: i32 = func2(s);
107 -
    if r2 != 0 {
107 +
    if r2 <> 0 {
108 108
        return 30 + r2;
109 109
    }
110 110
111 111
    let r3: i32 = func3(s);
112 -
    if r3 != 0 {
112 +
    if r3 <> 0 {
113 113
        return 40 + r3;
114 114
    }
115 115
116 116
    let r4: i32 = func4(s);
117 -
    if r4 != 0 {
117 +
    if r4 <> 0 {
118 118
        return 50 + r4;
119 119
    }
120 120
121 121
    let r5: i32 = func5(s);
122 -
    if r5 != 0 {
122 +
    if r5 <> 0 {
123 123
        return 60 + r5;
124 124
    }
125 125
126 126
    return 0;
127 127
}
test/tests/record.empty.eq.rad +1 -1
5 5
fn emptyEq(a: Empty, b: Empty) -> bool {
6 6
    return a == b;
7 7
}
8 8
9 9
fn emptyNeq(a: Empty, b: Empty) -> bool {
10 -
    return a != b;
10 +
    return a <> b;
11 11
}
12 12
13 13
fn emptyAlwaysEqual() -> bool {
14 14
    let a = Empty {};
15 15
    let b = Empty {};
test/tests/record.unlabeled.deref.rad +10 -10
16 16
17 17
@default fn main() -> i32 {
18 18
    let w: Wrap = Wrap(42);
19 19
20 20
    // Basic deref.
21 -
    if *w != 42 {
21 +
    if *w <> 42 {
22 22
        return 1;
23 23
    }
24 24
25 25
    // Deref in function call.
26 -
    if getInner(w) != 42 {
26 +
    if getInner(w) <> 42 {
27 27
        return 2;
28 28
    }
29 29
30 30
    // Deref bool.
31 31
    let b: WrapBool = WrapBool(true);
32 -
    if *b != true {
32 +
    if *b <> true {
33 33
        return 3;
34 34
    }
35 35
36 36
    // Deref u8.
37 37
    let u: WrapU8 = WrapU8(7);
38 -
    if *u != 7 {
38 +
    if *u <> 7 {
39 39
        return 4;
40 40
    }
41 41
42 42
    // Deref in arithmetic.
43 43
    let a: Wrap = Wrap(10);
44 44
    let b2: Wrap = Wrap(20);
45 -
    if *a + *b2 != 30 {
45 +
    if *a + *b2 <> 30 {
46 46
        return 5;
47 47
    }
48 48
49 49
    // Deref and reconstruct.
50 50
    let w2: Wrap = passThrough(w);
51 -
    if *w2 != 42 {
51 +
    if *w2 <> 42 {
52 52
        return 6;
53 53
    }
54 54
55 55
    // Deref u64.
56 56
    let big: WrapU64 = WrapU64(1234567890);
57 -
    if *big != 1234567890 {
57 +
    if *big <> 1234567890 {
58 58
        return 7;
59 59
    }
60 60
61 61
    // Deref in comparison.
62 62
    let x: Wrap = Wrap(5);
63 63
    let y: Wrap = Wrap(5);
64 -
    if *x != *y {
64 +
    if *x <> *y {
65 65
        return 8;
66 66
    }
67 67
68 68
    // Deref in let binding.
69 69
    let val: i32 = *Wrap(99);
70 -
    if val != 99 {
70 +
    if val <> 99 {
71 71
        return 9;
72 72
    }
73 73
74 74
    // Assignment through deref on mutable binding.
75 75
    let mut m: Wrap = Wrap(0);
76 76
    *m = 77;
77 -
    if *m != 77 {
77 +
    if *m <> 77 {
78 78
        return 10;
79 79
    }
80 80
81 81
    return 0;
82 82
}
test/tests/record.unlabeled.rad +2 -2
17 17
    let r1: R = R(true, 43);
18 18
19 19
    let s2: S = passS(s1);
20 20
    let r2: R = passR(r1);
21 21
22 -
    if s2 != S(42) {
22 +
    if s2 <> S(42) {
23 23
        return 0;
24 24
    }
25 -
    if r2 != R(true, 43) {
25 +
    if r2 <> R(true, 43) {
26 26
        return 0;
27 27
    }
28 28
    return 1;
29 29
}
test/tests/regalloc.spill.reuse.rad +1 -1
7 7
    let saved: u32 = old + 1;
8 8
9 9
    let first: u32 = callPressure(1, 2, 3, 4, 5, 6, 7, 8);
10 10
    let second: u32 = callPressure(8, 7, 6, 5, 4, 3, 2, 1);
11 11
12 -
    assert first != 0 and second != 0;
12 +
    assert first <> 0 and second <> 0;
13 13
14 14
    return saved;
15 15
}
16 16
17 17
@default fn main() -> i32 {
test/tests/result.void.success.rad +2 -2
21 21
    try voidSuccess() catch {
22 22
        return (1) - 42;
23 23
    };
24 24
25 25
    // Guard should still be 42, not clobbered.
26 -
    if guard != 42 {
26 +
    if guard <> 42 {
27 27
        return (2) - 42;
28 28
    }
29 29
30 30
    // Try the error path too.
31 31
    try voidError() catch {
32 32
        guard = 99;
33 33
    };
34 34
35 -
    if guard != 99 {
35 +
    if guard <> 99 {
36 36
        return (3) - 42;
37 37
    }
38 38
39 39
    return (42) - 42;
40 40
}
test/tests/slice.append.rad +24 -24
54 54
    // Append within capacity.
55 55
    nums.append(10, a);
56 56
    nums.append(20, a);
57 57
    nums.append(30, a);
58 58
59 -
    if nums.len != 3 {
59 +
    if nums.len <> 3 {
60 60
        return 1;
61 61
    }
62 -
    if nums.cap != 4 {
62 +
    if nums.cap <> 4 {
63 63
        return 2;
64 64
    }
65 -
    if nums[0] != 10 {
65 +
    if nums[0] <> 10 {
66 66
        return 3;
67 67
    }
68 -
    if nums[1] != 20 {
68 +
    if nums[1] <> 20 {
69 69
        return 4;
70 70
    }
71 -
    if nums[2] != 30 {
71 +
    if nums[2] <> 30 {
72 72
        return 5;
73 73
    }
74 74
75 75
    // Append to fill capacity.
76 76
    nums.append(40, a);
77 77
78 -
    if nums.len != 4 {
78 +
    if nums.len <> 4 {
79 79
        return 6;
80 80
    }
81 -
    if nums.cap != 4 {
81 +
    if nums.cap <> 4 {
82 82
        return 7;
83 83
    }
84 84
85 85
    // Append past capacity -- triggers growth.
86 86
    nums.append(50, a);
87 87
88 -
    if nums.len != 5 {
88 +
    if nums.len <> 5 {
89 89
        return 8;
90 90
    }
91 91
    // Cap should have grown (cap * 2 | 1 = 4 * 2 | 1 = 9).
92 -
    if nums.cap != 9 {
92 +
    if nums.cap <> 9 {
93 93
        return 9;
94 94
    }
95 -
    if nums[4] != 50 {
95 +
    if nums[4] <> 50 {
96 96
        return 10;
97 97
    }
98 98
99 99
    // Verify old elements survived the copy.
100 -
    if nums[0] != 10 {
100 +
    if nums[0] <> 10 {
101 101
        return 11;
102 102
    }
103 -
    if nums[3] != 40 {
103 +
    if nums[3] <> 40 {
104 104
        return 12;
105 105
    }
106 106
107 107
    // Append from empty (cap == 0 triggers growth with cap = 1).
108 108
    let mut empty = @sliceOf(ptr as *mut i32, 0, 0);
109 109
    empty.append(99, a);
110 110
111 -
    if empty.len != 1 {
111 +
    if empty.len <> 1 {
112 112
        return 13;
113 113
    }
114 -
    if empty.cap != 1 {
114 +
    if empty.cap <> 1 {
115 115
        return 14;
116 116
    }
117 -
    if empty[0] != 99 {
117 +
    if empty[0] <> 99 {
118 118
        return 15;
119 119
    }
120 120
121 121
    // Sum all elements in nums.
122 122
    let mut sum: i32 = 0;
123 123
    for n in nums {
124 124
        sum += n;
125 125
    }
126 -
    if sum != 150 {
126 +
    if sum <> 150 {
127 127
        return 16;
128 128
    }
129 129
130 130
    // Test append with u8 elements (stride = 1).
131 131
    let bytePtr = arenaAlloc(&mut arena, 2, 1);
132 132
    let mut bytes = @sliceOf(bytePtr as *mut u8, 0, 2);
133 133
    bytes.append(0xAB, a);
134 134
    bytes.append(0xCD, a);
135 135
136 -
    if bytes.len != 2 {
136 +
    if bytes.len <> 2 {
137 137
        return 17;
138 138
    }
139 -
    if bytes[0] != 0xAB {
139 +
    if bytes[0] <> 0xAB {
140 140
        return 18;
141 141
    }
142 -
    if bytes[1] != 0xCD {
142 +
    if bytes[1] <> 0xCD {
143 143
        return 19;
144 144
    }
145 145
146 146
    // Trigger growth on u8 slice.
147 147
    bytes.append(0xEF, a);
148 148
149 -
    if bytes.len != 3 {
149 +
    if bytes.len <> 3 {
150 150
        return 20;
151 151
    }
152 -
    if bytes.cap != 5 {
152 +
    if bytes.cap <> 5 {
153 153
        return 21;
154 154
    }
155 -
    if bytes[2] != 0xEF {
155 +
    if bytes[2] <> 0xEF {
156 156
        return 22;
157 157
    }
158 158
    // Verify old u8 elements survived.
159 -
    if bytes[0] != 0xAB {
159 +
    if bytes[0] <> 0xAB {
160 160
        return 23;
161 161
    }
162 162
163 163
    // Test that .append() returns the slice, allowing rebinding.
164 164
    let ptr2 = arenaAlloc(&mut arena, @sizeOf(i32) * 2, @alignOf(i32));
178 178
    assert vals.len == 3;
179 179
    assert vals.cap == 5;
180 180
181 181
    // After growth, the data pointer should have changed.
182 182
    let newPtr = &vals[0] as *opaque;
183 -
    assert oldPtr != newPtr;
183 +
    assert oldPtr <> newPtr;
184 184
185 185
    // Verify all elements survived.
186 186
    assert vals[0] == 42;
187 187
    assert vals[1] == 43;
188 188
    assert vals[2] == 44;
test/tests/slice.cap.rad +10 -10
4 4
@default fn main() -> i32 {
5 5
    // Test that regular slices have cap == len.
6 6
    let mut arr: [i32; 4] = [10, 20, 30, 40];
7 7
    let s = &mut arr[..];
8 8
9 -
    if s.cap != 4 {
9 +
    if s.cap <> 4 {
10 10
        return 1;
11 11
    }
12 -
    if s.len != s.cap {
12 +
    if s.len <> s.cap {
13 13
        return 2;
14 14
    }
15 15
16 16
    // Test @sliceOf with explicit capacity.
17 17
    let ptr = &mut arr[0];
18 18
    let s2 = @sliceOf(ptr, 2, 4);
19 19
20 -
    if s2.len != 2 {
20 +
    if s2.len <> 2 {
21 21
        return 3;
22 22
    }
23 -
    if s2.cap != 4 {
23 +
    if s2.cap <> 4 {
24 24
        return 4;
25 25
    }
26 -
    if s2[0] != 10 {
26 +
    if s2[0] <> 10 {
27 27
        return 5;
28 28
    }
29 -
    if s2[1] != 20 {
29 +
    if s2[1] <> 20 {
30 30
        return 6;
31 31
    }
32 32
33 33
    // Test @sliceOf with zero length.
34 34
    let s3 = @sliceOf(ptr, 0, 4);
35 35
36 -
    if s3.len != 0 {
36 +
    if s3.len <> 0 {
37 37
        return 7;
38 38
    }
39 -
    if s3.cap != 4 {
39 +
    if s3.cap <> 4 {
40 40
        return 8;
41 41
    }
42 42
43 43
    // Test @sliceOf still works and has cap == len.
44 44
    let s4 = @sliceOf(ptr, 3);
45 45
46 -
    if s4.len != 3 {
46 +
    if s4.len <> 3 {
47 47
        return 9;
48 48
    }
49 -
    if s4.cap != 3 {
49 +
    if s4.cap <> 3 {
50 50
        return 10;
51 51
    }
52 52
    return 0;
53 53
}
test/tests/slice.delete.rad +13 -13
6 6
    let mut s = &mut arr[..];
7 7
8 8
    // Delete middle element (index 2: value 30).
9 9
    s.delete(2);
10 10
11 -
    if s.len != 4 {
11 +
    if s.len <> 4 {
12 12
        return 1;
13 13
    }
14 -
    if s[0] != 10 {
14 +
    if s[0] <> 10 {
15 15
        return 2;
16 16
    }
17 -
    if s[1] != 20 {
17 +
    if s[1] <> 20 {
18 18
        return 3;
19 19
    }
20 -
    if s[2] != 40 {
20 +
    if s[2] <> 40 {
21 21
        return 4;
22 22
    }
23 -
    if s[3] != 50 {
23 +
    if s[3] <> 50 {
24 24
        return 5;
25 25
    }
26 26
27 27
    // Delete first element (index 0: value 10).
28 28
    s.delete(0);
29 29
30 -
    if s.len != 3 {
30 +
    if s.len <> 3 {
31 31
        return 6;
32 32
    }
33 -
    if s[0] != 20 {
33 +
    if s[0] <> 20 {
34 34
        return 7;
35 35
    }
36 -
    if s[1] != 40 {
36 +
    if s[1] <> 40 {
37 37
        return 8;
38 38
    }
39 -
    if s[2] != 50 {
39 +
    if s[2] <> 50 {
40 40
        return 9;
41 41
    }
42 42
43 43
    // Delete last element (index 2: value 50).
44 44
    s.delete(2);
45 45
46 -
    if s.len != 2 {
46 +
    if s.len <> 2 {
47 47
        return 10;
48 48
    }
49 -
    if s[0] != 20 {
49 +
    if s[0] <> 20 {
50 50
        return 11;
51 51
    }
52 -
    if s[1] != 40 {
52 +
    if s[1] <> 40 {
53 53
        return 12;
54 54
    }
55 55
56 56
    // Cap should be unchanged.
57 -
    if s.cap != 5 {
57 +
    if s.cap <> 5 {
58 58
        return 13;
59 59
    }
60 60
    return 0;
61 61
}
test/tests/slice.subslice.rad +2 -2
29 29
    let arr: [i32; 3] = [7, 8, 9];
30 30
    let slice: *[i32] = &arr[..];
31 31
32 32
    // Test single element subslice
33 33
    let single: *[i32] = &slice[1..2];
34 -
    if (single[0] != 8 or single.len != 1) {
34 +
    if (single[0] <> 8 or single.len <> 1) {
35 35
        return false;
36 36
    }
37 37
38 38
    // Test empty subslice
39 39
    let empty: *[i32] = &slice[2..2];
40 -
    if (empty.len != 0) {
40 +
    if (empty.len <> 0) {
41 41
        return false;
42 42
    }
43 43
    return true;
44 44
}
45 45
test/tests/switch.blockargs.clobber.rad +2 -2
20 20
@default fn main() -> i32 {
21 21
    // Critical case: two payload values that differ.
22 22
    // With the bug, the switch clobber makes this return true.
23 23
    let a: Val = Val::data(42);
24 24
    let b: Val = Val::data(99);
25 -
    assert a != b;
25 +
    assert a <> b;
26 26
27 27
    // Same payload - should be equal.
28 28
    let c: Val = Val::data(42);
29 29
    let d: Val = Val::data(42);
30 30
    assert c == d;
40 40
    assert g == h;
41 41
42 42
    // Different variants - should not be equal.
43 43
    let i: Val = Val::none;
44 44
    let j: Val = Val::data(42);
45 -
    assert i != j;
45 +
    assert i <> j;
46 46
    return 0;
47 47
}
test/tests/union.payload.record.eq.rad +1 -1
13 13
fn maybePointEq(a: MaybePoint, b: MaybePoint) -> bool {
14 14
    return a == b;
15 15
}
16 16
17 17
fn maybePointNeq(a: MaybePoint, b: MaybePoint) -> bool {
18 -
    return a != b;
18 +
    return a <> b;
19 19
}
test/tests/unsigned.compare.rad +2 -2
61 61
        }
62 62
        if current < 0 {
63 63
            return false;
64 64
        }
65 65
        if current >= MAX_U32 {
66 -
            if current != MAX_U32 {
66 +
            if current <> MAX_U32 {
67 67
                return false;
68 68
            }
69 69
        } else {
70 70
            if current == MAX_U32 {
71 71
                return false;
72 72
            }
73 73
        }
74 74
        if current <= 0 {
75 -
            if current != 0 {
75 +
            if current <> 0 {
76 76
                return false;
77 77
            }
78 78
        } else {
79 79
            if current == 0 {
80 80
                return false;