Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package intcode
  2. // VirtualMachine is an IntCode virtual machine.
  3. type VirtualMachine struct {
  4. ip int
  5. modes uint8
  6. Memory []int
  7. Halted bool
  8. Input chan int
  9. Output chan int
  10. }
  11. // NewVirtualMachine creates a new IntCode virtual machine, initialised to the given slice of memory.
  12. // The caller is responsible for initialising the VM's I/O channels if required.
  13. func NewVirtualMachine(memory []int) *VirtualMachine {
  14. vm := &VirtualMachine{
  15. ip: 0,
  16. Memory: memory,
  17. Halted: false,
  18. }
  19. return vm
  20. }
  21. // arg Returns the value of the given argument for the current instruction.
  22. func (vm *VirtualMachine) arg(pos int) int {
  23. mask := uint8(1) << uint8(pos)
  24. if vm.modes&mask == mask {
  25. return vm.Memory[vm.ip+1+pos]
  26. } else {
  27. return vm.Memory[vm.Memory[vm.ip+1+pos]]
  28. }
  29. }
  30. // Run repeatedly executes instructions until the VM halts.
  31. func (vm *VirtualMachine) Run() {
  32. for !vm.Halted {
  33. instruction := vm.Memory[vm.ip]
  34. opcode := instruction % 100
  35. vm.modes = 0
  36. mask := uint8(1)
  37. for i := instruction / 100; i > 0; i /= 10 {
  38. if i%10 == 1 {
  39. vm.modes = vm.modes | mask
  40. }
  41. mask = mask << 1
  42. }
  43. opcodes[opcode](vm)
  44. }
  45. if vm.Output != nil {
  46. close(vm.Output)
  47. }
  48. }
  49. // Reset resets the memory to the given slice, and all other state back to its original value.
  50. func (vm *VirtualMachine) Reset(memory []int) {
  51. copy(vm.Memory, memory)
  52. vm.ip = 0
  53. vm.Halted = false
  54. }