added 'sig' feature; removed tfShared support in the compiler
This commit is contained in:
parent
7ae45ea420
commit
38dee2095c
17 changed files with 62 additions and 57 deletions
|
|
@ -221,6 +221,7 @@ type
|
||||||
nkGotoState, # used for the state machine (for iterators)
|
nkGotoState, # used for the state machine (for iterators)
|
||||||
nkState, # give a label to a code section (for iterators)
|
nkState, # give a label to a code section (for iterators)
|
||||||
nkBreakState, # special break statement for easier code generation
|
nkBreakState, # special break statement for easier code generation
|
||||||
|
nkSigSection
|
||||||
TNodeKinds* = set[TNodeKind]
|
TNodeKinds* = set[TNodeKind]
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -459,7 +460,7 @@ type
|
||||||
tfByCopy, # pass object/tuple by copy (C backend)
|
tfByCopy, # pass object/tuple by copy (C backend)
|
||||||
tfByRef, # pass object/tuple by reference (C backend)
|
tfByRef, # pass object/tuple by reference (C backend)
|
||||||
tfIterator, # type is really an iterator, not a tyProc
|
tfIterator, # type is really an iterator, not a tyProc
|
||||||
tfShared, # type is 'shared'
|
tfPartial, # type is declared as 'partial'
|
||||||
tfNotNil, # type cannot be 'nil'
|
tfNotNil, # type cannot be 'nil'
|
||||||
|
|
||||||
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
||||||
|
|
@ -534,7 +535,7 @@ const
|
||||||
skError* = skUnknown
|
skError* = skUnknown
|
||||||
|
|
||||||
# type flags that are essential for type equality:
|
# type flags that are essential for type equality:
|
||||||
eqTypeFlags* = {tfIterator, tfShared, tfNotNil, tfVarIsPtr}
|
eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr}
|
||||||
|
|
||||||
type
|
type
|
||||||
TMagic* = enum # symbols that require compiler magic:
|
TMagic* = enum # symbols that require compiler magic:
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,6 @@ proc hashType(c: var MD5Context, t: PType) =
|
||||||
if tfThread in t.flags: c &= ".thread"
|
if tfThread in t.flags: c &= ".thread"
|
||||||
else:
|
else:
|
||||||
for i in 0.. <t.len: c.hashType(t.sons[i])
|
for i in 0.. <t.len: c.hashType(t.sons[i])
|
||||||
if tfShared in t.flags: c &= "shared"
|
|
||||||
if tfNotNil in t.flags: c &= "not nil"
|
if tfNotNil in t.flags: c &= "not nil"
|
||||||
|
|
||||||
proc canonConst(n: PNode): TUid =
|
proc canonConst(n: PNode): TUid =
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,8 @@ type
|
||||||
tkLet,
|
tkLet,
|
||||||
tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin,
|
tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin,
|
||||||
tkObject, tkOf, tkOr, tkOut,
|
tkObject, tkOf, tkOr, tkOut,
|
||||||
tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkStatic,
|
tkProc, tkPtr, tkRaise, tkRef, tkReturn,
|
||||||
|
tkShl, tkShr, tkSig, tkStatic,
|
||||||
tkTemplate,
|
tkTemplate,
|
||||||
tkTry, tkTuple, tkType, tkUsing,
|
tkTry, tkTuple, tkType, tkUsing,
|
||||||
tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor,
|
tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor,
|
||||||
|
|
@ -81,7 +82,7 @@ const
|
||||||
"macro", "method", "mixin", "mod",
|
"macro", "method", "mixin", "mod",
|
||||||
"nil", "not", "notin", "object", "of", "or",
|
"nil", "not", "notin", "object", "of", "or",
|
||||||
"out", "proc", "ptr", "raise", "ref", "return",
|
"out", "proc", "ptr", "raise", "ref", "return",
|
||||||
"shl", "shr", "static",
|
"shl", "shr", "sig", "static",
|
||||||
"template",
|
"template",
|
||||||
"try", "tuple", "type", "using",
|
"try", "tuple", "type", "using",
|
||||||
"var", "when", "while", "with", "without", "xor",
|
"var", "when", "while", "with", "without", "xor",
|
||||||
|
|
|
||||||
|
|
@ -1938,6 +1938,7 @@ proc complexOrSimpleStmt(p: var TParser): PNode =
|
||||||
of tkLet: result = parseSection(p, nkLetSection, parseVariable)
|
of tkLet: result = parseSection(p, nkLetSection, parseVariable)
|
||||||
of tkWhen: result = parseIfOrWhen(p, nkWhenStmt)
|
of tkWhen: result = parseIfOrWhen(p, nkWhenStmt)
|
||||||
of tkVar: result = parseSection(p, nkVarSection, parseVariable)
|
of tkVar: result = parseSection(p, nkVarSection, parseVariable)
|
||||||
|
of tkSig: result = parseSection(p, nkSigSection, parseVariable)
|
||||||
of tkBind: result = parseBind(p, nkBindStmt)
|
of tkBind: result = parseBind(p, nkBindStmt)
|
||||||
of tkMixin: result = parseBind(p, nkMixinStmt)
|
of tkMixin: result = parseBind(p, nkMixinStmt)
|
||||||
of tkUsing: result = parseBind(p, nkUsingStmt)
|
of tkUsing: result = parseBind(p, nkUsingStmt)
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ proc lsub(n: PNode): int =
|
||||||
else:
|
else:
|
||||||
result = len("enum")
|
result = len("enum")
|
||||||
of nkEnumFieldDef: result = lsons(n) + 3
|
of nkEnumFieldDef: result = lsons(n) + 3
|
||||||
of nkVarSection, nkLetSection:
|
of nkVarSection, nkLetSection, nkSigSection:
|
||||||
if sonsLen(n) > 1: result = MaxLineLen + 1
|
if sonsLen(n) > 1: result = MaxLineLen + 1
|
||||||
else: result = lsons(n) + len("var_")
|
else: result = lsons(n) + len("var_")
|
||||||
of nkReturnStmt: result = lsub(n.sons[0]) + len("return_")
|
of nkReturnStmt: result = lsub(n.sons[0]) + len("return_")
|
||||||
|
|
@ -1173,11 +1173,12 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||||
initContext(a)
|
initContext(a)
|
||||||
incl(a.flags, rfInConstExpr)
|
incl(a.flags, rfInConstExpr)
|
||||||
gsection(g, n, a, tkConst, "const")
|
gsection(g, n, a, tkConst, "const")
|
||||||
of nkVarSection, nkLetSection:
|
of nkVarSection, nkLetSection, nkSigSection:
|
||||||
var L = sonsLen(n)
|
var L = sonsLen(n)
|
||||||
if L == 0: return
|
if L == 0: return
|
||||||
if n.kind == nkVarSection: putWithSpace(g, tkVar, "var")
|
if n.kind == nkVarSection: putWithSpace(g, tkVar, "var")
|
||||||
else: putWithSpace(g, tkLet, "let")
|
elif n.kind == nkLetSection: putWithSpace(g, tkLet, "let")
|
||||||
|
else: putWithSpace(g, tkSig, "sig")
|
||||||
if L > 1:
|
if L > 1:
|
||||||
gcoms(g)
|
gcoms(g)
|
||||||
indentNL(g)
|
indentNL(g)
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ type
|
||||||
instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
|
instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
|
||||||
op: TTypeAttachedOp): PSym {.nimcall.}
|
op: TTypeAttachedOp): PSym {.nimcall.}
|
||||||
selfName*: PIdent
|
selfName*: PIdent
|
||||||
|
signatures*: TStrTable
|
||||||
|
|
||||||
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
||||||
result.genericSym = s
|
result.genericSym = s
|
||||||
|
|
@ -178,6 +179,8 @@ proc newContext(module: PSym): PContext =
|
||||||
initStrTable(result.userPragmas)
|
initStrTable(result.userPragmas)
|
||||||
result.generics = @[]
|
result.generics = @[]
|
||||||
result.unknownIdents = initIntSet()
|
result.unknownIdents = initIntSet()
|
||||||
|
initStrTable(result.signatures)
|
||||||
|
|
||||||
|
|
||||||
proc inclSym(sq: var TSymSeq, s: PSym) =
|
proc inclSym(sq: var TSymSeq, s: PSym) =
|
||||||
var L = len(sq)
|
var L = len(sq)
|
||||||
|
|
|
||||||
|
|
@ -2354,6 +2354,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if not n.sons[0].typ.isEmptyType and not implicitlyDiscardable(n.sons[0]):
|
if not n.sons[0].typ.isEmptyType and not implicitlyDiscardable(n.sons[0]):
|
||||||
localError(n.info, errGenerated, "'defer' takes a 'void' expression")
|
localError(n.info, errGenerated, "'defer' takes a 'void' expression")
|
||||||
#localError(n.info, errGenerated, "'defer' not allowed in this context")
|
#localError(n.info, errGenerated, "'defer' not allowed in this context")
|
||||||
|
of nkSigSection: result = semSigSection(c, n)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errInvalidExpressionX,
|
localError(n.info, errInvalidExpressionX,
|
||||||
renderTree(n, {renderNoComments}))
|
renderTree(n, {renderNoComments}))
|
||||||
|
|
|
||||||
|
|
@ -386,6 +386,27 @@ proc isDiscardUnderscore(v: PSym): bool =
|
||||||
v.flags.incl(sfGenSym)
|
v.flags.incl(sfGenSym)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
proc semSigSection(c: PContext; n: PNode): PNode =
|
||||||
|
result = ast.emptyNode
|
||||||
|
for i in countup(0, sonsLen(n)-1):
|
||||||
|
var a = n.sons[i]
|
||||||
|
if gCmd == cmdIdeTools: suggestStmt(c, a)
|
||||||
|
if a.kind == nkCommentStmt: continue
|
||||||
|
if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a)
|
||||||
|
checkMinSonsLen(a, 3)
|
||||||
|
var length = sonsLen(a)
|
||||||
|
if a.sons[length-2].kind != nkEmpty:
|
||||||
|
let typ = semTypeNode(c, a.sons[length-2], nil)
|
||||||
|
for j in countup(0, length-3):
|
||||||
|
let v = semIdentDef(c, a.sons[j], skParam)
|
||||||
|
v.typ = typ
|
||||||
|
strTableIncl(c.signatures, v)
|
||||||
|
else:
|
||||||
|
localError(a.info, "'sig' section must have a type")
|
||||||
|
var def: PNode
|
||||||
|
if a.sons[length-1].kind != nkEmpty:
|
||||||
|
localError(a.info, "'sig' sections cannot contain assignments")
|
||||||
|
|
||||||
proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
var b: PNode
|
var b: PNode
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
|
|
||||||
|
|
@ -934,14 +934,18 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||||
def = fitNode(c, typ, def)
|
def = fitNode(c, typ, def)
|
||||||
if not hasType and not hasDefault:
|
if not hasType and not hasDefault:
|
||||||
if isType: localError(a.info, "':' expected")
|
if isType: localError(a.info, "':' expected")
|
||||||
let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything
|
if kind in {skTemplate, skMacro}:
|
||||||
if tdef == tyAnything:
|
typ = newTypeS(tyExpr, c)
|
||||||
message(a.info, warnTypelessParam, renderTree(n))
|
elif skipTypes(typ, {tyGenericInst}).kind == tyEmpty:
|
||||||
typ = newTypeS(tdef, c)
|
continue
|
||||||
|
|
||||||
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
|
|
||||||
for j in countup(0, length-3):
|
for j in countup(0, length-3):
|
||||||
var arg = newSymG(skParam, a.sons[j], c)
|
var arg = newSymG(skParam, a.sons[j], c)
|
||||||
|
if not hasType and not hasDefault and kind notin {skTemplate, skMacro}:
|
||||||
|
let param = strTableGet(c.signatures, arg.name)
|
||||||
|
if param != nil: typ = param.typ
|
||||||
|
else:
|
||||||
|
localError(a.info, "typeless parameters are obsolete")
|
||||||
|
typ = errorType(c)
|
||||||
let lifted = liftParamType(c, kind, genericParams, typ,
|
let lifted = liftParamType(c, kind, genericParams, typ,
|
||||||
arg.name.s, arg.info)
|
arg.name.s, arg.info)
|
||||||
let finalType = if lifted != nil: lifted else: typ.skipIntLit
|
let finalType = if lifted != nil: lifted else: typ.skipIntLit
|
||||||
|
|
@ -1307,11 +1311,6 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
of nkType: result = n.typ
|
of nkType: result = n.typ
|
||||||
of nkStmtListType: result = semStmtListType(c, n, prev)
|
of nkStmtListType: result = semStmtListType(c, n, prev)
|
||||||
of nkBlockType: result = semBlockType(c, n, prev)
|
of nkBlockType: result = semBlockType(c, n, prev)
|
||||||
of nkSharedTy:
|
|
||||||
checkSonsLen(n, 1)
|
|
||||||
result = semTypeNode(c, n.sons[0], prev)
|
|
||||||
result = freshType(result, prev)
|
|
||||||
result.flags.incl(tfShared)
|
|
||||||
else:
|
else:
|
||||||
localError(n.info, errTypeExpected)
|
localError(n.info, errTypeExpected)
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
|
|
@ -1387,15 +1386,6 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||||
of mPNimrodNode:
|
of mPNimrodNode:
|
||||||
incl m.typ.flags, tfTriggersCompileTime
|
incl m.typ.flags, tfTriggersCompileTime
|
||||||
of mShared:
|
|
||||||
setMagicType(m, tyObject, 0)
|
|
||||||
m.typ.n = newNodeI(nkRecList, m.info)
|
|
||||||
incl m.typ.flags, tfShared
|
|
||||||
of mGuarded:
|
|
||||||
setMagicType(m, tyObject, 0)
|
|
||||||
m.typ.n = newNodeI(nkRecList, m.info)
|
|
||||||
incl m.typ.flags, tfShared
|
|
||||||
rawAddSon(m.typ, sysTypeFromName"shared")
|
|
||||||
else: localError(m.info, errTypeExpected)
|
else: localError(m.info, errTypeExpected)
|
||||||
|
|
||||||
proc semGenericConstraints(c: PContext, x: PType): PType =
|
proc semGenericConstraints(c: PContext, x: PType): PType =
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,11 @@ import ast, astalgo, msgs, types, magicsys, semdata, renderer
|
||||||
const
|
const
|
||||||
tfInstClearedFlags = {tfHasMeta}
|
tfInstClearedFlags = {tfHasMeta}
|
||||||
|
|
||||||
proc sharedPtrCheck(info: TLineInfo, t: PType) =
|
|
||||||
if t.kind == tyPtr and t.len > 1:
|
|
||||||
if t.sons[0].sym.magic == mShared:
|
|
||||||
incl(t.flags, tfShared)
|
|
||||||
#if t.sons[0].sym.magic == mGuarded: incl(t.flags, tfGuarded)
|
|
||||||
if tfHasGCedMem in t.flags or t.isGCedMem:
|
|
||||||
localError(info, errGenerated,
|
|
||||||
"shared memory may not refer to GC'ed thread local memory")
|
|
||||||
|
|
||||||
proc checkPartialConstructedType(info: TLineInfo, t: PType) =
|
proc checkPartialConstructedType(info: TLineInfo, t: PType) =
|
||||||
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||||
localError(info, errInvalidPragmaX, "acyclic")
|
localError(info, errInvalidPragmaX, "acyclic")
|
||||||
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
||||||
localError(info, errVarVarTypeNotAllowed)
|
localError(info, errVarVarTypeNotAllowed)
|
||||||
else:
|
|
||||||
sharedPtrCheck(info, t)
|
|
||||||
|
|
||||||
proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||||
var t = typ.skipTypes({tyDistinct})
|
var t = typ.skipTypes({tyDistinct})
|
||||||
|
|
@ -40,8 +29,6 @@ proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||||
localError(info, errVarVarTypeNotAllowed)
|
localError(info, errVarVarTypeNotAllowed)
|
||||||
elif computeSize(t) == szIllegalRecursion:
|
elif computeSize(t) == szIllegalRecursion:
|
||||||
localError(info, errIllegalRecursionInTypeX, typeToString(t))
|
localError(info, errIllegalRecursionInTypeX, typeToString(t))
|
||||||
else:
|
|
||||||
sharedPtrCheck(info, t)
|
|
||||||
when false:
|
when false:
|
||||||
if t.kind == tyObject and t.sons[0] != nil:
|
if t.kind == tyObject and t.sons[0] != nil:
|
||||||
if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
|
if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,6 @@ const
|
||||||
const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg}
|
const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg}
|
||||||
|
|
||||||
proc addTypeFlags(name: var string, typ: PType) {.inline.} =
|
proc addTypeFlags(name: var string, typ: PType) {.inline.} =
|
||||||
if tfShared in typ.flags: name = "shared " & name
|
|
||||||
if tfNotNil in typ.flags: name.add(" not nil")
|
if tfNotNil in typ.flags: name.add(" not nil")
|
||||||
|
|
||||||
proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ type
|
||||||
wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
|
wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
|
||||||
wMacro, wMethod, wMixin, wMod, wNil,
|
wMacro, wMethod, wMixin, wMod, wNil,
|
||||||
wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
|
wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
|
||||||
wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wUsing, wVar,
|
wShl, wShr, wSig, wStatic, wTemplate, wTry, wTuple, wType, wUsing, wVar,
|
||||||
wWhen, wWhile, wWith, wWithout, wXor, wYield,
|
wWhen, wWhile, wWith, wWithout, wXor, wYield,
|
||||||
|
|
||||||
wColon, wColonColon, wEquals, wDot, wDotDot,
|
wColon, wColonColon, wEquals, wDot, wDotDot,
|
||||||
|
|
@ -113,7 +113,7 @@ const
|
||||||
"macro", "method", "mixin", "mod", "nil", "not", "notin",
|
"macro", "method", "mixin", "mod", "nil", "not", "notin",
|
||||||
"object", "of", "or",
|
"object", "of", "or",
|
||||||
"out", "proc", "ptr", "raise", "ref", "return",
|
"out", "proc", "ptr", "raise", "ref", "return",
|
||||||
"shl", "shr", "static",
|
"shl", "shr", "sig", "static",
|
||||||
"template", "try", "tuple", "type", "using", "var",
|
"template", "try", "tuple", "type", "using", "var",
|
||||||
"when", "while", "with", "without", "xor",
|
"when", "while", "with", "without", "xor",
|
||||||
"yield",
|
"yield",
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,13 @@ type
|
||||||
nnkEnumTy,
|
nnkEnumTy,
|
||||||
nnkEnumFieldDef,
|
nnkEnumFieldDef,
|
||||||
nnkArglist, nnkPattern
|
nnkArglist, nnkPattern
|
||||||
nnkReturnToken
|
nnkReturnToken,
|
||||||
|
nnkClosure,
|
||||||
|
nnkGotoState,
|
||||||
|
nnkState,
|
||||||
|
nnkBreakState,
|
||||||
|
nnkSigSection
|
||||||
|
|
||||||
NimNodeKinds* = set[NimNodeKind]
|
NimNodeKinds* = set[NimNodeKind]
|
||||||
NimTypeKind* = enum
|
NimTypeKind* = enum
|
||||||
ntyNone, ntyBool, ntyChar, ntyEmpty,
|
ntyNone, ntyBool, ntyChar, ntyEmpty,
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ const
|
||||||
"generic", "if", "import", "in", "include",
|
"generic", "if", "import", "in", "include",
|
||||||
"interface", "is", "isnot", "iterator", "let", "macro", "method",
|
"interface", "is", "isnot", "iterator", "let", "macro", "method",
|
||||||
"mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc",
|
"mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc",
|
||||||
"ptr", "raise", "ref", "return", "shl", "shr", "static",
|
"ptr", "raise", "ref", "return", "shl", "shr", "sig", "static",
|
||||||
"template", "try", "tuple", "type", "using", "var", "when", "while", "with",
|
"template", "try", "tuple", "type", "using", "var", "when", "while", "with",
|
||||||
"without", "xor", "yield"]
|
"without", "xor", "yield"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -279,11 +279,6 @@ when not defined(niminheritable):
|
||||||
when not defined(nimunion):
|
when not defined(nimunion):
|
||||||
{.pragma: unchecked.}
|
{.pragma: unchecked.}
|
||||||
|
|
||||||
when defined(nimNewShared):
|
|
||||||
type
|
|
||||||
`shared`* {.magic: "Shared".}
|
|
||||||
guarded* {.magic: "Guarded".}
|
|
||||||
|
|
||||||
# comparison operators:
|
# comparison operators:
|
||||||
proc `==` *[Enum: enum](x, y: Enum): bool {.magic: "EqEnum", noSideEffect.}
|
proc `==` *[Enum: enum](x, y: Enum): bool {.magic: "EqEnum", noSideEffect.}
|
||||||
## Checks whether values within the *same enum* have the same underlying value
|
## Checks whether values within the *same enum* have the same underlying value
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,9 @@ else:
|
||||||
proc c_setjmp(jmpb: C_JmpBuf): cint {.
|
proc c_setjmp(jmpb: C_JmpBuf): cint {.
|
||||||
header: "<setjmp.h>", importc: "setjmp".}
|
header: "<setjmp.h>", importc: "setjmp".}
|
||||||
|
|
||||||
proc c_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.
|
proc c_signal(sign: cint, handler: proc (a: cint) {.noconv.}) {.
|
||||||
importc: "signal", header: "<signal.h>".}
|
importc: "signal", header: "<signal.h>".}
|
||||||
proc c_raise(sig: cint) {.importc: "raise", header: "<signal.h>".}
|
proc c_raise(sign: cint) {.importc: "raise", header: "<signal.h>".}
|
||||||
|
|
||||||
proc c_fputs(c: cstring, f: C_TextFileStar) {.importc: "fputs",
|
proc c_fputs(c: cstring, f: C_TextFileStar) {.importc: "fputs",
|
||||||
header: "<stdio.h>".}
|
header: "<stdio.h>".}
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ when defined(endb):
|
||||||
dbgAborting: bool # whether the debugger wants to abort
|
dbgAborting: bool # whether the debugger wants to abort
|
||||||
|
|
||||||
when not defined(noSignalHandler):
|
when not defined(noSignalHandler):
|
||||||
proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
proc signalHandler(sign: cint) {.exportc: "signalHandler", noconv.} =
|
||||||
template processSignal(s, action: expr) {.immediate, dirty.} =
|
template processSignal(s, action: expr) {.immediate, dirty.} =
|
||||||
if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n")
|
if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n")
|
||||||
elif s == SIGSEGV:
|
elif s == SIGSEGV:
|
||||||
|
|
@ -342,13 +342,13 @@ when not defined(noSignalHandler):
|
||||||
GC_disable()
|
GC_disable()
|
||||||
var buf = newStringOfCap(2000)
|
var buf = newStringOfCap(2000)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
processSignal(sig, buf.add) # nice hu? currying a la Nim :-)
|
processSignal(sign, buf.add) # nice hu? currying a la Nim :-)
|
||||||
showErrorMessage(buf)
|
showErrorMessage(buf)
|
||||||
GC_enable()
|
GC_enable()
|
||||||
else:
|
else:
|
||||||
var msg: cstring
|
var msg: cstring
|
||||||
template asgn(y: expr) = msg = y
|
template asgn(y: expr) = msg = y
|
||||||
processSignal(sig, asgn)
|
processSignal(sign, asgn)
|
||||||
showErrorMessage(msg)
|
showErrorMessage(msg)
|
||||||
when defined(endb): dbgAborting = true
|
when defined(endb): dbgAborting = true
|
||||||
quit(1) # always quit when SIGABRT
|
quit(1) # always quit when SIGABRT
|
||||||
|
|
@ -367,6 +367,6 @@ when not defined(noSignalHandler):
|
||||||
|
|
||||||
proc setControlCHook(hook: proc () {.noconv.} not nil) =
|
proc setControlCHook(hook: proc () {.noconv.} not nil) =
|
||||||
# ugly cast, but should work on all architectures:
|
# ugly cast, but should work on all architectures:
|
||||||
type SignalHandler = proc (sig: cint) {.noconv, benign.}
|
type SignalHandler = proc (sign: cint) {.noconv, benign.}
|
||||||
{.deprecated: [TSignalHandler: SignalHandler].}
|
{.deprecated: [TSignalHandler: SignalHandler].}
|
||||||
c_signal(SIGINT, cast[SignalHandler](hook))
|
c_signal(SIGINT, cast[SignalHandler](hook))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue