summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@gmail.com>2016-01-18 13:20:13 +0000
committerDominik Picheta <dominikpicheta@gmail.com>2016-01-18 13:20:13 +0000
commitfaf5fb8467d5b841c840e255ccd19db6bfd08d2b (patch)
tree9f5c2693c050a7c6f9a9953f8c9624eb9372ca29
parenta34206fe84a3f02c0ee89fe32611ac4496ea9677 (diff)
parent7211462a04f7759126145a878b98f598494322ea (diff)
downloadNim-faf5fb8467d5b841c840e255ccd19db6bfd08d2b.tar.gz
Merge branch 'devel' of github.com:nim-lang/Nim into devel
-rw-r--r--compiler/ccgexprs.nim2
-rw-r--r--compiler/lambdalifting.nim8
-rw-r--r--compiler/transf.nim4
-rw-r--r--tools/nimgrep.nim14
4 files changed, 22 insertions, 6 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 6f513c165..3607f347e 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1847,6 +1847,8 @@ proc genClosure(p: BProc, n: PNode, d: var TLoc) =
     var tmp, a, b: TLoc
     initLocExpr(p, n.sons[0], a)
     initLocExpr(p, n.sons[1], b)
+    if n.sons[0].skipConv.kind == nkClosure:
+      internalError(n.info, "closure to closure created")
     getTemp(p, n.typ, tmp)
     linefmt(p, cpsStmts, "$1.ClPrc = $2; $1.ClEnv = $3;$n",
             tmp.rdLoc, a.rdLoc, b.rdLoc)
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index 9265d09e3..1c0c2494a 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -213,7 +213,7 @@ proc makeClosure*(prc: PSym; env: PNode; info: TLineInfo): PNode =
   if env == nil:
     result.add(newNodeIT(nkNilLit, info, getSysType(tyNil)))
   else:
-    if env.kind == nkClosure:
+    if env.skipConv.kind == nkClosure:
       localError(info, "internal error: taking closure of closure")
     result.add(env)
 
@@ -711,7 +711,11 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
   of nkClosure:
     if n[1].kind == nkNilLit:
       n.sons[0] = liftCapturedVars(n[0], owner, d, c)
-      #if n.sons[0].kind == nkClosure: result = n.sons[0]
+      let x = n.sons[0].skipConv
+      if x.kind == nkClosure:
+        #localError(n.info, "internal error: closure to closure created")
+        # now we know better, so patch it:
+        n.sons[0] = x.sons[0]
   of nkLambdaKinds, nkIteratorDef:
     if n.typ != nil and n[namePos].kind == nkSym:
       let m = newSymNode(n[namePos].sym)
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 3e074841e..b2bbdcec3 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -383,9 +383,11 @@ proc generateThunk(prc: PNode, dest: PType): PNode =
   # (see internal documentation):
   if gCmd == cmdCompileToJS: return prc
   result = newNodeIT(nkClosure, prc.info, dest)
-  var conv = newNodeIT(nkHiddenStdConv, prc.info, dest)
+  var conv = newNodeIT(nkHiddenSubConv, prc.info, dest)
   conv.add(emptyNode)
   conv.add(prc)
+  if prc.kind == nkClosure:
+    internalError(prc.info, "closure to closure created")
   result.add(conv)
   result.add(newNodeIT(nkNilLit, prc.info, getSysType(tyNil)))
 
diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim
index 221181f66..e93168847 100644
--- a/tools/nimgrep.nim
+++ b/tools/nimgrep.nim
@@ -11,7 +11,7 @@ import
   os, strutils, parseopt, pegs, re, terminal
 
 const
