summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/main.nim13
-rw-r--r--compiler/service.nim71
-rwxr-xr-xcompiler/suggest.nim21
-rwxr-xr-xdoc/nimrodc.txt1
-rwxr-xr-xdoc/tut1.txt10
-rwxr-xr-xdoc/tut2.txt4
-rwxr-xr-xlib/system/alloc.nim3
-rwxr-xr-xpackages/docutils/rst.nim15
-rwxr-xr-xreadme.txt2
-rwxr-xr-xweb/index.txt26
-rwxr-xr-xweb/question.txt16
11 files changed, 142 insertions, 40 deletions
diff --git a/compiler/main.nim b/compiler/main.nim
index 37feabd17..dec393c50 100755
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -16,7 +16,7 @@ import
   wordrecg, sem, semdata, idents, passes, docgen, extccomp,
   cgen, ecmasgen,
   platform, nimconf, importer, passaux, depends, evals, types, idgen,
-  tables, docgen2
+  tables, docgen2, service
 
 const
   has_LLVM_Backend = false
@@ -292,5 +292,16 @@ proc MainCommand =
     gCmd = cmdIdeTools
     wantMainModule()
     CommandSuggest()
+  of "serve":
+    gCmd = cmdIdeTools
+    msgs.gErrorMax = high(int)  # do not stop after first error
+    semanticPasses()
+    # no need to write rod files and would slow down things:
+    #registerPass(rodwrite.rodwritePass())
+    discard CompileModule(options.libpath / "system", {sfSystemModule})
+    service.serve(proc () =
+      let projectFile = gProjectFull
+      discard CompileModule(projectFile, {sfMainModule})
+    )
   else: rawMessage(errInvalidCommandX, command)
 
diff --git a/compiler/service.nim b/compiler/service.nim
new file mode 100644
index 000000000..95fb11022
--- /dev/null
+++ b/compiler/service.nim
@@ -0,0 +1,71 @@
+#
+#
+#           The Nimrod Compiler
+#        (c) Copyright 2012 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Implements the "compiler as a service" feature.
+
+import 
+  sockets,
+  times, commands, options, msgs, nimconf,
+  extccomp, strutils, os, platform, main, parseopt
+
+# We cache modules and the dependency graph. However, we don't check for
+# file changes but expect the client to tell us about them, otherwise the
+# repeated CRC calculations may turn out to be too slow.
+
+var 
+  arguments: string = ""      # the arguments to be passed to the program that
+                              # should be run
+
+proc ProcessCmdLine(pass: TCmdLinePass, cmd: string) = 
+  # XXX remove duplication with nimrod.nim
+  var p = parseopt.initOptParser(cmd)
+  var argsCount = 0
+  while true: 
+    parseopt.next(p)
+    case p.kind
+    of cmdEnd: break 
+    of cmdLongOption, cmdShortOption: 
+      # hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
+      # we fix this here
+      var bracketLe = strutils.find(p.key, '[')
+      if bracketLe >= 0: 
+        var key = substr(p.key, 0, bracketLe - 1)
+        var val = substr(p.key, bracketLe + 1) & ':' & p.val
+        ProcessSwitch(key, val, pass, gCmdLineInfo)
+      else: 
+        ProcessSwitch(p.key, p.val, pass, gCmdLineInfo)
+    of cmdArgument:
+      if argsCount == 0:
+        options.command = p.key
+      else:
+        if pass == passCmd1: options.commandArgs.add p.key
+        if argsCount == 1:
+          # support UNIX style filenames anywhere for portable build scripts:
+          options.gProjectName = unixToNativePath(p.key)
+          arguments = cmdLineRest(p)
+          break
+      inc argsCount
+          
+  if pass == passCmd2:
+    if optRun notin gGlobalOptions and arguments != "":
+      rawMessage(errArgsNeedRunOption, [])
+
+proc serve*(action: proc (){.nimcall.}) =
+  var server = Socket()
+  let p = getConfigVar("server.port")
+  let port = if p.len > 0: parseInt(p).TPort else: 6000.TPort
+  server.bindAddr(port, getConfigVar("server.address"))
+  var inp = "".TaintedString
+  server.listen()
+  while true:
+    var client = InvalidSocket
+    accept(server, client)
+    discard client.recvLine(inp)
+    processCmdLine(passCmd2, inp.string)
+    action()
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index daecf44b8..d33f9a7bd 100755
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -18,6 +18,11 @@ const
   sectionContext = "con"
   sectionUsage = "use"
 
