added 'sig' feature; removed tfShared support in the compiler

This commit is contained in:
Andreas Rumpf
2016-02-28 19:56:41 +01:00
parent 7ae45ea420
commit 38dee2095c
17 changed files with 62 additions and 57 deletions

View File

@@ -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:

View File

@@ -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 =

View File

@@ -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",

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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}))

View File

@@ -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)

View File

@@ -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 =

View File

@@ -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:

View File

@@ -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 =

View File

@@ -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",

View File

@@ -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,

View File

@@ -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"]

View File

@@ -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

View File

@@ -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>".}

View File

@@ -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))