nimbuild should work again

This commit is contained in:
Araq 2012-11-01 01:11:48 +01:00
commit 42d0911d6a
11 changed files with 106 additions and 31 deletions

View file

@ -3,7 +3,7 @@ REM Generated by niminst
SET CC=gcc SET CC=gcc
SET LINKER=gcc SET LINKER=gcc
SET COMP_FLAGS=-w -O3 -fno-strict-aliasing SET COMP_FLAGS=-w -O3 -fno-strict-aliasing
SET LINK_FLAGS=-lsocket -lnsl SET LINK_FLAGS=
REM call the compiler: REM call the compiler:

View file

@ -3,7 +3,7 @@ REM Generated by niminst
SET CC=gcc SET CC=gcc
SET LINKER=gcc SET LINKER=gcc
SET COMP_FLAGS=-w -O3 -fno-strict-aliasing SET COMP_FLAGS=-w -O3 -fno-strict-aliasing
SET LINK_FLAGS=-lsocket -lnsl SET LINK_FLAGS=
REM call the compiler: REM call the compiler:

View file

@ -2,7 +2,7 @@
Name: "Nimrod" Name: "Nimrod"
Version: "$version" Version: "$version"
; Windows and i386 must be first! ; 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 CPU: "i386;amd64;powerpc64;arm" # ;sparc
Authors: "Andreas Rumpf" Authors: "Andreas Rumpf"
Description: """This is the Nimrod Compiler. Nimrod is a new statically typed, Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,

View file

@ -12,7 +12,7 @@
import import
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer, os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer,
wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees, wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees,
rodread rodread, types
const const
FirstCallConv* = wNimcall FirstCallConv* = wNimcall
@ -24,7 +24,7 @@ const
wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
wNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wHoist, wNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wHoist,
wGenSym, wInject} wGenSym, wInject, wRaises}
converterPragmas* = procPragmas converterPragmas* = procPragmas
methodPragmas* = procPragmas methodPragmas* = procPragmas
templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty} templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty}
@ -33,7 +33,7 @@ const
wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject} wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject}
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect, iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect,
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern, wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject} wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject, wRaises}
exprPragmas* = {wLine} exprPragmas* = {wLine}
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
@ -44,7 +44,8 @@ const
wLinearScanEnd, wPatterns, wEffects} wLinearScanEnd, wPatterns, wEffects}
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, 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, typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow, wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow,
wImportcpp, wImportobjc, wError, wIncompleteStruct, wByCopy, wByRef, wImportcpp, wImportobjc, wError, wIncompleteStruct, wByCopy, wByRef,
@ -59,7 +60,7 @@ const
wExtern, wImportcpp, wImportobjc, wError, wGenSym, wInject} wExtern, wImportcpp, wImportobjc, wError, wGenSym, wInject}
letPragmas* = varPragmas letPragmas* = varPragmas
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect, procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect,
wThread} wThread, wRaises}
allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) 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 userPragma.ast = body
StrTableAdd(c.userPragmas, userPragma) 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) = proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
if n == nil: return if n == nil: return
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
@ -679,6 +696,7 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
noVal(it) noVal(it)
if sym == nil: invalidPragma(it) if sym == nil: invalidPragma(it)
of wLine: PragmaLine(c, it) of wLine: PragmaLine(c, it)
of wRaises: pragmaRaises(c, it)
else: invalidPragma(it) else: invalidPragma(it)
else: invalidPragma(it) else: invalidPragma(it)
else: processNote(c, it) else: processNote(c, it)

View file

@ -208,6 +208,7 @@ proc myOpen(module: PSym, filename: string): PPassContext =
c.semExpr = semExprNoFlags c.semExpr = semExprNoFlags
c.semConstBoolExpr = semConstBoolExpr c.semConstBoolExpr = semConstBoolExpr
c.semOverloadedCall = semOverloadedCall c.semOverloadedCall = semOverloadedCall
c.semTypeNode = semTypeNode
pushProcCon(c, module) pushProcCon(c, module)
pushOwner(c.module) pushOwner(c.module)
openScope(c.tab) # scope for imported symbols openScope(c.tab) # scope for imported symbols

View file

@ -78,6 +78,7 @@ type
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
semOverloadedCall*: proc (c: PContext, n, nOrig: PNode, semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
filter: TSymKinds): PNode {.nimcall.} filter: TSymKinds): PNode {.nimcall.}
semTypeNode*: proc(c: PContext, n: PNode, prev: PType): PType {.nimcall.}
includedFiles*: TIntSet # used to detect recursive include files includedFiles*: TIntSet # used to detect recursive include files
filename*: string # the module's filename filename*: string # the module's filename
userPragmas*: TStrTable userPragmas*: TStrTable

View file

@ -8,7 +8,8 @@
# #
import 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 # Second semantic checking pass over the AST. Necessary because the old
# way had some inherent problems. Performs: # way had some inherent problems. Performs:
@ -48,8 +49,6 @@ when false:
proc sem2call(c: PContext, n: PNode): PNode = proc sem2call(c: PContext, n: PNode): PNode =
assert n.kind in nkCallKinds assert n.kind in nkCallKinds
proc sem2sym(c: PContext, n: PNode): PNode = proc sem2sym(c: PContext, n: PNode): PNode =
assert n.kind == nkSym assert n.kind == nkSym
@ -97,16 +96,17 @@ proc excType(n: PNode): PType =
else: n.sons[0].typ else: n.sons[0].typ
result = skipTypes(t, skipPtrs) result = skipTypes(t, skipPtrs)
proc addEffect(a: PEffects, e: PNode) = proc addEffect(a: PEffects, e: PNode, useLineInfo=true) =
assert e.kind == nkRaiseStmt assert e.kind == nkRaiseStmt
var aa = a.exc var aa = a.exc
for i in a.bottom .. <aa.len: 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) throws(a, e)
proc mergeEffects(a: PEffects, b: PNode) = proc mergeEffects(a: PEffects, b: PNode, useLineInfo) =
for effect in items(b): for effect in items(b): addEffect(a, effect, useLineInfo)
addEffect(a, effect)
proc listEffects(a: PEffects) = proc listEffects(a: PEffects) =
var aa = a.exc var aa = a.exc
@ -118,12 +118,13 @@ proc catches(tracked: PEffects, e: PType) =
var L = tracked.exc.len var L = tracked.exc.len
var i = tracked.bottom var i = tracked.bottom
while i < L: while i < L:
# e supertype of r? # r supertype of e?
if inheritanceDiff(e, tracked.exc[i].excType) <= 0: if inheritanceDiff(tracked.exc[i].excType, e) <= 0:
tracked.exc.sons[i] = tracked.exc.sons[L-1] tracked.exc.sons[i] = tracked.exc.sons[L-1]
dec L dec L
else: else:
inc i inc i
setLen(tracked.exc.sons, L)
proc catchesAll(tracked: PEffects) = proc catchesAll(tracked: PEffects) =
setLen(tracked.exc.sons, tracked.bottom) setLen(tracked.exc.sons, tracked.bottom)
@ -161,6 +162,20 @@ proc trackPragmaStmt(tracked: PEffects, n: PNode) =
# list the computed effects up to here: # list the computed effects up to here:
listEffects(tracked) 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) = proc track(tracked: PEffects, n: PNode) =
case n.kind case n.kind
of nkRaiseStmt: throws(tracked, n) of nkRaiseStmt: throws(tracked, n)
@ -168,18 +183,20 @@ proc track(tracked: PEffects, n: PNode) =
# p's effects are ours too: # p's effects are ours too:
let op = n.sons[0].typ let op = n.sons[0].typ
if op != nil and op.kind == tyProc: 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] var effectList = op.n.sons[0]
if effectList.len == 0: if effectList.len == 0:
if isIndirectCall(n.sons[0]) or isForwardedProc(n.sons[0]): if isForwardedProc(n.sons[0]):
# assume the worst: raise of exception 'E_Base': let spec = raisesSpec(n.sons[0].sym.ast.sons[pragmasPos])
var rs = newNodeI(nkRaiseStmt, n.info) if not isNil(spec):
var re = newNodeIT(nkType, n.info, sysTypeFromName"E_Base") mergeEffects(tracked, spec, useLineInfo=false)
rs.add(re) else:
addEffect(tracked, rs) addEffect(tracked, createRaise(n, sysTypeFromName"E_Base"))
elif isIndirectCall(n.sons[0]):
addEffect(tracked, createRaise(n, sysTypeFromName"E_Base"))
else: else:
effectList = effectList.sons[exceptionEffects] effectList = effectList.sons[exceptionEffects]
mergeEffects(tracked, effectList) mergeEffects(tracked, effectList, useLineInfo=true)
of nkTryStmt: of nkTryStmt:
trackTryStmt(tracked, n) trackTryStmt(tracked, n)
return return
@ -191,10 +208,45 @@ proc track(tracked: PEffects, n: PNode) =
for i in 0 .. <safeLen(n): for i in 0 .. <safeLen(n):
track(tracked, n.sons[i]) 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) = proc trackProc*(s: PSym, body: PNode) =
var effects = s.typ.n.sons[0] var effects = s.typ.n.sons[0]
InternalAssert effects.kind == nkEffectList InternalAssert effects.kind == nkEffectList
# effects already computed? # effects already computed?
if sfForward in s.flags: return
if effects.len == effectListLen: return if effects.len == effectListLen: return
newSeq(effects.sons, effectListLen) newSeq(effects.sons, effectListLen)
effects.sons[exceptionEffects] = newNodeI(nkArgList, body.info) effects.sons[exceptionEffects] = newNodeI(nkArgList, body.info)
@ -203,3 +255,6 @@ proc trackProc*(s: PSym, body: PNode) =
t.exc = effects.sons[exceptionEffects] t.exc = effects.sons[exceptionEffects]
track(t, body) track(t, body)
let spec = raisesSpec(s.ast.sons[pragmasPos])
if not isNil(spec):
checkRaisesSpec(spec, t.exc)

View file

@ -765,6 +765,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
s = proto s = proto
n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos] n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos]
n.sons[paramsPos] = proto.ast.sons[paramsPos] n.sons[paramsPos] = proto.ast.sons[paramsPos]
n.sons[pragmasPos] = proto.ast.sons[pragmasPos]
if n.sons[namePos].kind != nkSym: InternalError(n.info, "semProcAux") if n.sons[namePos].kind != nkSym: InternalError(n.info, "semProcAux")
n.sons[namePos].sym = proto n.sons[namePos].sym = proto
proto.ast = n # needed for code generation proto.ast = n # needed for code generation

View file

@ -14,6 +14,9 @@
## For OpenSSL support compile with ``-d:ssl``. When using SSL be aware that ## For OpenSSL support compile with ``-d:ssl``. When using SSL be aware that
## most functions will then raise ``ESSL`` on SSL errors. ## most functions will then raise ``ESSL`` on SSL errors.
when hostos == "solaris":
{.passl: "-lsocket -lnsl".}
import os, parseutils import os, parseutils
from times import epochTime from times import epochTime
@ -25,9 +28,6 @@ when defined(Windows):
else: else:
import posix import posix
when defined(solaris):
{.passl: "-lsocket -lnsl".}
# Note: The enumerations are mapped to Window's constants. # Note: The enumerations are mapped to Window's constants.
when defined(ssl): when defined(ssl):

View file

@ -1671,7 +1671,6 @@ proc debugEcho*[T](x: varargs[T, `$`]) {.magic: "Echo", noSideEffect.}
template newException*(exceptn: typeDesc, message: string): expr = template newException*(exceptn: typeDesc, message: string): expr =
## creates an exception object of type ``exceptn`` and sets its ``msg`` field ## creates an exception object of type ``exceptn`` and sets its ``msg`` field
## to `message`. Returns the new exception object. ## to `message`. Returns the new exception object.
# block: # open a new scope
var var
e: ref exceptn e: ref exceptn
new(e) new(e)

View file

@ -69,7 +69,7 @@ case $uos in
;; ;;
*solaris* | *sun* ) *solaris* | *sun* )
myos="solaris" myos="solaris"
LINK_FLAGS="$LINK_FLAGS -ldl -lm" LINK_FLAGS="$LINK_FLAGS -ldl -lm -lsocket -lnsl"
;; ;;
*haiku* ) *haiku* )
myos="haiku" myos="haiku"