mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
added 'sig' feature; removed tfShared support in the compiler
This commit is contained in:
@@ -221,6 +221,7 @@ type
|
||||
nkGotoState, # used for the state machine (for iterators)
|
||||
nkState, # give a label to a code section (for iterators)
|
||||
nkBreakState, # special break statement for easier code generation
|
||||
nkSigSection
|
||||
TNodeKinds* = set[TNodeKind]
|
||||
|
||||
type
|
||||
@@ -459,7 +460,7 @@ type
|
||||
tfByCopy, # pass object/tuple by copy (C backend)
|
||||
tfByRef, # pass object/tuple by reference (C backend)
|
||||
tfIterator, # type is really an iterator, not a tyProc
|
||||
tfShared, # type is 'shared'
|
||||
tfPartial, # type is declared as 'partial'
|
||||
tfNotNil, # type cannot be 'nil'
|
||||
|
||||
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
||||
@@ -534,7 +535,7 @@ const
|
||||
skError* = skUnknown
|
||||
|
||||
# type flags that are essential for type equality:
|
||||
eqTypeFlags* = {tfIterator, tfShared, tfNotNil, tfVarIsPtr}
|
||||
eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr}
|
||||
|
||||
type
|
||||
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"
|
||||
else:
|
||||
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"
|
||||
|
||||
proc canonConst(n: PNode): TUid =
|
||||
|
||||
@@ -44,7 +44,8 @@ type
|
||||
tkLet,
|
||||
tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin,
|
||||
tkObject, tkOf, tkOr, tkOut,
|
||||
tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkStatic,
|
||||
tkProc, tkPtr, tkRaise, tkRef, tkReturn,
|
||||
tkShl, tkShr, tkSig, tkStatic,
|
||||
tkTemplate,
|
||||
tkTry, tkTuple, tkType, tkUsing,
|
||||
tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor,
|
||||
@@ -81,7 +82,7 @@ const
|
||||
"macro", "method", "mixin", "mod",
|
||||
"nil", "not", "notin", "object", "of", "or",
|
||||
"out", "proc", "ptr", "raise", "ref", "return",
|
||||
"shl", "shr", "static",
|
||||
"shl", "shr", "sig", "static",
|
||||
"template",
|
||||
"try", "tuple", "type", "using",
|
||||
"var", "when", "while", "with", "without", "xor",
|
||||
|
||||
@@ -1938,6 +1938,7 @@ proc complexOrSimpleStmt(p: var TParser): PNode =
|
||||
of tkLet: result = parseSection(p, nkLetSection, parseVariable)
|
||||
of tkWhen: result = parseIfOrWhen(p, nkWhenStmt)
|
||||
of tkVar: result = parseSection(p, nkVarSection, parseVariable)
|
||||
of tkSig: result = parseSection(p, nkSigSection, parseVariable)
|
||||
of tkBind: result = parseBind(p, nkBindStmt)
|
||||
of tkMixin: result = parseBind(p, nkMixinStmt)
|
||||
of tkUsing: result = parseBind(p, nkUsingStmt)
|
||||
|
||||
@@ -460,7 +460,7 @@ proc lsub(n: PNode): int =
|
||||
else:
|
||||
result = len("enum")
|
||||
of nkEnumFieldDef: result = lsons(n) + 3
|
||||
of nkVarSection, nkLetSection:
|
||||
of nkVarSection, nkLetSection, nkSigSection:
|
||||
if sonsLen(n) > 1: result = MaxLineLen + 1
|
||||
else: result = lsons(n) + len("var_")
|
||||
of nkReturnStmt: result = lsub(n.sons[0]) + len("return_")
|
||||
@@ -1173,11 +1173,12 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||
initContext(a)
|
||||
incl(a.flags, rfInConstExpr)
|
||||
gsection(g, n, a, tkConst, "const")
|
||||
of nkVarSection, nkLetSection:
|
||||
of nkVarSection, nkLetSection, nkSigSection:
|
||||
var L = sonsLen(n)
|
||||
if L == 0: return
|
||||
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:
|
||||
gcoms(g)
|
||||
indentNL(g)
|
||||
|
||||
@@ -105,6 +105,7 @@ type
|
||||
instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
|
||||
op: TTypeAttachedOp): PSym {.nimcall.}
|
||||
selfName*: PIdent
|
||||
signatures*: TStrTable
|
||||
|
||||
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
||||
result.genericSym = s
|
||||
@@ -178,6 +179,8 @@ proc newContext(module: PSym): PContext =
|
||||
initStrTable(result.userPragmas)
|
||||
result.generics = @[]
|
||||
result.unknownIdents = initIntSet()
|
||||
initStrTable(result.signatures)
|
||||
|
||||
|
||||
proc inclSym(sq: var TSymSeq, s: PSym) =
|
||||
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]):
|
||||
localError(n.info, errGenerated, "'defer' takes a 'void' expression")
|
||||
#localError(n.info, errGenerated, "'defer' not allowed in this context")
|
||||
of nkSigSection: result = semSigSection(c, n)
|
||||
else:
|
||||
localError(n.info, errInvalidExpressionX,
|
||||
renderTree(n, {renderNoComments}))
|
||||
|
||||
@@ -386,6 +386,27 @@ proc isDiscardUnderscore(v: PSym): bool =
|
||||
v.flags.incl(sfGenSym)
|
||||
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 =
|
||||
var b: PNode
|
||||
result = copyNode(n)
|
||||
|
||||
@@ -934,14 +934,18 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
def = fitNode(c, typ, def)
|
||||
if not hasType and not hasDefault:
|
||||
if isType: localError(a.info, "':' expected")
|
||||
let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything
|
||||
if tdef == tyAnything:
|
||||
message(a.info, warnTypelessParam, renderTree(n))
|
||||
typ = newTypeS(tdef, c)
|
||||
|
||||
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
|
||||
if kind in {skTemplate, skMacro}:
|
||||
typ = newTypeS(tyExpr, c)
|
||||
elif skipTypes(typ, {tyGenericInst}).kind == tyEmpty:
|
||||
continue
|
||||
for j in countup(0, length-3):
|
||||
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,
|
||||
arg.name.s, arg.info)
|
||||
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 nkStmtListType: result = semStmtListType(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:
|
||||
localError(n.info, errTypeExpected)
|
||||
result = newOrPrevType(tyError, prev, c)
|
||||
@@ -1387,15 +1386,6 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||
of mPNimrodNode:
|
||||
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)
|
||||
|
||||
proc semGenericConstraints(c: PContext, x: PType): PType =
|
||||
|
||||
@@ -14,22 +14,11 @@ import ast, astalgo, msgs, types, magicsys, semdata, renderer
|
||||
const
|
||||
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) =
|
||||
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||
localError(info, errInvalidPragmaX, "acyclic")
|
||||
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
||||
localError(info, errVarVarTypeNotAllowed)
|
||||
else:
|
||||
sharedPtrCheck(info, t)
|
||||
|
||||
proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||
var t = typ.skipTypes({tyDistinct})
|
||||
@@ -40,8 +29,6 @@ proc checkConstructedType*(info: TLineInfo, typ: PType) =
|
||||
localError(info, errVarVarTypeNotAllowed)
|
||||
elif computeSize(t) == szIllegalRecursion:
|
||||
localError(info, errIllegalRecursionInTypeX, typeToString(t))
|
||||
else:
|
||||
sharedPtrCheck(info, t)
|
||||
when false:
|
||||
if t.kind == tyObject and t.sons[0] != nil:
|
||||
if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
|
||||
|
||||
@@ -412,7 +412,6 @@ const
|
||||
const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg}
|
||||
|
||||
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")
|
||||
|
||||
proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
|
||||
@@ -30,7 +30,7 @@ type
|
||||
wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
|
||||
wMacro, wMethod, wMixin, wMod, wNil,
|
||||
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,
|
||||
|
||||
wColon, wColonColon, wEquals, wDot, wDotDot,
|
||||
@@ -113,7 +113,7 @@ const
|
||||
"macro", "method", "mixin", "mod", "nil", "not", "notin",
|
||||
"object", "of", "or",
|
||||
"out", "proc", "ptr", "raise", "ref", "return",
|
||||
"shl", "shr", "static",
|
||||
"shl", "shr", "sig", "static",
|
||||
"template", "try", "tuple", "type", "using", "var",
|
||||
"when", "while", "with", "without", "xor",
|
||||
"yield",
|
||||
|
||||
@@ -71,7 +71,13 @@ type
|
||||
nnkEnumTy,
|
||||
nnkEnumFieldDef,
|
||||
nnkArglist, nnkPattern
|
||||
nnkReturnToken
|
||||
nnkReturnToken,
|
||||
nnkClosure,
|
||||
nnkGotoState,
|
||||
nnkState,
|
||||
nnkBreakState,
|
||||
nnkSigSection
|
||||
|
||||
NimNodeKinds* = set[NimNodeKind]
|
||||
NimTypeKind* = enum
|
||||
ntyNone, ntyBool, ntyChar, ntyEmpty,
|
||||
|
||||
@@ -56,7 +56,7 @@ const
|
||||
"generic", "if", "import", "in", "include",
|
||||
"interface", "is", "isnot", "iterator", "let", "macro", "method",
|
||||
"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",
|
||||
"without", "xor", "yield"]
|
||||
|
||||
|
||||
@@ -279,11 +279,6 @@ when not defined(niminheritable):
|
||||
when not defined(nimunion):
|
||||
{.pragma: unchecked.}
|
||||
|
||||
when defined(nimNewShared):
|
||||
type
|
||||
`shared`* {.magic: "Shared".}
|
||||
guarded* {.magic: "Guarded".}
|
||||
|
||||
# comparison operators:
|
||||
proc `==` *[Enum: enum](x, y: Enum): bool {.magic: "EqEnum", noSideEffect.}
|
||||
## Checks whether values within the *same enum* have the same underlying value
|
||||
|
||||
@@ -103,9 +103,9 @@ else:
|
||||
proc c_setjmp(jmpb: C_JmpBuf): cint {.
|
||||
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>".}
|
||||
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",
|
||||
header: "<stdio.h>".}
|
||||
|
||||
@@ -316,7 +316,7 @@ when defined(endb):
|
||||
dbgAborting: bool # whether the debugger wants to abort
|
||||
|
||||
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.} =
|
||||
if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n")
|
||||
elif s == SIGSEGV:
|
||||
@@ -342,13 +342,13 @@ when not defined(noSignalHandler):
|
||||
GC_disable()
|
||||
var buf = newStringOfCap(2000)
|
||||
rawWriteStackTrace(buf)
|
||||
processSignal(sig, buf.add) # nice hu? currying a la Nim :-)
|
||||
processSignal(sign, buf.add) # nice hu? currying a la Nim :-)
|
||||
showErrorMessage(buf)
|
||||
GC_enable()
|
||||
else:
|
||||
var msg: cstring
|
||||
template asgn(y: expr) = msg = y
|
||||
processSignal(sig, asgn)
|
||||
processSignal(sign, asgn)
|
||||
showErrorMessage(msg)
|
||||
when defined(endb): dbgAborting = true
|
||||
quit(1) # always quit when SIGABRT
|
||||
@@ -367,6 +367,6 @@ when not defined(noSignalHandler):
|
||||
|
||||
proc setControlCHook(hook: proc () {.noconv.} not nil) =
|
||||
# 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].}
|
||||
c_signal(SIGINT, cast[SignalHandler](hook))
|
||||
|
||||
Reference in New Issue
Block a user