dromologue
dromologue

Reputation: 51

Can't evaluate at compile time - NIM

Hi I'm starting to play around with NIM

I get a "can't evaluate at compile time" error on this code:

import strutils

type
 Matrix[x, y: static[int], T] = object
  data: array[x * y, T]

var n,m: int = 0

  
proc readFile() =
  
  let f = open("matrix.txt")
  defer: f.close()

  var graph_size = parseInt(f.readline)
  var whole_graph: Matrix[graph_size, graph_size, int]
  

  for line in f.lines:
   for field in line.splitWhitespace:
    var cell = parseInt(field)
    whole_graph[n][m] = cell
    m = m + 1 
   n = n + 1
     


readFile()

Any help appreciated.

Upvotes: 0

Views: 924

Answers (1)

Philipp Doerner
Philipp Doerner

Reputation: 1882

Unless you absolutely positively need array in this scenario while not knowing its size at compile-time, you may want to rather swap to the seq type, whose size does not need to be known at compile-time.

Together with std/enumerate you can even save yourself the hassle of tracking the index with n and m:

import std/[strutils, enumerate]

type Matrix[T] = seq[seq[T]]

proc newZeroIntMatrix(x: int, y: int): Matrix[int] =
  result = newSeqOfCap[seq[int]](x)
  for i in 0..x-1:
    result.add(newSeqOfCap[int](y))
    for j in 0..y-1:
      result[i].add(0)

proc readFile(): Matrix[int] =
  let f = open("matrix.txt")
  defer: f.close()

  let graph_size = parseInt(f.readline)
  var whole_graph = newZeroIntMatrix(graph_size, graph_size)
  
  for rowIndex, line in enumerate(f.lines):
    for columnIndex, field in enumerate(line.split):
      let cell = parseInt(field)
      whole_graph[rowIndex][columnIndex] = cell
    
  result = whole_graph

let myMatrix = readFile()
echo myMatrix.repr

Further things I'd like to point out though are:

  • array[x * y, T] will not give you a 2D array, but a single array of length x*y. If you want a 2D array, you would most likely want to store this as array[x, array[y, T]]. That is assuming that you know x and y at compile-time, so your variable declaration would look roughly like this: var myMatrix: array[4, array[5, int]]
  • Your Matrix type has the array in its data field, so trying to access the array with that Matrix type needs to be done accordingly (myMatrix.data[n][m]). That is, unless you define proper []and []= procs for the Matrix type that do exactly that under the hood.

Upvotes: 1

Related Questions