summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-11-01 01:11:48 +0100
committerAraq <rumpf_a@web.de>2012-11-01 01:11:48 +0100
commit42d0911d6a1daa60cfe0dcd2cf8c403083f6ca65 (patch)
tree725312d68f74d603a2cdd28642c90d87246fb143
parentfaed98d21573feec1beceb9149eab249cc44a6f4 (diff)
downloadNim-42d0911d6a1daa60cfe0dcd2cf8c403083f6ca65.tar.gz
nimbuild should work again
-rwxr-xr-xbuild.bat2
-rw-r--r--build64.bat2
-rwxr-xr-xcompiler/nimrod.ini2
-rwxr-xr-xcompiler/pragmas.nim28
-rwxr-xr-xcompiler/sem.nim1
-rwxr-xr-xcompiler/semdata.nim1
-rw-r--r--compiler/sempass2.nim91
-rwxr-xr-xcompiler/semstmts.nim1
-rwxr-xr-xlib/pure/sockets.nim6
-rwxr-xr-xlib/system.nim1
-rwxr-xr-xtools/niminst/buildsh.tmpl2
11 files changed, 106 insertions, 31 deletions
diff --git a/build.bat b/build.bat
index 6582f957c..2795fe5cb 100755
--- a/build.bat
+++ b/build.bat
@@ -3,7 +3,7 @@ REM Generated by niminst
 SET CC=gcc

 SET LINKER=gcc

 SET COMP_FLAGS=-w -O3 -fno-strict-aliasing

-SET LINK_FLAGS=-lsocket -lnsl

+SET LINK_FLAGS=

 

 REM call the compiler:

 

diff --git a/build64.bat b/build64.bat
index 97dfefdc5..5e7f98260 100644
--- a/build64.bat
+++ b/build64.bat
@@ -3,7 +3,7 @@ REM Generated by niminst
 SET CC=gcc

 SET LINKER=gcc

 SET COMP_FLAGS=-w -O3 -fno-strict-aliasing

-SET LINK_FLAGS=-lsocket -lnsl

+SET LINK_FLAGS=

 

 REM call the compiler:

 

diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini
index 3f820e505..ea98c743b 100755
--- a/compiler/nimrod.ini
+++ b/compiler/nimrod.ini
@@ -2,7 +2,7 @@
 Name: "Nimrod"
 Version: "$version"
 ; Windows and i386 must be first!
-OS: "windows;linux;macosx;freebsd;netbsd;openbsd;solaris"
+OS: "windows;linux;macosx;solaris;freebsd;netbsd;openbsd"
 CPU: "i386;amd64;powerpc64;arm"  # ;sparc
 Authors: "Andreas Rumpf"
 Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index e5854d93d..65574e80e 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -12,7 +12,7 @@
 import 
   os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer, 
   wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees,
-  rodread
+  rodread, types
 
 const 
   FirstCallConv* = wNimcall
@@ -24,7 +24,7 @@ const
     wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, 
     wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
     wNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wHoist,
-    wGenSym, wInject}
+    wGenSym, wInject, wRaises}
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas
   templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty}
@@ -33,7 +33,7 @@ const
     wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject}
   iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect, 
     wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
-    wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject}
+    wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject, wRaises}
   exprPragmas* = {wLine}
   stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
     wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
@@ -44,7 +44,8 @@ const
     wLinearScanEnd, wPatterns, wEffects}
   lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, 
-    wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame}
+    wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame,
+    wRaises}
   typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, 
     wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow, 
     wImportcpp, wImportobjc, wError, wIncompleteStruct, wByCopy, wByRef,
@@ -59,7 +60,7 @@ const
     wExtern, wImportcpp, wImportobjc, wError, wGenSym, wInject}
   letPragmas* = varPragmas
   procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect,
-                      wThread}
+                      wThread, wRaises}
   allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
 
 proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
@@ -463,6 +464,22 @@ proc processPragma(c: PContext, n: PNode, i: int) =
   userPragma.ast = body
   StrTableAdd(c.userPragmas, userPragma)
 
+proc pragmaRaises(c: PContext, n: PNode) =
+  proc processExc(c: PContext, x: PNode) =
+    var t = skipTypes(c.semTypeNode(c, x, nil), skipPtrs)
+    if t.kind != tyObject:
+      localError(x.info, errGenerated, "invalid exception type")
+    x.typ = t
+    
+  if n.kind == nkExprColonExpr:
+    let it = n.sons[1]
+    if it.kind notin {nkCurly, nkBracket}:
+      processExc(c, it)
+    else:
+      for e in items(it): processExc(c, e)
+  else:
+    invalidPragma(n)
+
 proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
   if n == nil: return
   for i in countup(0, sonsLen(n) - 1): 
@@ -679,6 +696,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
             noVal(it)
             if sym == nil: invalidPragma(it)
           of wLine: PragmaLine(c, it)
