You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ops.go 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package intcode
  2. // opcodeFunc is a function that describes an opcode implemented in the VM.
  3. type opcodeFunc = func(vm *VirtualMachine)
  4. var opcodes = [100]opcodeFunc{
  5. 1: addOpcode,
  6. 2: mulOpcode,
  7. 3: readOpCode,
  8. 4: writeOpCode,
  9. 5: jumpIfTrueOpCode,
  10. 6: jumpIfFalseOpCode,
  11. 7: lessThanOpCode,
  12. 8: equalsOpCode,
  13. 9: relativeBaseOffsetOpCode,
  14. 99: haltOpcode,
  15. }
  16. // addOpcode takes the values specified by args 1 and 2, adds them together, and stores at the memory address given
  17. // by arg 3.
  18. func addOpcode(vm *VirtualMachine) {
  19. *vm.arg(2) = *vm.arg(0) + *vm.arg(1)
  20. vm.ip += 4
  21. }
  22. // mulOpcode takes the values specified by args 1 and 2, multiplies them together, and stores at the memory address
  23. // given by arg 3.
  24. func mulOpcode(vm *VirtualMachine) {
  25. *vm.arg(2) = *vm.arg(0) * *vm.arg(1)
  26. vm.ip += 4
  27. }
  28. // readOpCode reads a value from the input stream and stores it at the memory address given by arg 1.
  29. func readOpCode(vm *VirtualMachine) {
  30. *vm.arg(0) = <-vm.Input
  31. vm.ip += 2
  32. }
  33. // writeOpCode writes the value specified by the first argument to the output stream.
  34. func writeOpCode(vm *VirtualMachine) {
  35. vm.Output <- *vm.arg(0)
  36. vm.ip += 2
  37. }
  38. // jumpIfTrueOpCode checks if the first argument is not zero, and if so jumps to the second argument.
  39. func jumpIfTrueOpCode(vm *VirtualMachine) {
  40. if *vm.arg(0) != 0 {
  41. vm.ip = *vm.arg(1)
  42. } else {
  43. vm.ip += 3
  44. }
  45. }
  46. // jumpIfFalseOpCode checks if the first argument is zero, and if so jumps to the second argument.
  47. func jumpIfFalseOpCode(vm *VirtualMachine) {
  48. if *vm.arg(0) == 0 {
  49. vm.ip = *vm.arg(1)
  50. } else {
  51. vm.ip += 3
  52. }
  53. }
  54. // lessThanOpCode checks if the first argument is less than the second, and stores the result at the address given
  55. // by the third argument.
  56. func lessThanOpCode(vm *VirtualMachine) {
  57. if *vm.arg(0) < *vm.arg(1) {
  58. *vm.arg(2) = 1
  59. } else {
  60. *vm.arg(2) = 0
  61. }
  62. vm.ip += 4
  63. }
  64. // equalsOpCode checks if the first argument is equal to the second, and stores the result at the address given
  65. // by the third argument.
  66. func equalsOpCode(vm *VirtualMachine) {
  67. if *vm.arg(0) == *vm.arg(1) {
  68. *vm.arg(2) = 1
  69. } else {
  70. *vm.arg(2) = 0
  71. }
  72. vm.ip += 4
  73. }
  74. // relativeBaseOffsetOpCode increases the relative base by the given argument.
  75. func relativeBaseOffsetOpCode(vm *VirtualMachine) {
  76. vm.rb += *vm.arg(0)
  77. vm.ip += 2
  78. }
  79. // haltOpcode halts the VM and takes no arguments.
  80. func haltOpcode(vm *VirtualMachine) {
  81. vm.Halted = true
  82. }