+proc SuggestWriteln(s: string) = 
+  if gSilence == 0: 
+    Writeln(stdout, s)
+    
+
 proc SymToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string = 
   result = section
   result.add(sep)
@@ -51,7 +56,7 @@ proc fieldVisible*(c: PContext, f: PSym): bool {.inline.} =
 
 proc suggestField(c: PContext, s: PSym, outputs: var int) = 
   if filterSym(s) and fieldVisible(c, s):
-    OutWriteln(SymToStr(s, isLocal=true, sectionSuggest))
+    SuggestWriteln(SymToStr(s, isLocal=true, sectionSuggest))
     inc outputs
 
 when not defined(nimhygiene):
@@ -62,7 +67,7 @@ template wholeSymTab(cond, section: expr) {.immediate.} =
     for item in items(c.tab.stack[i]):
       let it {.inject.} = item
       if cond:
-        OutWriteln(SymToStr(it, isLocal = i > ModuleTablePos, section))
+        SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, section))
         inc outputs
 
 proc suggestSymList(c: PContext, list: PNode, outputs: var int) = 
@@ -120,7 +125,7 @@ proc suggestEverything(c: PContext, n: PNode, outputs: var int) =
   for i in countdown(c.tab.tos-1, 1):
     for it in items(c.tab.stack[i]):
       if filterSym(it):
-        OutWriteln(SymToStr(it, isLocal = i > ModuleTablePos, sectionSuggest))
+        SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, sectionSuggest))
         inc outputs
 
 proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
@@ -134,12 +139,12 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
         # all symbols accessible, because we are in the current module:
         for it in items(c.tab.stack[ModuleTablePos]): 
           if filterSym(it): 
-            OutWriteln(SymToStr(it, isLocal=false, sectionSuggest))
+            SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest))
             inc outputs
       else: 
         for it in items(n.sym.tab): 
           if filterSym(it): 
-            OutWriteln(SymToStr(it, isLocal=false, sectionSuggest))
+            SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest))
             inc outputs
     else:
       # fallback:
@@ -224,15 +229,15 @@ var
 proc findUsages(node: PNode, s: PSym) =
   if usageSym == nil and isTracked(node.info, s.name.s.len):
     usageSym = s
-    OutWriteln(SymToStr(s, isLocal=false, sectionUsage))
+    SuggestWriteln(SymToStr(s, isLocal=false, sectionUsage))
   elif s == usageSym:
     if lastLineInfo != node.info:
-      OutWriteln(SymToStr(s, isLocal=false, sectionUsage, node.info))
+      SuggestWriteln(SymToStr(s, isLocal=false, sectionUsage, node.info))
     lastLineInfo = node.info
 
 proc findDefinition(node: PNode, s: PSym) =
   if isTracked(node.info, s.name.s.len):
-    OutWriteln(SymToStr(s, isLocal=false, sectionDef))
+    SuggestWriteln(SymToStr(s, isLocal=false, sectionDef))
     quit(0)
 
 proc suggestSym*(n: PNode, s: PSym) {.inline.} =
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 7b969c3bb..117d226a6 100755
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -159,6 +159,7 @@ Define               Effect
                      systems. See the documentation of the `gc <gc.html>`_ 
                      for further information.
 ``nodejs``           The EcmaScript target is actually ``node.js``.
+``ssl``              Enables OpenSSL support for the sockets module.
 ==================   =========================================================
 
 