+          of wRaises: pragmaRaises(c, it)
           else: invalidPragma(it)
         else: invalidPragma(it)
     else: processNote(c, it)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 21bbdf4d2..93d023806 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -208,6 +208,7 @@ proc myOpen(module: PSym, filename: string): PPassContext =
   c.semExpr = semExprNoFlags
   c.semConstBoolExpr = semConstBoolExpr
   c.semOverloadedCall = semOverloadedCall
+  c.semTypeNode = semTypeNode
   pushProcCon(c, module)
   pushOwner(c.module)
   openScope(c.tab)            # scope for imported symbols
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index fe6f43f44..57721bdc0 100755
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -78,6 +78,7 @@ type
     semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
     semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
                               filter: TSymKinds): PNode {.nimcall.}
+    semTypeNode*: proc(c: PContext, n: PNode, prev: PType): PType {.nimcall.}
     includedFiles*: TIntSet    # used to detect recursive include files
     filename*: string          # the module's filename
     userPragmas*: TStrTable
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index bdc4e7028..89d8d45d8 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -8,7 +8,8 @@
 #
 
 import
-  ast, astalgo, msgs, renderer, magicsys, types, idents, trees, wordrecg
+  intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, 
+  wordrecg
 
 # Second semantic checking pass over the AST. Necessary because the old
 # way had some inherent problems. Performs:
@@ -48,8 +49,6 @@ when false:
   proc sem2call(c: PContext, n: PNode): PNode =
     assert n.kind in nkCallKinds
     
-    
-
   proc sem2sym(c: PContext, n: PNode): PNode =
     assert n.kind == nkSym
   
@@ -97,16 +96,17 @@ proc excType(n: PNode): PType =
           else: n.sons[0].typ
   result = skipTypes(t, skipPtrs)
 
-proc addEffect(a: PEffects, e: PNode) =
+proc addEffect(a: PEffects, e: PNode, useLineInfo=true) =
   assert e.kind == nkRaiseStmt
   var aa = a.exc
   for i in a.bottom .. <aa.len:
-    if sameType(aa[i].excType, e.excType) and aa[i].info == e.info: return
+    if sameType(aa[i].excType, e.excType):
+      if not useLineInfo: return
+      elif aa[i].info == e.info: return
   throws(a, e)
 
-proc mergeEffects(a: PEffects, b: PNode) =
-  for effect in items(b):
-    addEffect(a, effect)
+proc mergeEffects(a: PEffects, b: PNode, useLineInfo) =
+  for effect in items(b): addEffect(a, effect, useLineInfo)
 
 proc listEffects(a: PEffects) =
   var aa = a.exc
@@ -118,12 +118,13 @@ proc catches(tracked: PEffects, e: PType) =
   var L = tracked.exc.len
   var i = tracked.bottom
   while i < L:
-    # e supertype of r?
-    if inheritanceDiff(e, tracked.exc[i].excType) <= 0:
+    # r supertype of e?
+    if inheritanceDiff(tracked.exc[i].excType, e) <= 0:
       tracked.exc.sons[i] = tracked.exc.sons[L-1]
       dec L
     else:
       inc i
+  setLen(tracked.exc.sons, L)
   
 proc catchesAll(tracked: PEffects) =
   setLen(tracked.exc.sons, tracked.bottom)
@@ -161,6 +162,20 @@ proc trackPragmaStmt(tracked: PEffects, n: PNode) =
       # list the computed effects up to here:
       listEffects(tracked)
 
+proc raisesSpec(n: PNode): PNode =
+  for i in countup(0, sonsLen(n) - 1):
+    var it = n.sons[i]
+    if it.kind == nkExprColonExpr and whichPragma(it) == wRaises:
+      result = it.sons[1]
+      if result.kind notin {nkCurly, nkBracket}:
+        result = newNodeI(nkCurly, result.info)
+        result.add(it.sons[1])
+      return
+
+proc createRaise(n: PNode, t: PType): PNode =
+  result = newNodeI(nkRaiseStmt, n.info)
+  result.add(newNodeIT(nkType, n.info, t))
+
 proc track(tracked: PEffects, n: PNode) =
   case n.kind
   of nkRaiseStmt: throws(tracked, n)
@@ -168,18 +183,20 @@ proc track(tracked: PEffects, n: PNode) =
     # p's effects are ours too:
     let op = n.sons[0].typ
     if op != nil and op.kind == tyProc:
-      InternalAssert op.kind == tyProc and op.n.sons[0].kind == nkEffectList
+      InternalAssert op.n.sons[0].kind == nkEffectList
       var effectList = op.n.sons[0]
       if effectList.len == 0:
-        if isIndirectCall(n.sons[0]) or isForwardedProc(n.sons[0]):
-          # assume the worst: raise of exception 'E_Base':
-          var rs = newNodeI(nkRaiseStmt, n.info)
-          var re = newNodeIT(nkType, n.info, sysTypeFromName"E_Base")
-          rs.add(re)
-          addEffect(tracked, rs)
+        if isForwardedProc(n.sons[0]):
+          let spec = raisesSpec(n.sons[0].sym.ast.sons[pragmasPos])
+          if not isNil(spec):
+            mergeEffects(tracked, spec, useLineInfo=false)
+          else:
+            addEffect(tracked, createRaise(n, sysTypeFromName"E_Base"))
+        elif isIndirectCall(n.sons[0]):
+          addEffect(tracked, createRaise(n, sysTypeFromName"E_Base"))
       else:
         effectList = effectList.sons[exceptionEffects]
