diff options
Diffstat (limited to 'rod')
-rwxr-xr-x | rod/cgen.nim | 19 | ||||
-rwxr-xr-x | rod/lexbase.nim | 4 | ||||
-rwxr-xr-x | rod/semstmts.nim | 45 | ||||
-rwxr-xr-x | rod/semtypes.nim | 57 | ||||
-rwxr-xr-x | rod/semtypinst.nim | 10 | ||||
-rwxr-xr-x | rod/transf.nim | 2 |
6 files changed, 74 insertions, 63 deletions
diff --git a/rod/cgen.nim b/rod/cgen.nim index 51aee87ab..a15c4c4ca 100755 --- a/rod/cgen.nim +++ b/rod/cgen.nim @@ -267,7 +267,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc, of frHeader: var r = rdLoc(a) if not takeAddr: r = ropef("(*$1)", [r]) - var s = t + var s = skipTypes(t, abstractInst) while (s.kind == tyObject) and (s.sons[0] != nil): app(r, ".Sup") s = skipTypes(s.sons[0], abstractInst) @@ -373,7 +373,7 @@ proc cstringLit(m: BModule, r: var PRope, s: string): PRope = proc allocParam(p: BProc, s: PSym) = assert(s.kind == skParam) - if not (lfParamCopy in s.loc.flags): + if lfParamCopy notin s.loc.flags: inc(p.labels) var tmp = con("%LOC", toRope(p.labels)) incl(s.loc.flags, lfParamCopy) @@ -383,7 +383,6 @@ proc allocParam(p: BProc, s: PSym) = s.loc.r = tmp proc localDebugInfo(p: BProc, s: PSym) = - var name, a: PRope if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return # XXX work around a bug: No type information for open arrays possible: if skipTypes(s.typ, abstractVar).kind == tyOpenArray: return @@ -391,7 +390,7 @@ proc localDebugInfo(p: BProc, s: PSym) = # "address" is the 0th field # "typ" is the 1rst field # "name" is the 2nd field - name = cstringLit(p, p.s[cpsInit], normalize(s.name.s)) + var name = cstringLit(p, p.s[cpsInit], normalize(s.name.s)) if (s.kind == skParam) and not ccgIntroducedPtr(s): allocParam(p, s) inc(p.labels, 3) appf(p.s[cpsInit], "%LOC$6 = getelementptr %TF* %F, %NI 0, $1, %NI 0$n" & @@ -404,12 +403,12 @@ proc localDebugInfo(p: BProc, s: PSym) = toRope(p.labels), toRope(p.labels - 1), toRope(p.labels - 2)]) else: - a = con("&", s.loc.r) + var a = con("&", s.loc.r) if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r appf(p.s[cpsInit], - "F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n", [ - toRope(p.frameLen), makeCString(normalize(s.name.s)), a, - genTypeInfo(p.module, s.loc.t)]) + "F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n", + [toRope(p.frameLen), makeCString(normalize(s.name.s)), a, + genTypeInfo(p.module, s.loc.t)]) inc(p.frameLen) proc assignLocalVar(p: BProc, s: PSym) = @@ -461,7 +460,7 @@ proc iff(cond: bool, the, els: PRope): PRope = proc assignParam(p: BProc, s: PSym) = assert(s.loc.r != nil) - if (sfAddrTaken in s.flags) and (gCmd == cmdCompileToLLVM): allocParam(p, s) + if sfAddrTaken in s.flags and gCmd == cmdCompileToLLVM: allocParam(p, s) localDebugInfo(p, s) proc fillProcLoc(sym: PSym) = @@ -574,7 +573,7 @@ proc generateHeaders(m: BModule) = app(m.s[cfsHeaders], "#include \"nimbase.h\"" & tnl & tnl) var it = PStrEntry(m.headerFiles.head) while it != nil: - if not (it.data[0] in {'\"', '<'}): + if it.data[0] notin {'\"', '<'}: appf(m.s[cfsHeaders], "#include \"$1\"$n", [toRope(it.data)]) else: appf(m.s[cfsHeaders], "#include $1$n", [toRope(it.data)]) diff --git a/rod/lexbase.nim b/rod/lexbase.nim index 4f946b35f..f37fcc0a4 100755 --- a/rod/lexbase.nim +++ b/rod/lexbase.nim @@ -164,7 +164,7 @@ proc getCurrentLine(L: TBaseLexer, marker: bool = true): string = while not (L.buf[i] in {CR, LF, EndOfFile}): add(result, L.buf[i]) inc(i) - result = result & "\n" + result.add("\n") if marker: - result = result & RepeatChar(getColNumber(L, L.bufpos)) & '^' & "\n" + result.add(RepeatChar(getColNumber(L, L.bufpos)) & '^' & "\n") diff --git a/rod/semstmts.nim b/rod/semstmts.nim index 8f0fc64b5..176fdad1b 100755 --- a/rod/semstmts.nim +++ b/rod/semstmts.nim @@ -472,11 +472,7 @@ proc addGenericParamListToScope(c: PContext, n: PNode) = if a.kind != nkSym: internalError(a.info, "addGenericParamListToScope") addDecl(c, a.sym) -proc SemTypeSection(c: PContext, n: PNode): PNode = - var - s: PSym - t, body: PType - result = n +proc typeSectionLeftSidePass(c: PContext, n: PNode) = # process the symbols on the left side for the whole type section, before # we even look at the type definitions on the right for i in countup(0, sonsLen(n) - 1): @@ -485,7 +481,8 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = if a.kind == nkCommentStmt: continue if a.kind != nkTypeDef: IllFormedAst(a) checkSonsLen(a, 3) - if (c.p.owner.kind == skModule): + var s: PSym + if c.p.owner.kind == skModule: s = semIdentWithPragma(c, skType, a.sons[0], {sfStar, sfMinus}) incl(s.flags, sfGlobal) else: @@ -493,18 +490,20 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = if s.flags * {sfStar, sfMinus} != {}: incl(s.flags, sfInInterface) s.typ = newTypeS(tyForward, c) s.typ.sym = s # process pragmas: - if a.sons[0].kind == nkPragmaExpr: + if a.sons[0].kind == nkPragmaExpr: pragma(c, s, a.sons[0].sons[1], typePragmas) # add it here, so that recursive types are possible: addInterfaceDecl(c, s) a.sons[0] = newSymNode(s) + +proc typeSectionRightSidePass(c: PContext, n: PNode) = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkTypeDef): IllFormedAst(a) checkSonsLen(a, 3) if (a.sons[0].kind != nkSym): IllFormedAst(a) - s = a.sons[0].sym + var s = a.sons[0].sym if (s.magic == mNone) and (a.sons[2].kind == nkEmpty): GlobalError(a.info, errImplOfXexpected, s.name.s) if s.magic != mNone: processMagicType(c, s) @@ -518,13 +517,12 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = InternalError(a.info, "semTypeSection: containerID") s.typ.containerID = getID() a.sons[1] = semGenericParamList(c, a.sons[1], s.typ) - # we fill it out later. For magic generics like 'seq', it won't be filled # so we use tyEmpty instead of nil to not crash for strange conversions - # like: mydata.seq + # like: mydata.seq addSon(s.typ, newTypeS(tyEmpty, c)) s.ast = a - body = semTypeNode(c, a.sons[2], nil) + var body = semTypeNode(c, a.sons[2], nil) if body != nil: body.sym = s s.typ.sons[sonsLen(s.typ) - 1] = body popOwner() @@ -532,28 +530,39 @@ proc SemTypeSection(c: PContext, n: PNode): PNode = elif a.sons[2].kind != nkEmpty: # process the type's body: pushOwner(s) - t = semTypeNode(c, a.sons[2], s.typ) - if (t != s.typ) and (s.typ != nil): - internalError(a.info, "semTypeSection()") - s.typ = t + var t = semTypeNode(c, a.sons[2], s.typ) + if s.typ == nil: + s.typ = t + elif t != s.typ: + # this can happen for e.g. tcan_alias_specialised_generic: + assignType(s.typ, t) + #debug s.typ s.ast = a popOwner() + +proc typeSectionFinalPass(c: PContext, n: PNode) = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.sons[0].kind != nkSym): IllFormedAst(a) - s = a.sons[0].sym + var s = a.sons[0].sym # compute the type's size and check for illegal recursions: if a.sons[1].kind == nkEmpty: - if (a.sons[2].kind in {nkSym, nkIdent, nkAccQuoted}): + if a.sons[2].kind in {nkSym, nkIdent, nkAccQuoted}: # type aliases are hard: #MessageOut('for type ' + typeToString(s.typ)); - t = semTypeNode(c, a.sons[2], nil) + var t = semTypeNode(c, a.sons[2], nil) if t.kind in {tyObject, tyEnum}: assignType(s.typ, t) s.typ.id = t.id # same id checkConstructedType(s.info, s.typ) +proc SemTypeSection(c: PContext, n: PNode): PNode = + typeSectionLeftSidePass(c, n) + typeSectionRightSidePass(c, n) + typeSectionFinalPass(c, n) + result = n + proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = s.typ = semProcTypeNode(c, n, genericParams, nil) diff --git a/rod/semtypes.nim b/rod/semtypes.nim index ec5bb9e2f..90a774645 100755 --- a/rod/semtypes.nim +++ b/rod/semtypes.nim @@ -421,27 +421,34 @@ proc addInheritedFields(c: PContext, check: var TIntSet, pos: var int, addInheritedFields(c, check, pos, obj.sons[0]) addInheritedFieldsAux(c, check, pos, obj.n) +proc skipGenericInvokation(t: PType): PType {.inline.} = + result = t + if result.kind == tyGenericInvokation: + result = result.sons[0] + if result.kind == tyGenericBody: + result = lastSon(result) + proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = - var - check: TIntSet - base: PType - pos: int + var check: TIntSet IntSetInit(check) - pos = 0 # n.sons[0] contains the pragmas (if any). We process these later... + var pos = 0 + var base: PType = nil + # n.sons[0] contains the pragmas (if any). We process these later... checkSonsLen(n, 3) if n.sons[1].kind != nkEmpty: base = semTypeNode(c, n.sons[1].sons[0], nil) - if base.kind == tyObject: addInheritedFields(c, check, pos, base) - else: localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) - else: - base = nil + var concreteBase = skipGenericInvokation(skipTypes(base, skipPtrs)) + if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags: + addInheritedFields(c, check, pos, concreteBase) + else: + debug base + debug concreteBase + localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) if n.kind != nkObjectTy: InternalError(n.info, "semObjectNode") result = newOrPrevType(tyObject, prev, c) addSon(result, base) result.n = newNodeI(nkRecList, n.info) semRecordNodeAux(c, n.sons[2], check, pos, result.n, result.sym) - if (base != nil) and (tfFinal in base.flags): - localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) proc addTypeVarsOfGenericBody(c: PContext, t: PType, genericParams: PNode, cl: var TIntSet): PType = @@ -559,9 +566,6 @@ proc semBlockType(c: PContext, n: PNode, prev: PType): PType = Dec(c.p.nestedBlockCounter) proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = - var - s: PSym - t: PType result = nil if gCmd == cmdIdeTools: suggestExpr(c, n) case n.kind @@ -576,7 +580,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = else: GlobalError(n.info, errTypeExpected) of nkBracketExpr: checkMinSonsLen(n, 2) - s = semTypeIdent(c, n.sons[0]) + var s = semTypeIdent(c, n.sons[0]) case s.magic of mArray: result = semArray(c, n, prev) of mOpenArray: result = semContainer(c, n, tyOpenArray, "openarray", prev) @@ -586,7 +590,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of mSeq: result = semContainer(c, n, tySequence, "seq", prev) else: result = semGeneric(c, n, s, prev) of nkIdent, nkDotExpr, nkAccQuoted: - s = semTypeIdent(c, n) + var s = semTypeIdent(c, n) if s.typ == nil: GlobalError(n.info, errTypeExpected) if prev == nil: result = s.typ @@ -596,7 +600,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = prev of nkSym: if (n.sym.kind == skType) and (n.sym.typ != nil): - t = n.sym.typ + var t = n.sym.typ if prev == nil: result = t else: @@ -615,20 +619,15 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = checkSonsLen(n, 2) result = semProcTypeNode(c, n.sons[0], nil, prev) # dummy symbol for `pragma`: - s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c) + var s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c) s.typ = result pragma(c, s, n.sons[1], procTypePragmas) - of nkEnumTy: - result = semEnum(c, n, prev) - of nkType: - result = n.typ - of nkStmtListType: - result = semStmtListType(c, n, prev) - of nkBlockType: - result = semBlockType(c, n, prev) - else: - GlobalError(n.info, errTypeExpected) - #internalError(n.info, 'semTypeNode(' +{&} nodeKindToStr[n.kind] +{&} ')'); + of nkEnumTy: result = semEnum(c, n, prev) + of nkType: result = n.typ + of nkStmtListType: result = semStmtListType(c, n, prev) + of nkBlockType: result = semBlockType(c, n, prev) + else: GlobalError(n.info, errTypeExpected) + #internalError(n.info, 'semTypeNode(' +{&} nodeKindToStr[n.kind] +{&} ')'); proc setMagicType(m: PSym, kind: TTypeKind, size: int) = m.typ.kind = kind diff --git a/rod/semtypinst.nim b/rod/semtypinst.nim index 6427d7858..b6126e285 100755 --- a/rod/semtypinst.nim +++ b/rod/semtypinst.nim @@ -12,13 +12,17 @@ import ast, astalgo, msgs, types, semdata proc checkConstructedType*(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") elif computeSize(t) < 0: LocalError(info, errIllegalRecursionInTypeX, typeToString(t)) - elif (t.kind == tyVar) and (t.sons[0].kind == tyVar): + elif t.kind == tyVar and t.sons[0].kind == tyVar: LocalError(info, errVarVarTypeNotAllowed) - + when false: + if t.kind == tyObject and t.sons[0] != nil: + if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags: + localError(info, errInheritanceOnlyWithNonFinalObjects) + proc containsGenericTypeIter(t: PType, closure: PObject): bool = result = t.kind in GenericTypes diff --git a/rod/transf.nim b/rod/transf.nim index c7c4e3db8..d2e6f8c69 100755 --- a/rod/transf.nim +++ b/rod/transf.nim @@ -669,7 +669,7 @@ proc transform(c: PTransf, n: PNode): PTransNode = result = transformFor(c, n) of nkCaseStmt: result = transformCase(c, n) - of nkProcDef, nkMethodDef, nkIteratorDef, nkMacroDef: + of nkProcDef, nkMethodDef, nkIteratorDef, nkMacroDef, nkConverterDef: if n.sons[genericParamsPos].kind == nkEmpty: n.sons[codePos] = PNode(transform(c, n.sons[codePos])) if n.kind == nkMethodDef: methodDef(n.sons[namePos].sym) |