diff --git a/doc/tut1.txt b/doc/tut1.txt
index 833d364df..c6e4edb82 100755
--- a/doc/tut1.txt
+++ b/doc/tut1.txt
@@ -16,10 +16,10 @@ Introduction
   </p></blockquote>
 
 
-This document is a tutorial for the programming language *Nimrod*. After this
-tutorial you will have a decent knowledge of Nimrod. This tutorial assumes
-that you are familiar with basic programming concepts like variables, types
-or statements.
+This document is a tutorial for the programming language *Nimrod*. 
+This tutorial assumes that you are familiar with basic programming concepts 
+like variables, types or statements but is kept very basic. The manual 
+contains many more examples of the advanced language features.
 
 
 
@@ -593,7 +593,7 @@ caller, a ``var`` parameter can be used:
 
 In the example, ``res`` and ``remainder`` are `var parameters`.
 Var parameters can be modified by the procedure and the changes are
-visible to the caller. Note that the above example would better make usage of
+visible to the caller. Note that the above example would better make use of
 a tuple as a return value instead of using var parameters.
 
 
diff --git a/doc/tut2.txt b/doc/tut2.txt
index 3882296be..149d444f0 100755
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -16,7 +16,9 @@ Introduction
 
 
 This document is a tutorial for the advanced constructs of the *Nimrod*
-programming language.
+programming language. **Note that this document is somewhat obsolete as
+the `manual <manual.html>`_ contains many more examples of the advanced 
+language features.**
 
 
 Pragmas
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 82755ca86..d6093c5b1 100755
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -729,7 +729,8 @@ template InstantiateForRegion(allocator: expr) =
     proc interiorAllocatedPtr*(p: pointer): pointer =
       result = interiorAllocatedPtr(allocator, p)
 
-    proc isAllocatedPtr*(p: pointer): bool = 
+    proc isAllocatedPtr*(p: pointer): bool =
+      let p = cast[pointer](cast[TAddress](p)-%TAddress(sizeof(TCell)))
       result = isAllocatedPtr(allocator, p)
 
   proc deallocOsPages = deallocOsPages(allocator)
diff --git a/packages/docutils/rst.nim b/packages/docutils/rst.nim
index 333ef11d9..debbd2520 100755
--- a/packages/docutils/rst.nim
+++ b/packages/docutils/rst.nim
@@ -818,7 +818,7 @@ proc getDirective(p: var TRstParser): string =
 proc parseComment(p: var TRstParser): PRstNode = 
   case p.tok[p.idx].kind
   of tkIndent, tkEof: 
-    if p.tok[p.idx + 1].kind == tkIndent: 
+    if p.tok[p.idx].kind != tkEof and p.tok[p.idx + 1].kind == tkIndent: 
       inc(p.idx)              # empty comment
     else: 
       var indent = p.tok[p.idx].ival
@@ -1348,9 +1348,20 @@ proc parseSectionWrapper(p: var TRstParser): PRstNode =
   while (result.kind == rnInner) and (len(result) == 1): 
     result = result.sons[0]
   
+proc `$`(t: TToken): string =
+  result = $t.kind & ' ' & (if isNil(t.symbol): "NIL" else: t.symbol)
+
 proc parseDoc(p: var TRstParser): PRstNode = 
   result = parseSectionWrapper(p)
-  if p.tok[p.idx].kind != tkEof: rstMessage(p, meGeneralParseError)
+  if p.tok[p.idx].kind != tkEof: 
+    when false:
+      assert isAllocatedPtr(cast[pointer](p.tok))
+      for i in 0 .. high(p.tok):
+        assert isNil(p.tok[i].symbol) or 
+               isAllocatedPtr(cast[pointer](p.tok[i].symbol))
+      echo "index: ", p.idx, " length: ", high(p.tok), "##",
+          p.tok[p.idx-1], p.tok[p.idx], p.tok[p.idx+1]
+    rstMessage(p, meGeneralParseError)
   
 type
   TDirFlag = enum
