kosayoda / chickenpy

A Python implementation of the chicken esoteric programming language.
https://pypi.org/project/chickenpy/
MIT License
16 stars 4 forks source link

The 99 chickens program crashes #2

Open none-None1 opened 1 year ago

none-None1 commented 1 year ago

The 99 chickens program crashes and raises an error:

ValueError: invalid literal for int() with base 10: ''
armichaud commented 1 year ago

I'm working on a Rust implementation and encountered a similar issue. Without any user input, the program crashes at instruction 48, attempting to subtract from an empty string. This part of the program is supposed to be looping back to the user input, decrementing the count until we reach 0 chickens.

The root of the issue lies in the fact that the examples pass the Javascript implementation on the creator's site, and so end up relying on some of Javascript's weird behavior, e.g. the addition operator also serves as string concatenation, automatically casting integers to strings. What's relevant here is the comparison of 0 against the user input on instruction 34. '' == 0 returns true in Javascript, and false (or type error) in most any other language. That comparison needs to return truthy for any value other than a positive integer in order to trigger the jump from instruction 36 to the end of the program, where the final "no chickens" is appended.

Below is the full debug log of the program with no user input when '' != 0. Ignore the fact that the numbers are wrapped in double quotes – they are in fact signed integers.

Loading Instruction Num(2)
Executing 18
Resulting Input Register: Chars("")
Resulting Data Stack: ["8"]

Loading Instruction Num(3)
Executing 14
Resulting Input Register: Chars("")
Resulting Data Stack: ["8", "4"]

Loading Instruction Num(4)
Executing 4
Resulting Input Register: Chars("")
Resulting Data Stack: ["32"]

Loading Instruction Num(5)
Executing 9
Resulting Input Register: Chars("")
Resulting Data Stack: [" "]

Loading Instruction Num(6)
Executing 13
Resulting Input Register: Chars("")
Resulting Data Stack: [" ", "3"]

// STORES SPACE IN REGISTER 3
Loading Instruction Num(7)
Executing 7
Resulting Input Register: Chars("")
Resulting Data Stack: []

Loading Instruction Num(8)
Executing 13
Resulting Input Register: Chars("")
Resulting Data Stack: ["3"]

// LOAD REGISTER 3 FROM STACK
Loading Instruction Num(9)
Executing 6
Resulting Input Register: Chars("")
Resulting Data Stack: [" "]

Loading Instruction Num(11)
Executing 1
Resulting Input Register: Chars("")
Resulting Data Stack: [" ", "chicken"]

// CONCATENATE
Loading Instruction Num(12)
Executing 2
Resulting Input Register: Chars("")
Resulting Data Stack: [" chicken"]

Loading Instruction Num(13)
Executing 33
Resulting Input Register: Chars("")
Resulting Data Stack: [" chicken", "23"]

Loading Instruction Num(14)
Executing 15
Resulting Input Register: Chars("")
Resulting Data Stack: [" chicken", "23", "5"]

Loading Instruction Num(15)
Executing 4
Resulting Input Register: Chars("")
Resulting Data Stack: [" chicken", "115"]

Loading Instruction Num(16)
Executing 9
Resulting Input Register: Chars("")
Resulting Data Stack: [" chicken", "s"]

Loading Instruction Num(17)
Executing 2
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens"]

Loading Instruction Num(18)
Executing 20
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens", "10"]

Loading Instruction Num(19)
Executing 9
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens", "\n"]

Loading Instruction Num(20)
Executing 2
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens\n"]

Loading Instruction Num(21)
Executing 12
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens\n", "2"]

// STORE " chickens\n" IN REGISTER 2
Loading Instruction Num(22)
Executing 7
Resulting Input Register: Chars("")
Resulting Data Stack: []

Loading Instruction Num(23)
Executing 11
Resulting Input Register: Chars("")
Resulting Data Stack: ["1"]

// LOAD REGISTER 1 (USER INPUT) FROM STACK
Loading Instruction Num(24)
Executing 6
Resulting Input Register: Chars("")
Resulting Data Stack: [""]

Loading Instruction Num(26)
Executing 11
Resulting Input Register: Chars("")
Resulting Data Stack: ["", "1"]

// USER INPUT IS FALSE COMPARED TO ONE
Loading Instruction Num(27)
Executing 5
Resulting Input Register: Chars("")
Resulting Data Stack: ["0"]

Loading Instruction Num(28)
Executing 31
Resulting Input Register: Chars("")
Resulting Data Stack: ["0", "21"]

// DOES NOT JUMP TO 50
Loading Instruction Num(29)
Executing 8
Resulting Input Register: Chars("")
Resulting Data Stack: []

Loading Instruction Num(30)
Executing 11
Resulting Input Register: Chars("")
Resulting Data Stack: ["1"]

// LOAD REGISTER 1 FROM STACK (USER INPUT, HERE EMPTY STRING)
Loading Instruction Num(31)
Executing 6
Resulting Input Register: Chars("")
Resulting Data Stack: [""]

Loading Instruction Num(33)
Executing 10
Resulting Input Register: Chars("")
Resulting Data Stack: ["", "0"]

// THIS IS THE BUG !!!
// USE COMPARE TO CHECK IF INPUT IS ZERO
Loading Instruction Num(34)
Executing 5
Resulting Input Register: Chars("")
Resulting Data Stack: ["0"]

Loading Instruction Num(35)
Executing 43
Resulting Input Register: Chars("")
Resulting Data Stack: ["0", "33"]

// DOESN'T JUMP TO 69
Loading Instruction Num(36)
Executing 8
Resulting Input Register: Chars("")
Resulting Data Stack: []

Loading Instruction Num(37)
Executing 11
Resulting Input Register: Chars("")
Resulting Data Stack: ["1"]

// LOAD EMPTY STRING FROM STACK REGISTER 1
Loading Instruction Num(38)
Executing 6
Resulting Input Register: Chars("")
Resulting Data Stack: [""]

Loading Instruction Num(40)
Executing 12
Resulting Input Register: Chars("")
Resulting Data Stack: ["", "2"]

// LOAD CHICKENS FROM STACK REGISTER 2
Loading Instruction Num(41)
Executing 6
Resulting Input Register: Chars("")
Resulting Data Stack: ["", " chickens\n"]

// CONCATENATE
Loading Instruction Num(43)
Executing 2
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens\n"]

Loading Instruction Num(44)
Executing 11
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens\n", "1"]

// LOAD FROM STACK REGISTER 1
Loading Instruction Num(45)
Executing 6
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens\n", ""]

Loading Instruction Num(47)
Executing 11
Resulting Input Register: Chars("")
Resulting Data Stack: [" chickens\n", "", "1"]

Loading Instruction Num(48)
Executing 3
thread 'main' panicked at 'Incompatible types – a: Chars("") | b: Num(1)', src/lib.rs:77:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace