It would be possible to write a C compiler for Hack.
Using the compiler / VM translator scheme, the compiler would simply use new VM commands to do unsigned comparisons, sat 
ult and 
ugt. It would be the VM translator's job to write appropriate ASM to do the unsigned compares.
(Note that the simple ASM code that students usually write for 
gt and 
lt is not true 
signed comparison; the D=x, D=D-y, D;JGT code fails if abs(x-y) >= 32768.)
Assuming that the VM translator writes correct signed compare code for 
gt and 
lt that handles full input range, it is possible to write unsigned compares in Jack:
function boolean ugt (/*unsigned*/ int ux, /*unsigned*/ int uy) {
    int INT_MIN;
    let INT_MIN = ~32767;   // 0x8000
    return (ux-INT_MIN) > (uy-INT_MIN);
}
Likewise, you can do tricky things to get around not having carry and sign status bits. For instance, here's a double-word left shift and a right rotate:
    int MSW, LSW;
    boolean sign;
    // left shift MSW:LSW
    let MSW = MSW+MSW-(LSW<0);  // Yes, that's a minus
    let LSW = LSW+LSW;
    // left rotate LSW
    let sign = (LSW < 0);
    let LSW = LSW+LSW-sign;
At one point when I was between contracts I got bored and wrote a 
floating point class in Jack.  A bit later I write a 
Trigonometry class using Float.
--Mark