diff --git a/readme.txt b/readme.txt
index e2ac5c7c4..c4d3b2ba7 100755
--- a/readme.txt
+++ b/readme.txt
@@ -11,7 +11,7 @@ can be used to create domain specific languages.
 

 *Nimrod* is a compiled, garbage-collected systems programming language 

 which has an excellent productivity/performance ratio. Nimrod's design 

-focuses on the 3E: efficiency, expressiveness, elegance (in the order of 

+focuses on efficiency, expressiveness, elegance (in the order of 

 priority). 

 

 See the file ``install.txt`` for installation instructions. See the file

diff --git a/web/index.txt b/web/index.txt
index 26725ffe9..03f11ed49 100755
--- a/web/index.txt
+++ b/web/index.txt
@@ -8,23 +8,20 @@ Home
   -- D. E. Knuth
 
 
-**This page is about the Nimrod programming language, which combines Lisp's
-power with Python's readability and C's performance.**
+**Nimrod combines Lisp's power with Python's readability and C's performance.**
 
 Welcome to Nimrod
 -----------------
 
-**Nimrod** is a new statically typed, imperative
-programming language, that supports procedural, object oriented, functional 
-and generic programming styles while remaining simple and efficient. 
-A special feature that Nimrod inherited from Lisp is that Nimrod's abstract 
-syntax tree (*AST*) is part of the specification - this allows a powerful 
-macro system which allows domain specific languages.
-
-Nimrod is a compiled, garbage-collected systems programming language
-which has an excellent productivity/performance ratio. Nimrod's design
-focuses on the 3E: efficiency, expressiveness, elegance (in the order of
-priority).
+**Nimrod** is a statically typed, imperative programming language that tries to
+give the programmer ultimate power without compromises on runtime efficiency. 
+This means it focuses on compile-time mechanisms in all their
+various forms. Beneath a nice infix/indentation based syntax with a 
+powerful (AST based, hygienic) macro system lies a semantic model that supports 
+a soft realtime GC on thread local heaps. Asynchronous message passing is used 
+between threads, so no "stop the world" mechanism is necessary. An unsafe 
+shared memory heap is also provided for the increased efficiency that results 
+from that model.
 
 
 .. container:: snippet
@@ -33,7 +30,8 @@ priority).
   .. code-block:: nimrod
     import strutils
     
-    echo "Type in a list of ints of ints (separate by whitespace): "
+    # Prints the maximum integer from a list of integers
+    # delimited by whitespace read from stdin.
     let tokens = stdin.readLine.split
     echo tokens.each(parseInt).max, " is the maximum."
 
diff --git a/web/question.txt b/web/question.txt
index ffa26a364..46cbb4f88 100755
--- a/web/question.txt
+++ b/web/question.txt
@@ -9,13 +9,15 @@ General
 What is Nimrod?
 ---------------
 
-Nimrod is a new statically typed, imperative
-programming language, that supports procedural, functional, object oriented and
-generic programming styles while remaining simple and efficient. A special
-feature that Nimrod inherited from Lisp is that Nimrod's abstract syntax tree
-(*AST*) is part of the specification - this allows a powerful macro system which
-can be used to create domain specific languages. Nimrod does not sacrifice
-flexibility for speed. You get both.
+Nimrod is a statically typed, imperative programming language that tries to
+give the programmer ultimate power without compromises on runtime efficiency. 
+This means it focuses on compile-time mechanisms in all their
+various forms. Beneath a nice infix/indentation based syntax with a 
+powerful (AST based, hygienic) macro system lies a semantic model that supports 
+a soft realtime GC on thread local heaps. Asynchronous message passing is used 
+between threads, so no "stop the world" mechanism is necessary. An unsafe 
+shared memory heap is also provided for the increased efficiency that results 
+from that model.
 
 ..
   Don't give me that marketing crap. What is Nimrod?