CensoredUsername / whitespace-rs

A whitespace JIT compiler
Mozilla Public License 2.0
62 stars 4 forks source link

Incorrect compiler behavior? #4

Closed Yu212 closed 5 months ago

Yu212 commented 5 months ago

While using this compiler for competitive programming, I discovered two behaviors of this compiler that differ from the official interpreter and many other compilers.

This compiler interprets \n as 0, whereas other implementation interprets __\n or \t_\n as 0.

This compiler copies the nth value from the bottom of the stack with the Copy instruction. other implementation copies the nth value from the top of the stack. If the Copy instruction is called in a function, it is not possible to know the offset of the stack at compile time, so it is more appropriate to use the index from the top of the stack.

Are these behaviors intended? If not, would you correct them? (I'm also interested in contributing a PR)

CensoredUsername commented 5 months ago

This compiler interprets \n as 0, whereas other implementation interprets _ or \t as 0.

This compiler implements those as 0 as well. If my haskell is correct then there's 5 valid ways of writing 0 as an integer: The fully formed __\n and \t_\n, and the shorter technically incomplete \n, _\n and \t\n.

The spec is a bit vague on what the incomplete ones would be (as the first data bit and/or the sign bit) get lost, but the official interpreter does accept them as 0.

This compiler copies the nth value from the bottom of the stack with the Copy instruction. other implementation copies the nth value from the top of the stack.

The official page is very unclear about what Copy does. Looking at the reference interpreter, you may be correct here. It does seem that Copy is used very rarely then. I've never encountered a whitespace program that failed due to this mismatch.

That does seem more logical as well. Feel free to make a pull request.

edit: looking through the ecosystem I can find both ways implemented. Seems like this was the source of much confusion.

Yu212 commented 5 months ago

Sorry about the first one, I had checked that the __\n was causing the error, but in fact it was because my editor adding a \n at the end of the code. I'll PR about the second one later. Thank you!

CensoredUsername commented 5 months ago

I think I already have a fix in f52bd3d. Mind testing that instead?

Yu212 commented 5 months ago

Wow thank you for implementing it. How should I test? I confirmed that the code I had in mind works correctly (same as the official interpreter) with mod.rs/interpret_block and compiler_x64.rs/compile

    push 123
    call func
    pop
    push 10
loop:
    push 1
    push 2
    push 3
    copy 1
    pnum
    pop
    pop
    pop
    push 1
    sub
    dup
    jz end
    jmp loop
end:
    exit

func:
    push 456
    copy 1
    pnum
    pop
    ret
CensoredUsername commented 5 months ago

If it worked for you, that's fine. Just wanted to confirm I indeed implemented the right behaviour now. I'll close this and make a new release!

Yu212 commented 5 months ago

Okay, thank you!