diff --git a/compiler/ast.nim b/compiler/ast.nim index 54b96d69e..21358ba3e 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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: diff --git a/compiler/canonicalizer.nim b/compiler/canonicalizer.nim index 9afe4ab10..85dbe7536 100644 --- a/compiler/canonicalizer.nim +++ b/compiler/canonicalizer.nim @@ -158,7 +158,6 @@ proc hashType(c: var MD5Context, t: PType) = if tfThread in t.flags: c &= ".thread" else: for i in 0.. 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) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 48d1a1a74..a13f2c232 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -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) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d27edf304..a2f1940f7 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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})) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d1c088d73..d84415827 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index ac425ba15..6fa042bbb 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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 = diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index a7f28feec..d20704a2a 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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: diff --git a/compiler/types.nim b/compiler/types.nim index 71ab84022..9aa991086 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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 = diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 0a0534118..7fec140a2 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -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", diff --git a/lib/core/macros.nim b/lib/core/macros.nim index eda793620..7d39812c4 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -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, diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index 1bc0af1b6..6321115c4 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -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"] diff --git a/lib/system.nim b/lib/system.nim index 3ef9c1b31..904791a46 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -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 diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 1bbd89fe7..1abd8466d 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -103,9 +103,9 @@ else: proc c_setjmp(jmpb: C_JmpBuf): cint {. header: "", 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: "".} -proc c_raise(sig: cint) {.importc: "raise", header: "".} +proc c_raise(sign: cint) {.importc: "raise", header: "".} proc c_fputs(c: cstring, f: C_TextFileStar) {.importc: "fputs", header: "".} diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 8d1e04b8d..948f87410 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -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))