I've been playing with Nim for about 4 weeks now. I've copied/run some small 
programs (Rosetta Stone), and translated some small Ruby snippets that 
compiled. Now I'm trying to do a direct translation of a bigger C++ program of 
about 200 loc with about 5 separate functions.

Here's an example of a snippet of code that won't compile.

When I write this routine with the following indention (starting from first 
column)
    
    
    proc segsieve(Kn: uint):
                                          # for Kn resgroups in segment
      for b in 0 .. <Kn:                  # for every byte in the segment
        seg[b] = 0                        # set every byte bit to prime (0)
      for r in 0 .. <rescnt:              # for each ith (of 8) residues for P5
        let biti = uint8(1 shl r)         # set the ith residue track bit mask
        let row  = r*pcnt                 # set address to ith row in next[]
        for j in 0 .. <pcnt:              # for each prime <= sqrt(N) for 
restrack
          if next[row+j] < uint(Kn):      # if 1st mult resgroup index <= seg 
size
            var k: int = int(next[row+j]) # get its resgroup value
            let prime = primes[j]         # get the prime
            while k < Kn:                 # for each primenth byte < segment 
size
              seg[k] = seg[k] or biti     # set ith residue in byte as nonprime
              next[row+j] = uint(k - Kn)  # 1st resgroup in next eligible 
segment
              k += prime
          else: next[row+j] -= uint(Kn)   # if 1st mult resgroup index > seg 
size
                                          # count the primes in the segment
      for byt in seg:                     # for the Kn resgroup bytes
        primecnt += uint(pbits[int(byt)]) # count the '0' bits as primes
    
    

I get the following compiler message, which points to the start of the first 
**for** statement:
    
    
    ssozp5segsieve.nim(56, 3) Error: expression expected, but found 'keyword 
for'
    

But when I get rid of the **proc** statement, and write it like below, starting 
from first column, it compiles and run.
    
    
    #proc segsieve(Kn: uint):
                                        # for Kn resgroups in segment
    for b in 0 .. <Kn:                  # for every byte in the segment
      seg[b] = 0                        # set every byte bit to prime (0)
    for r in 0 .. <rescnt:              # for each ith (of 8) residues for P5
      let biti = uint8(1 shl r)         # set the ith residue track bit mask
      let row  = r*pcnt                 # set address to ith row in next[]
      for j in 0 .. <pcnt:              # for each prime <= sqrt(N) for restrack
        if next[row+j] < uint(Kn):      # if 1st mult resgroup index <= seg size
          var k: int = int(next[row+j]) # get its resgroup value
          let prime = primes[j]         # get the prime
          while k < Kn:                 # for each primenth byte < segment size
            seg[k] = seg[k] or biti     # set ith residue in byte as nonprime
            next[row+j] = uint(k - Kn)  # 1st resgroup in next eligible segment
            k += prime
        else: next[row+j] -= uint(Kn)   # if 1st mult resgroup index > seg size
                                        # count the primes in the segment
    for byt in seg:                     # for the Kn resgroup bytes
      primecnt += uint(pbits[int(byt)]) # count the '0' bits as primes
    
    