-        mergeEffects(tracked, effectList)
+        mergeEffects(tracked, effectList, useLineInfo=true)
   of nkTryStmt:
     trackTryStmt(tracked, n)
     return
@@ -191,10 +208,45 @@ proc track(tracked: PEffects, n: PNode) =
   for i in 0 .. <safeLen(n):
     track(tracked, n.sons[i])
 
+# XXX
+# - make use of 'raises' in proc types compatibility
+# - check for 'raises' consistency for multi-methods
+
+proc checkRaisesSpec(spec, real: PNode) =
+  # check that any real exception is listed in 'spec'; mark those as used;
+  # report any unused exception
+  var used = initIntSet()
+  for r in items(real):
+    block search:
+      for s in 0 .. <spec.len:
+        # r supertype of s?
+        if inheritanceDiff(r.excType, spec[s].typ) <= 0:
+          used.incl(s)
+          break search
+      # XXX call graph analysis would be nice here!
+      localError(r.info, errGenerated, "can raise an unlisted exception: " &
+        typeToString(r.sons[0].typ))
+  # hint about unnecessarily listed exception types:
+  for s in 0 .. <spec.len:
+    if not used.contains(s):
+      Message(spec[s].info, hintXDeclaredButNotUsed, renderTree(spec[s]))
+
+proc compatibleEffects*(formal, actual: PType): bool =
+  # for proc type compatibility checking:
+  assert formal.kind == tyProc and actual.kind == tyProc
+  InternalAssert formal.n.sons[0].kind == nkEffectList
+  InternalAssert actual.n.sons[0].kind == nkEffectList
+  
+  var effectList = formal.n.sons[0]
+  if effectList.len == 0:
+    # 'formal' has no restrictions :-)
+    result = true
+
 proc trackProc*(s: PSym, body: PNode) =
   var effects = s.typ.n.sons[0]
   InternalAssert effects.kind == nkEffectList
   # effects already computed?
+  if sfForward in s.flags: return
   if effects.len == effectListLen: return
   newSeq(effects.sons, effectListLen)
   effects.sons[exceptionEffects] = newNodeI(nkArgList, body.info)
@@ -203,3 +255,6 @@ proc trackProc*(s: PSym, body: PNode) =
   t.exc = effects.sons[exceptionEffects]
   track(t, body)
   
+  let spec = raisesSpec(s.ast.sons[pragmasPos])
+  if not isNil(spec):
+    checkRaisesSpec(spec, t.exc)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 2cc28437d..586270277 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -765,6 +765,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     s = proto
     n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos]
     n.sons[paramsPos] = proto.ast.sons[paramsPos]
+    n.sons[pragmasPos] = proto.ast.sons[pragmasPos]
     if n.sons[namePos].kind != nkSym: InternalError(n.info, "semProcAux")
     n.sons[namePos].sym = proto
     proto.ast = n             # needed for code generation
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim
index f0d4cb6b8..10af213f4 100755
--- a/lib/pure/sockets.nim
+++ b/lib/pure/sockets.nim
@@ -14,6 +14,9 @@
 ## For OpenSSL support compile with ``-d:ssl``. When using SSL be aware that
 ## most functions will then raise ``ESSL`` on SSL errors.
 
+when hostos == "solaris":
+  {.passl: "-lsocket -lnsl".}
+
 import os, parseutils
 from times import epochTime
 
@@ -24,9 +27,6 @@ when defined(Windows):
   import winlean
 else:
   import posix
-  
-  when defined(solaris):
-    {.passl: "-lsocket -lnsl".}
 
 # Note: The enumerations are mapped to Window's constants.
 
diff --git a/lib/system.nim b/lib/system.nim
index 4a1bde56a..9caf38614 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1671,7 +1671,6 @@ proc debugEcho*[T](x: varargs[T, `$`]) {.magic: "Echo", noSideEffect.}
 template newException*(exceptn: typeDesc, message: string): expr =
   ## creates an exception object of type ``exceptn`` and sets its ``msg`` field
   ## to `message`. Returns the new exception object.
-  # block: # open a new scope
   var
     e: ref exceptn
   new(e)
diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl
index 70f21a691..60a06c93f 100755
--- a/tools/niminst/buildsh.tmpl
+++ b/tools/niminst/buildsh.tmpl
@@ -69,7 +69,7 @@ case $uos in
     ;;
   *solaris* | *sun* ) 
     myos="solaris"
-    LINK_FLAGS="$LINK_FLAGS -ldl -lm"
+    LINK_FLAGS="$LINK_FLAGS -ldl -lm -lsocket -lnsl"
     ;;
   *haiku* )
     myos="haiku"