-  Version = "0.9"
+  Version = "1.0"
   Usage = "nimgrep - Nim Grep Utility Version " & Version & """
 
   (c) 2012 Andreas Rumpf
@@ -56,6 +56,7 @@ var
 
 proc ask(msg: string): string =
   stdout.write(msg)
+  stdout.flushFile()
   result = stdin.readLine()
 
 proc confirm: TConfirmEnum =
@@ -108,18 +109,21 @@ proc highlight(s, match, repl: string, t: tuple[first, last: int],
   writeColored(match)
   for i in t.last+1 .. y: stdout.write(s[i])
   stdout.write("\n")
+  stdout.flushFile()
   if showRepl:
     stdout.write(spaces(alignment-1), "-> ")
     for i in x .. t.first-1: stdout.write(s[i])
     writeColored(repl)
     for i in t.last+1 .. y: stdout.write(s[i])
     stdout.write("\n")
+    stdout.flushFile()
 
 proc processFile(filename: string) =
   var filenameShown = false
   template beforeHighlight =
     if not filenameShown and optVerbose notin options:
       stdout.writeLine(filename)
+      stdout.flushFile()
       filenameShown = true
 
   var buffer: string
@@ -128,7 +132,9 @@ proc processFile(filename: string) =
   except IOError:
     echo "cannot open file: ", filename
     return
-  if optVerbose in options: stdout.writeLine(filename)
+  if optVerbose in options:
+    stdout.writeLine(filename)
+    stdout.flushFile()
   var pegp: TPeg
   var rep: Regex
   var result: string
@@ -254,10 +260,12 @@ proc walker(dir: string) =
 
 proc writeHelp() =
   stdout.write(Usage)
+  stdout.flushFile()
   quit(0)
 
 proc writeVersion() =
   stdout.write(Version & "\n")
+  stdout.flushFile()
   quit(0)
 
 proc checkOptions(subset: TOptions, a, b: string) =
@@ -291,7 +299,7 @@ for kind, key, val in getopt():
     of "word", "w": incl(options, optWord)
     of "ignorecase", "i": incl(options, optIgnoreCase)
     of "ignorestyle", "y": incl(options, optIgnoreStyle)
-    of "ext": extensions = val.split('|')
+    of "ext": extensions.add val.split('|')
     of "nocolor": useWriteStyled = false
     of "verbose": incl(options, optVerbose)
     of "help", "h": writeHelp()
> (real) port # that way repeatedly running the test will give ports time to timeout and # close before reusing them make-random-nondeterministic port:num <- random-in-range null/real-random-numbers, 8000, 8100 run [ socket:num <- $open-server-socket port assert socket, [ F - example-server-test: $open-server-socket failed] handler-routine:number <- start-running serve-one-request socket, example-handler ] source:&:source:char <- start-reading-from-network null/real-resources, [localhost/], port response:text <- drain source 10:@:char/raw <- copy *response memory-should-contain [ 10:array:character <- [abc] ] socket <- $close-socket socket ] # helper just for this scenario def example-handler query:text -> response:text [ local-scope load-inputs return [abc] ] # To test client operations, use 'assume-resources' with a filename that # begins with a hostname. (Filenames starting with '/' are assumed to be # local.) scenario example-client-test [ local-scope assume-resources [ [example.com/] <- [ |abc| ] ] run [ source:&:source:char <- start-reading-from-network resources, [example.com/] ] contents:text <- drain source 10:@:char/raw <- copy *contents memory-should-contain [ 10:array:character <- [abc ] ] ] type request-handler = (recipe text -> text) def serve-one-request socket:num, request-handler:request-handler -> socket:num [ local-scope load-inputs session:num <- $accept socket assert session, [ F - example-server-test: $accept failed] contents:&:source:char, sink:&:sink:char <- new-channel 30 start-running receive-from-socket session, sink query:text <- drain contents response:text <- call request-handler, query write-to-socket session, response session <- $close-socket session ] def start-reading-from-network resources:&:resources, uri:text -> contents:&:source:char [ local-scope load-inputs { port:num, port-found?:boolean <- next-input break-if port-found? port <- copy 80/http-port } { break-unless resources # fake network contents <- start-reading-from-fake-resource resources, uri return } # real network host:text, path:text <- split-at uri, 47/slash socket:num <- $open-client-socket host, port assert socket, [contents] req:text <- interpolate [GET _ HTTP/1.1], path request-socket socket, req contents:&:source:char, sink:&:sink:char <- new-channel 10000 start-running receive-from-client-socket-and-close socket, sink ] def request-socket socket:num, s:text -> socket:num [ local-scope load-inputs write-to-socket socket, s $write-to-socket socket, 13/cr $write-to-socket socket, 10/lf # empty line to delimit request $write-to-socket socket, 13/cr $write-to-socket socket, 10/lf ] def receive-from-socket socket:num, sink:&:sink:char -> sink:&:sink:char, socket:num [ local-scope load-inputs { +next-attempt c:char, found?:bool, eof?:bool, error:num <- $read-from-socket socket break-if eof? break-if error { break-unless found? sink <- write sink, c } { break-if found? switch } loop } sink <- close sink ] def receive-from-client-socket-and-close socket:num, sink:&:sink:char -> sink:&:sink:char, socket:num [ local-scope load-inputs sink <- receive-from-socket socket, sink socket <- $close-socket socket ] def write-to-socket socket:num, s:text [ local-scope load-inputs len:num <- length *s i:num <- copy 0 { done?:bool <- greater-or-equal i, len break-if done? c:char <- index *s, i $write-to-socket socket, c i <- add i, 1 loop } ] # like split-first, but don't eat the delimiter def split-at text:text, delim:char -> x:text, y:text [ local-scope load-inputs # empty text? return empty texts len:num <- length *text { empty?:bool <- equal len, 0 break-unless empty? x:text <- new [] y:text <- new [] return } idx:num <- find-next text, delim, 0 x:text <- copy-range text, 0, idx y:text <- copy-range text, idx, len ] scenario text-split-at [ local-scope x:text <- new [a/b] run [ y:text, z:text <- split-at x, 47/slash 10:@:char/raw <- copy *y 20:@:char/raw <- copy *z ] memory-should-contain [ 10:array:character <- [a] 20:array:character <- [/b] ] ]