summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/impure/rdstdin.nim4
-rwxr-xr-xrod/astalgo.nim13
-rwxr-xr-xrod/commands.nim19
-rwxr-xr-xrod/main.nim9
-rwxr-xr-xrod/msgs.nim9
-rwxr-xr-xrod/options.nim2
-rwxr-xr-xrod/procfind.nim9
-rwxr-xr-xrod/sem.nim2
-rwxr-xr-xrod/semexprs.nim2
-rwxr-xr-xrod/semstmts.nim2
-rwxr-xr-xrod/wordrecg.nim4
-rwxr-xr-xtodo.txt4
12 files changed, 54 insertions, 25 deletions
diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim
index a1f0291bf..003cfa3d1 100644
--- a/lib/impure/rdstdin.nim
+++ b/lib/impure/rdstdin.nim
@@ -32,5 +32,7 @@ else:
 
   # initialization:
   # disable auto-complete: 
-  discard readline.bind_key('\t'.ord, readline.abort) 
+  proc doNothing(a, b: cint): cint {.cdecl, procvar.} = nil
+  
+  discard readline.bind_key('\t'.ord, doNothing)
 
diff --git a/rod/astalgo.nim b/rod/astalgo.nim
index 3167f814b..9c9719b35 100755
--- a/rod/astalgo.nim
+++ b/rod/astalgo.nim
@@ -677,8 +677,19 @@ proc OpenScope(tab: var TSymTab) =
   Inc(tab.tos)
 
 proc RawCloseScope(tab: var TSymTab) = 
-  Dec(tab.tos)                #tab.stack[tab.tos] := nil;
+  Dec(tab.tos)
   
+iterator items*(tab: TStrTable): PSym = 
+  var it: TTabIter
+  var s = InitTabIter(it, tab)
+  while s != nil: 
+    yield s
+    s = NextIter(it, tab)
+
+iterator items*(tab: TSymTab): PSym = 
+  for i in countdown(tab.tos-1, 0): 
+    for it in items(tab.stack[i]): yield it
+
 proc hasEmptySlot(data: TIdPairSeq): bool = 
   for h in countup(0, high(data)): 
     if data[h].key == nil: 
diff --git a/rod/commands.nim b/rod/commands.nim
index 3ecf8f0e3..315e9798a 100755
--- a/rod/commands.nim
+++ b/rod/commands.nim
@@ -11,7 +11,7 @@
 
 import 
   os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists, 
-  wordrecg
+  wordrecg, parseutils
 
 proc writeCommandLineUsage*()
 
@@ -78,7 +78,8 @@ Advanced commands:
                             module dependency graph
   listDef                   list all defined conditionals and exit
   check                     checks the project for syntax and semantic
-  parse                     parses a single file (for debugging Nimrod)
+  suggest                   list all possible symbols at position; 
+                            use with --track option
 Advanced options:
   -w, --warnings:on|off     turn all warnings on|off
   --warning[X]:on|off       turn specific warning X on|off
@@ -105,6 +106,7 @@ Advanced options:
   --gc:refc|boehm|none      use Nimrod's native GC|Boehm GC|no GC
   --index:FILE              use FILE to generate a documenation index file
   --putenv:key=value        set an environment variable
+  --track:FILE,LINE,COLUMN  track a file position for 'suggest'
   --listCmd                 list the commands used to execute external programs
   --parallelBuild=0|1|...   perform a parallel build
                             value = number of processors (0 for auto-detect)
@@ -289,6 +291,16 @@ proc addPathRec(dir: string, info: TLineInfo) =
         Message(info, hintPath, p)
         lists.PrependStr(options.searchPaths, p)
 
+proc track(arg: string, info: TLineInfo) = 
+  var a = arg.split(',')
+  if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLMUN")
+  var line, column: int
+  if parseUtils.parseInt(a[1], line) <= 0:
+    LocalError(info, errInvalidNumber, a[1])
+  if parseUtils.parseInt(a[2], column) <= 0:
+    LocalError(info, errInvalidNumber, a[2])
+  msgs.addCheckpoint(newLineInfo(a[0], line, column))
+
 proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = 
   var 
     theOS: TSystemOS
@@ -481,6 +493,9 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
   of wCC: 
     expectArg(switch, arg, pass, info)
     setCC(arg)
+  of wTrack:
+    expectArg(switch, arg, pass, info)
+    track(arg, info)
   else: 
     if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
     else: InvalidCmdLineOption(pass, switch, info)
diff --git a/rod/main.nim b/rod/main.nim
index f413a03ef..b6f20d7c4 100755
--- a/rod/main.nim
+++ b/rod/main.nim
@@ -176,6 +176,11 @@ proc CommandScan(filename: string) =
   else: 
     rawMessage(errCannotOpenFile, f)
   
+proc CommandSuggest(filename: string) = 
+  msgs.gErrorMax = high(int)  # do not stop after first error
+  semanticPasses()
+  compileProject(filename)
+
 proc WantFile(filename: string) = 
   if filename == "": 
     Fatal(newLineInfo("command line", 1, 1), errCommandExpectsFilename)
@@ -265,5 +270,9 @@ proc MainCommand(cmd, filename: string) =
   of wI: 
     gCmd = cmdInteractive
     CommandInteractive()
+  of wSuggest:
+    gCmd = cmdSuggest
+    wantFile(filename)
+    CommandSuggest(filename)
   else: rawMessage(errInvalidCommandX, cmd)
   
diff --git a/rod/msgs.nim b/rod/msgs.nim
index a34542c8d..69e260d41 100755
--- a/rod/msgs.nim
+++ b/rod/msgs.nim
@@ -430,11 +430,6 @@ proc ToLinenumber*(info: TLineInfo): int =
 proc toColumn*(info: TLineInfo): int = 
   result = info.col
 
