diff options
-rw-r--r-- | compiler/dfa.nim | 4 | ||||
-rw-r--r-- | compiler/parser.nim | 4 | ||||
-rw-r--r-- | compiler/semobjconstr.nim | 38 | ||||
-rw-r--r-- | compiler/semtypes.nim | 8 | ||||
-rw-r--r-- | compiler/varpartitions.nim | 2 |
5 files changed, 32 insertions, 24 deletions
diff --git a/compiler/dfa.nim b/compiler/dfa.nim index f3b358d72..85a9ccf42 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -280,7 +280,7 @@ proc patch(c: var Con, p: TPosition) = # patch with current index c.code[p.int].dest = checkedDistance(c.code.len - p.int) -func gen(c: var Con; n: PNode) +proc gen(c: var Con; n: PNode) proc popBlock(c: var Con; oldLen: int) = var exits: seq[TPosition] @@ -712,7 +712,7 @@ proc genVarSection(c: var Con; n: PNode) = if a.lastSon.kind != nkEmpty: genDef(c, a[0]) -func gen(c: var Con; n: PNode) = +proc gen(c: var Con; n: PNode) = case n.kind of nkSym: genUse(c, n) of nkCallKinds: diff --git a/compiler/parser.nim b/compiler/parser.nim index ccb7ca3b1..8cfeff6b0 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1953,7 +1953,7 @@ proc parseObjectPart(p: var TParser): PNode = else: parMessage(p, errIdentifierExpected, p.tok) break - else: + elif sameOrNoInd(p): case p.tok.tokType of tkWhen: result = parseObjectWhen(p) @@ -1968,6 +1968,8 @@ proc parseObjectPart(p: var TParser): PNode = getTok(p) else: result = p.emptyNode + else: + result = p.emptyNode proc parseObject(p: var TParser): PNode = #| object = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index f8639b000..cd5a52fe9 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -154,20 +154,20 @@ proc collectMissingFields(c: PContext, fieldsRecList: PNode, if assignment == nil: constrCtx.missingFields.add r.sym -proc semConstructFields(c: PContext, recNode: PNode, +proc semConstructFields(c: PContext, n: PNode, constrCtx: var ObjConstrContext, flags: TExprFlags): InitStatus = result = initUnknown - case recNode.kind + case n.kind of nkRecList: - for field in recNode: + for field in n: let status = semConstructFields(c, field, constrCtx, flags) mergeInitStatus(result, status) of nkRecCase: template fieldsPresentInBranch(branchIdx: int): string = - let branch = recNode[branchIdx] + let branch = n[branchIdx] let fields = branch[^1] fieldsPresentInInitExpr(c, fields, constrCtx.initExpr) @@ -176,12 +176,12 @@ proc semConstructFields(c: PContext, recNode: PNode, let fields = branchNode[^1] collectMissingFields(c, fields, constrCtx) - let discriminator = recNode[0] + let discriminator = n[0] internalAssert c.config, discriminator.kind == nkSym var selectedBranch = -1 - for i in 1..<recNode.len: - let innerRecords = recNode[i][^1] + for i in 1..<n.len: + let innerRecords = n[i][^1] let status = semConstructFields(c, innerRecords, constrCtx, flags) if status notin {initNone, initUnknown}: mergeInitStatus(result, status) @@ -217,9 +217,9 @@ proc semConstructFields(c: PContext, recNode: PNode, localError(c.config, discriminatorVal.info, ("possible values " & "$2 are in conflict with discriminator values for " & "selected object branch $1.") % [$selectedBranch, - valsDiff.renderAsType(recNode[0].typ)]) + valsDiff.renderAsType(n[0].typ)]) - let branchNode = recNode[selectedBranch] + let branchNode = n[selectedBranch] let flags = flags*{efAllowDestructor} + {efPreferStatic, efPreferNilResult} var discriminatorVal = semConstrField(c, flags, @@ -230,7 +230,7 @@ proc semConstructFields(c: PContext, recNode: PNode, if discriminatorVal.kind notin nkLiterals and ( not isOrdinalType(discriminatorVal.typ, true) or lengthOrd(c.config, discriminatorVal.typ) > MaxSetElements or - lengthOrd(c.config, recNode[0].typ) > MaxSetElements): + lengthOrd(c.config, n[0].typ) > MaxSetElements): localError(c.config, discriminatorVal.info, "branch initialization with a runtime discriminator only " & "supports ordinal types with 2^16 elements or less.") @@ -242,7 +242,7 @@ proc semConstructFields(c: PContext, recNode: PNode, if ctorCase == nil: if discriminatorVal.typ.kind == tyRange: let rangeVals = c.getIntSetOfType(discriminatorVal.typ) - let recBranchVals = branchVals(c, recNode, selectedBranch, false) + let recBranchVals = branchVals(c, n, selectedBranch, false) let diff = rangeVals - recBranchVals if diff.len != 0: valuesInConflictError(diff) @@ -260,7 +260,7 @@ proc semConstructFields(c: PContext, recNode: PNode, else: var ctorBranchVals = branchVals(c, ctorCase, ctorIdx, true) - recBranchVals = branchVals(c, recNode, selectedBranch, false) + recBranchVals = branchVals(c, n, selectedBranch, false) branchValsDiff = ctorBranchVals - recBranchVals if branchValsDiff.len != 0: valuesInConflictError(branchValsDiff) @@ -271,14 +271,14 @@ proc semConstructFields(c: PContext, recNode: PNode, failedBranch = selectedBranch else: # With an else clause, check that all other branches don't match: - for i in 1..<recNode.len - 1: - if recNode[i].caseBranchMatchesExpr(discriminatorVal): + for i in 1..<n.len - 1: + if n[i].caseBranchMatchesExpr(discriminatorVal): failedBranch = i break if failedBranch != -1: if discriminatorVal.typ.kind == tyRange: let rangeVals = c.getIntSetOfType(discriminatorVal.typ) - let recBranchVals = branchVals(c, recNode, selectedBranch, false) + let recBranchVals = branchVals(c, n, selectedBranch, false) let diff = rangeVals - recBranchVals if diff.len != 0: valuesInConflictError(diff) @@ -301,22 +301,22 @@ proc semConstructFields(c: PContext, recNode: PNode, # initialized to zero and this will select a particular branch as # a result: let defaultValue = newIntLit(c.graph, constrCtx.initExpr.info, 0) - let matchedBranch = recNode.pickCaseBranch defaultValue + let matchedBranch = n.pickCaseBranch defaultValue collectMissingFields matchedBranch else: result = initPartial if discriminatorVal.kind == nkIntLit: # When the discriminator is a compile-time value, we also know # which branch will be selected: - let matchedBranch = recNode.pickCaseBranch discriminatorVal + let matchedBranch = n.pickCaseBranch discriminatorVal if matchedBranch != nil: collectMissingFields matchedBranch else: # All bets are off. If any of the branches has a mandatory # fields we must produce an error: - for i in 1..<recNode.len: collectMissingFields recNode[i] + for i in 1..<n.len: collectMissingFields n[i] of nkSym: - let field = recNode.sym + let field = n.sym let e = semConstrField(c, flags, field, constrCtx.initExpr) result = if e != nil: initFull else: initNone diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 588a0f4f6..c2aeadc21 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -663,7 +663,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, internalError(c.config, "semRecordCase: discriminant is no symbol") return incl(a[0].sym.flags, sfDiscriminant) - var covered: Int128 = toInt128(0) + var covered = toInt128(0) var chckCovered = false var typ = skipTypes(a[0].typ, abstractVar-{tyTypeDesc}) const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool} @@ -744,6 +744,8 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, father.add n elif branch != nil: semRecordNodeAux(c, branch, check, pos, father, rectype, hasCaseFields) + elif father.kind in {nkElse, nkOfBranch}: + father.add newNodeI(nkRecList, n.info) of nkRecCase: semRecordCase(c, n, check, pos, father, rectype) of nkNilLit: @@ -800,7 +802,9 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, if containsOrIncl(check, n.sym.name.id): localError(c.config, n.info, "attempt to redefine: '" & n.sym.name.s & "'") father.add n - of nkEmpty: discard + of nkEmpty: + if father.kind in {nkElse, nkOfBranch}: + father.add n else: illFormedAst(n, c.config) proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 08b591cc5..7a6cc4f63 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -9,6 +9,8 @@ ## Partition variables into different graphs. Used for ## Nim's write tracking and also for the cursor inference. +## The algorithm is a reinvention / variation of Steensgaard's +## algorithm. ## The used algorithm is "union find" with path compression. import ast, types, lineinfos, options, msgs, renderer |