This commit is contained in:
Andreas Rumpf
2020-08-01 07:39:00 +02:00
committed by GitHub
parent 6b88cd0d42
commit 4ab6887a67
5 changed files with 32 additions and 24 deletions

View File

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

View File

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

View File

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

View File

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

View File

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