-proc checkpoint*(info: TLineInfo, filename: string, line: int): bool = 
-  result = (int(info.line) == line) and
-      (ChangeFileExt(extractFilename(filenames[info.fileIndex]), "") ==
-      filename)
-
 var checkPoints: seq[TLineInfo] = @[]
 
 proc addCheckpoint*(info: TLineInfo) = 
@@ -461,13 +456,9 @@ proc getMessageStr(msg: TMsgKind, arg: string): string =
 proc inCheckpoint*(current: TLineInfo): bool = 
   ## prints the line information if in checkpoint
   result = false
-  if not (optCheckpoints in gOptions): 
-    return                    # ignore all checkpoints
   for i in countup(0, high(checkPoints)): 
     if (current.line == checkPoints[i].line) and
         (current.fileIndex == (checkPoints[i].fileIndex)): 
-      MessageOut(`%`("$1($2, $3) Checkpoint: ", [toFilename(current), 
-          coordToStr(current.line), coordToStr(current.col)]))
       return true
 
 type
diff --git a/rod/options.nim b/rod/options.nim
index 16ff536bd..b2bf7fed9 100755
--- a/rod/options.nim
+++ b/rod/options.nim
@@ -50,7 +50,7 @@ type                          # please make sure we have under 32 options
     cmdGenDepend, cmdListDef, cmdCheck, # semantic checking for whole project
     cmdParse,                 # parse a single file (for debugging)
     cmdScan,                  # scan a single file (for debugging)
-    cmdDebugTrans,            # debug a transformation pass
+    cmdSuggest,               # suggest feature (auto-completion for IDEs)
     cmdRst2html,              # convert a reStructuredText file to HTML
     cmdRst2tex,               # convert a reStructuredText file to TeX
     cmdInteractive,           # start interactive session
diff --git a/rod/procfind.nim b/rod/procfind.nim
index 2bfa27494..30455c4c6 100755
--- a/rod/procfind.nim
+++ b/rod/procfind.nim
@@ -57,15 +57,12 @@ proc SearchForProc(c: PContext, fn: PSym, tos: int): PSym =
     result = NextIdentIter(it, c.tab.stack[tos])
 
 proc paramsFitBorrow(a, b: PNode): bool = 
-  var 
-    length: int
-    m, n: PSym
-  length = sonsLen(a)
+  var length = sonsLen(a)
   result = false
   if length == sonsLen(b): 
     for i in countup(1, length - 1): 
-      m = a.sons[i].sym
-      n = b.sons[i].sym
+      var m = a.sons[i].sym
+      var n = b.sons[i].sym
       assert((m.kind == skParam) and (n.kind == skParam))
       if not equalOrDistinctOf(m.typ, n.typ): return 
     if not equalOrDistinctOf(a.sons[0].typ, b.sons[0].typ): return 
diff --git a/rod/sem.nim b/rod/sem.nim
index 1e6ec9080..0518dc423 100755
--- a/rod/sem.nim
+++ b/rod/sem.nim
@@ -13,7 +13,7 @@ import
   strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab, 
   wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math, 
   magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer, 
-  procfind, lookups, rodread, pragmas, passes
+  procfind, lookups, rodread, pragmas, passes, suggest
 
 proc semPass*(): TPass
 # implementation
diff --git a/rod/semexprs.nim b/rod/semexprs.nim
index 064df0ded..58c358021 100755
--- a/rod/semexprs.nim
+++ b/rod/semexprs.nim
@@ -955,6 +955,8 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode =
   
 proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = 
   result = n
+  if gCmd == cmdSuggest: 
+    suggestExpr(c, n)
   if nfSem in n.flags: return 
   case n.kind                 # atoms:
   of nkIdent: 
diff --git a/rod/semstmts.nim b/rod/semstmts.nim
index c931c8102..eb4a51b51 100755
--- a/rod/semstmts.nim
+++ b/rod/semstmts.nim
@@ -792,6 +792,8 @@ proc SemStmt(c: PContext, n: PNode): PNode =
   const                       # must be last statements in a block:
     LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
   result = n
+  if gCmd == cmdSuggest: 
+    suggestStmt(c, n)
   if nfSem in n.flags: return 
   case n.kind
   of nkAsgn: result = semAsgn(c, n)
diff --git a/rod/wordrecg.nim b/rod/wordrecg.nim
index d4bbb8680..44ef00607 100755
--- a/rod/wordrecg.nim
+++ b/rod/wordrecg.nim
@@ -60,7 +60,7 @@ type
     wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wJs, wOC, 
     wRst2html, wRst2tex, wI,
     wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar, wEmit, wThreads,
-    wRecursivePath
+    wRecursivePath, wSuggest, wTrack
     
   TSpecialWords* = set[TSpecialWord]
 
@@ -109,7 +109,7 @@ const
     "pretty", "doc", "gendepend", "listdef", "check", "parse", "scan", 
     "js", "oc", "rst2html", "rst2tex", "i", 
     "write", "putenv", "prependenv", "appendenv", "threadvar", "emit",
-    "threads", "recursivepath"]
+    "threads", "recursivepath", "suggest", "track"]
 
 proc whichKeyword*(id: PIdent): TSpecialWord
 proc whichKeyword*(id: String): TSpecialWord
diff --git a/todo.txt b/todo.txt
index 4dfc05312..d7a3e4516 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,5 +1,5 @@
-- 'suggest'
-- Bug: var x = 89; float(x)
+- 'suggest' needs tweaking: more places in the semantic checking
+   need to take it into account
 
 - thread support: threadvar on Windows seems broken; 
   add --deadlock_prevention:on|off switch