This happens with alll the **procs** in the code. What am I doing wrong? Here's 
the whole code (88 tloc) that runs when no indentation is used.
    
    
    
    let pbits = [
     8,7,7,6,7,6,6,5,7,6,6,5,6,5,5,4,7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3
    ,7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3,6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2
    ,7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3,6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2
    ,6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2,5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1
    ,7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3,6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2
    ,6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2,5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1
    ,6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2,5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1
    ,5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1,4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0
    ]
    
    let residues = [1, 7, 11, 13, 17, 19, 23, 29, 31]
    
    # Global parameters
    const
      modp5  = 30          # prime generator mod value
      rescnt = 8           # number of residues for prime generator
    
    let
      #B = 262144
      B = 354
      Kn = B
      Ki = 0
      
      pcnt = 24            # number of primes from r1..sqrt(N)
    
    var
      primecnt = 3'u64     # number of primes <= N
      #next: seq[uint64 | uint]    # array of primes first multiples
      #primes: seq[uint]   # array of primes <= sqrt(N)
      #seg: seq[uint8]      # seg[B] segment byte array
      seg = newSeq[uint8](B)
    
    var next = newSeq[uint](rescnt*pcnt)
    
    let primes = [7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 
67, 71, 73, 79, 83, 89, 97, 101, 103]
    
    #proc next_init():
    var pos = newSeq[int](modp5)
    for i in 0 .. <rescnt: pos[residues[i]] = i-1
    pos[1] = rescnt-1
    
    # for each prime store resgroup on each restrack for prime*(modk+ri)
    for j in 0 .. <pcnt:                # for the pcnt primes r1..sqrt(N)
      let prime: uint = uint(primes[j])             # for each prime
      let k: uint = (prime-2) div uint(modp5)       # find the resgroup it's in
      let r: uint = (prime-2) mod uint(modp5) + 2   # its base residue value
      for ri in residues[1 .. rescnt]:  # for each residue value
        let prod: int = int(r) * ri                 # create residues 
cross-product r*ri
        let row:  int = pos[prod mod modp5] * pcnt  # create residue track 
address
        next[row + j] = k*(prime + uint(ri)) + uint(prod-2) div uint(modp5) # 
resgroup for prime*(modk+ri))
    
    #proc segsieve(Kn: uint):
                                        # for Kn resgroups in segment
    for b in 0 .. <Kn:                  # for every byte in the segment
      seg[b] = 0                        # set every byte bit to prime (0)
    for r in 0 .. <rescnt:              # for each ith (of 8) residues for P5
      let biti = uint8(1 shl r)         # set the ith residue track bit mask
      let row  = r*pcnt                 # set address to ith row in next[]
      for j in 0 .. <pcnt:              # for each prime <= sqrt(N) for restrack
        if next[row+j] < uint(Kn):      # if 1st mult resgroup index <= seg size
          var k: int = int(next[row+j]) # get its resgroup value
          let prime = primes[j]         # get the prime
          while k < Kn:                 # for each primenth byte < segment size
            seg[k] = seg[k] or biti     # set ith residue in byte as nonprime
            next[row+j] = uint(k - Kn)  # 1st resgroup in next eligible segment
            k += prime
        else: next[row+j] -= uint(Kn)   # if 1st mult resgroup index > seg size
                                        # count the primes in the segment
    for byt in seg:                     # for the Kn resgroup bytes
      primecnt += uint(pbits[int(byt)]) # count the '0' bits as primes
    
    #proc printprms(Kn: unit, Ki: uint64):
    
    # Extract and print the primes in each segment:
    # recommend piping output to less: ./ssozpxxx | less
    # can then use Home, End, Pgup, Pgdn keys to see primes
    for k in 0 .. <Kn:                 # for Kn residues groups|bytes
      for r in 0 .. <8:                # for each residue|bit in a byte
        if (int(seg[k]) and (1 shl r)) == 0:   # if it's '0' it's a prime
          write(stdout, " ", modp5*(Ki+k) + residues[r+1])
    
    echo "\n"
    
    #segsieve(Kn)
    echo(primecnt)
    echo(seg[0..353])
    

I'm using Nim 0.17 with Manjaro (KDE5) in VirtualBox with gcc 7.1.1 and clang 
4.0.1 (same results using gcc or clang) with the following compiler directive.
    
    
    [jzakiya@jabari-pc nim]$ nim c --cc:clang --d:release  ssozp5segsieve.nim
    Hint: used config file '/etc/nim.cfg' [Conf]
    Hint: system [Processing]
    Hint: ssozp5segsieve [Processing]
    ssozp5segsieve.nim(56, 3) Error: expression expected, but found 'keyword 
for'
    
    

Reply via email to