diff options
author | Araq <rumpf_a@web.de> | 2012-11-01 01:11:48 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-11-01 01:11:48 +0100 |
commit | 42d0911d6a1daa60cfe0dcd2cf8c403083f6ca65 (patch) | |
tree | 725312d68f74d603a2cdd28642c90d87246fb143 | |
parent | faed98d21573feec1beceb9149eab249cc44a6f4 (diff) | |
download | Nim-42d0911d6a1daa60cfe0dcd2cf8c403083f6ca65.tar.gz |
nimbuild should work again
-rwxr-xr-x | build.bat | 2 | ||||
-rw-r--r-- | build64.bat | 2 | ||||
-rwxr-xr-x | compiler/nimrod.ini | 2 | ||||
-rwxr-xr-x | compiler/pragmas.nim | 28 | ||||
-rwxr-xr-x | compiler/sem.nim | 1 | ||||
-rwxr-xr-x | compiler/semdata.nim | 1 | ||||
-rw-r--r-- | compiler/sempass2.nim | 91 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 1 | ||||
-rwxr-xr-x | lib/pure/sockets.nim | 6 | ||||
-rwxr-xr-x | lib/system.nim | 1 | ||||
-rwxr-xr-x | tools/niminst/buildsh.tmpl | 2 |
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" |