Re: Yet another misadventure/possible bug...

2018-02-26 Thread StasB
I've done that as well. I'm just not yet sure how to go about actually 
debugging the VM. Still figuring out how to instantiate it in a clean project 
and feed it some code.


Re: Yet another misadventure/possible bug...

2018-02-26 Thread cdome
I have followed my advice, and got a stacktrace of compiler crash:


nim.nim(121) nim
nim.nim(77)  handleCmdLine
main.nim(173)mainCommand
main.nim(77) commandCompileToC
modules.nim(242) compileProject
modules.nim(182) compileModule
passes.nim(250)  processModule
passes.nim(139)  processTopLevelStmt
sem.nim(576) myProcess
sem.nim(544) semStmtAndGenerateGenerics
semstmts.nim(1911)   semStmt
semexprs.nim(793)semExprNoType
semexprs.nim(2396)   semExpr
semstmts.nim(1758)   semStaticStmt
vm.nim(1659) evalStaticStmt
vm.nim(1649) evalConstExprAux
vm.nim(787)  rawExecute
system.nim(2839) sysFatal
Error: unhandled exception: node is not accessible [FieldError]


So it likely that the problem is in **vm.nim** file. At the top of vm.nim there 
are two constants that should be helpful producing assembly like output: ` 
debugEchoCode`, `traceCode`


Re: Fatal compilation error on Windows

2018-02-26 Thread tormund
Fixed this for gcc 
[https://github.com/nim-lang/Nim/pull/7263](https://github.com/nim-lang/Nim/pull/7263)
 Also we can do same trick for vcc


Re: Yet another misadventure/possible bug...

2018-02-26 Thread StasB
I've looked at it, but I have no idea where to even start. My approach would've 
been to examine the code generated for that function (assuming it can be viewed 
in a human-readable assembly-like form) and if it looks sane, to feed it to a 
fresh instance of the VM and follow the execution with a debugger, but I have 
no clue if this is viable with Nim. I did read the doc page, but the 
information there is very scarce and the code base is pretty large... Are there 
other resources?


Re: Yet another misadventure/possible bug...

2018-02-26 Thread cdome
It is something related to line: 


 page = addr pages[^1]

The following works fine:


proc parseAtlas(stream: var CtsStream) =
  var pages: seq[AtlasPage] = @[]
  
  while not stream.atEnd:
# Read a page:
pages.add(AtlasPage())
var line = ""
discard stream.readLine(line)

while peekLine(stream, line) and line != "":
  discard stream.readLine(line)
  let u0 = 100 / pages[^1].width




Re: Yet another misadventure/possible bug...

2018-02-26 Thread StasB
Alright. I'll do what cdome suggested and see if I can figure out why it 
crashes. Not sure I'm qualified, but it wouldn't hurt to try.


Re: Yet another misadventure/possible bug...

2018-02-26 Thread cdome
Hi StasB!

If it is important for you can try to investigate it youself. I find it is easy 
with Nim.

Build nim_temp using command in (takes 6 seconds): 


koch temp


Try building your code with nim_temp as usual: 


nim_temp c your_nim_file


You should get a nice stacktrace and good intuition where the problem is. More 
details: 
[https://github.com/nim-lang/Nim/wiki/Debugging-the-compiler](https://github.com/nim-lang/Nim/wiki/Debugging-the-compiler)


Re: [RFC] Cyclic imports and symbol dependencies

2018-02-26 Thread Arrrrrrrrr
Any project that is not a toy one will eventually run into this issue. I don't 
have any choice but I don't like splitting types and procs, produces more 
modules and readability suffers (You can define two types together that are 
related, but you cannot do the same with certain types and procs).

The biggest issue for me is that to work around cyclic imports sometimes you 
have to think deeply how to reorganize your code, and end up with a unintuitive 
module structure. When something is beyond saving I declare a proc var and 
later assign a proc to it because any other alternative is to fuck up your code 
even further.

As far as I'm concerned this cannot be fixed because macros and templates 
complicates the issue.


Re: [RFC] Cyclic imports and symbol dependencies

2018-02-26 Thread cumulonimbus
I am baffled by the need to have circular imports; I think I've been looking 
for an example in which they are actually needed (rather than "it saves 3 lines 
and a couple of minutes of reorganization") since Turbo Pascal added them in 
version 5.5 ; Indeed, dom's suggestion of having a types module has always 
solved any example I found without requiring circular imports.


Re: Preventing use after free

2018-02-26 Thread mashingan
thank you @mratsim, I didn't realize we can do that


Re: Yet another misadventure/possible bug...

2018-02-26 Thread mashingan
When I ran your snipped with "run" button in forum, it didn't crash.

Oh, only happened with devel version, I guess regression bug?


Yet another misadventure/possible bug...

2018-02-26 Thread StasB
Hi! The following snippet produces an "attempt to access a nil address" error, 
but only with the devel version, and only when **parseAtlas** is executed at 
compile time (the offending line is marked with a comment; only **parseAtlas** 
seems directly relevant): 


 const file = """

sprites.png
size: 1024,1024
format: RGBA
filter: Linear,Linear
repeat: none
char/slide_down
  rotate: false
  xy: 730, 810
  size: 204, 116
  orig: 204, 116
  offset: 0, 0
  index: -1
"""

type
  AtlasPage = object
width, height: int
path: string
  
  CtsStream = object
data: string
pos: int

# 
# Crappy string stream implementation, because Nim's doesn't work at 
compile time:
# Probably not interesting, but seems necessary to reproduce the bug.
# 

proc atEnd(stream: CtsStream): bool =
  stream.pos >= stream.data.len

proc readChar(stream: var CtsStream): char =
  if stream.atEnd:
result = '\0'
  else:
result = stream.data[stream.pos]
inc stream.pos

proc readLine(s: var CtsStream, line: var string): bool =
  # This is pretty much copied from the standard library:
  line.setLen(0)
  while true:
var c = readChar(s)
if c == '\c':
  c = readChar(s)
  break
elif c == '\L': break
elif c == '\0':
  if line.len > 0: break
  else: return false
line.add(c)
  result = true

proc peekLine(s: var CtsStream, line: var string): bool =
  let oldPos = s.pos
  result = s.readLine(line)
  s.pos = oldPos

proc initCtsStream(data: string): CtsStream =
  CtsStream(
pos: 0,
data: data
  )

# 
# Interesting stuff happens here:
# 

proc parseAtlas(stream: var CtsStream) =
  var pages: seq[AtlasPage] = @[]
  
  while not stream.atEnd:
# Read a page:
pages.add(AtlasPage())
var page = addr pages[^1]
var line = ""
discard stream.readLine(line)

while peekLine(stream, line) and line != "":
  echo page == nil
  discard stream.readLine(line)
  let u0 = 100 / page.width # <--- Crash happens 
here! 

static:
  var stream = initCtsStream(file)
  parseAtlas(stream)
  echo "Done!"


I couldn't shorten it any further. Even replacing the inner loop inside 
**parseAtlas** with a for that has the same body and executes the same number 
of times makes the error disappear. Perhaps I 'm doing something questionable 
with that page pointer?