nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.55k stars 1.47k forks source link

deepCopy bug #7108

Open dom96 opened 6 years ago

dom96 commented 6 years ago
import terminal, os
type Board = array[-1 .. 40, array[-1 .. 20, bool]]

proc initBoard: Board =
  result[20][8] = true
  result[21][9] = true
  result[19][10] = true
  result[20][10] = true
  result[21][10] = true

proc countLives(board: Board, x, y: int): int =
  result = if board[x][y]: -1 else: 0
  for nx in (x - 1) .. (x + 1):
    for ny in (y - 1) .. (y + 1):
      if board[nx][ny]: inc result

proc tick(board: var Board) =
  var copy = board
  deepCopy(copy, board) # REMOVE THIS TO GET A WORKING VERSION
  for x in 0..<board.high:
    for y in 0..<board[0].high:
      let neighbours = countLives(copy, x, y)
      let alive = copy[x][y]
      if not alive and neighbours == 3:
        board[x][y] = true
      elif alive and neighbours in {0 .. 8} - {2, 3}:
        board[x][y] = false

proc draw(board: Board) =
  stdout.eraseScreen()
  for x in 0..<board.high:
    for y in 0..<board[0].high:
      setCursorPos(stdout, x, y)
      if board[x][y]:
        stdout.write "●"
      else:
        stdout.write " "
  stdout.flushFile

var board = initBoard()
while true:
  board.draw()
  board.tick()

  sleep(200)
shirleyquirk commented 3 years ago

minimalish version:

type Foo = array[0..1, array[0..1, int]]
template Impl =
  var b, c: Foo
  b = deepCopy(x)
  deepCopy(c, x)
  assert x == b
  assert x == c
proc bar(x: Foo) =
  Impl()
proc baz(x: var Foo) =
  Impl()

var a: Foo
a[0][0] = 1
bar(a) #works
baz(a) # assertionDefect c!=a