Skip to content

Commit 0fd55d8

Browse files
committed
Halfway through
1 parent cd4585a commit 0fd55d8

File tree

3 files changed

+75
-52
lines changed

3 files changed

+75
-52
lines changed

compiler/semobjconstr.nim

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ proc semConstrField(c: PContext, flags: TExprFlags,
7070
var initValue = semExprFlagDispatched(c, assignment[1], flags)
7171
if initValue != nil:
7272
initValue = fitNode(c, field.typ, initValue, assignment.info)
73-
assignment.sons[0] = newSymNode(field)
74-
assignment.sons[1] = initValue
73+
assignment[0] = newSymNode(field)
74+
assignment[1] = initValue
7575
assignment.flags.incl nfSem
7676
return initValue
7777

@@ -88,7 +88,7 @@ proc allPossibleValues(c: PContext, t: PType): IntSet =
8888
result = initIntSet()
8989
if t.enumHasHoles:
9090
let t = t.skipTypes(abstractRange)
91-
for field in t.n.sons:
91+
for field in t.n:
9292
result.incl(field.sym.position)
9393
else:
9494
for i in toInt64(firstOrd(c.config, t)) .. toInt64(lastOrd(c.config, t)):
@@ -100,13 +100,13 @@ proc branchVals(c: PContext, caseNode: PNode, caseIdx: int,
100100
result = initIntSet()
101101
processBranchVals(caseNode[caseIdx], incl)
102102
else:
103-
result = allPossibleValues(c, caseNode.sons[0].typ)
103+
result = allPossibleValues(c, caseNode[0].typ)
104104
for i in 1 .. caseNode.len-2:
105105
processBranchVals(caseNode[i], excl)
106106

107107
proc rangeTypVals(rangeTyp: PType): IntSet =
108108
assert rangeTyp.kind == tyRange
109-
let (a, b) = (rangeTyp.n.sons[0].intVal, rangeTyp.n.sons[1].intVal)
109+
let (a, b) = (rangeTyp.n[0].intVal, rangeTyp.n[1].intVal)
110110
result = initIntSet()
111111
for it in a .. b:
112112
result.incl(it.int)
@@ -118,8 +118,8 @@ proc formatUnsafeBranchVals(t: PType, diffVals: IntSet): string =
118118
if t.kind in {tyEnum, tyBool}:
119119
var i = 0
120120
for val in diffVals:
121-
while t.n.sons[i].sym.position < val: inc(i)
122-
strs.add(t.n.sons[i].sym.name.s)
121+
while t.n[i].sym.position < val: inc(i)
122+
strs.add(t.n[i].sym.name.s)
123123
else:
124124
for val in diffVals:
125125
strs.add($val)
@@ -194,13 +194,11 @@ proc checkForMissingFields(c: PContext, recList, initExpr: PNode, considerDefaul
194194
localError(c.config, initExpr.info, "fields not initialized: $1.", [missing])
195195

196196
proc semConstructFields(c: PContext, recNode: PNode,
197-
initExpr: PNode, flags: TExprFlags, wantsInit = true): InitStatus =
198-
result = initUnknown
199-
197+
initExpr: PNode, flags: TExprFlags): InitStatus =
200198
case recNode.kind
201199
of nkRecList:
202200
for field in recNode:
203-
let status = semConstructFields(c, field, initExpr, flags, wantsInit)
201+
let status = semConstructFields(c, field, initExpr, flags)
204202
mergeInitStatus(result, status)
205203

206204
of nkRecCase:
@@ -209,18 +207,18 @@ proc semConstructFields(c: PContext, recNode: PNode,
209207
let fields = branch[branch.len - 1]
210208
fieldsPresentInInitExpr(c, fields, initExpr)
211209

212-
template checkMissingFields(branchNode: PNode, considerDefaults: bool) =
210+
proc checkMissingFields(branchNode: PNode, considerDefaults: bool) =
213211
if branchNode != nil:
214212
let fields = branchNode[^1]
215213
checkForMissingFields(c, fields, initExpr, considerDefaults)
216214

217-
let discriminator = recNode.sons[0]
215+
let discriminator = recNode[0]
218216
internalAssert c.config, discriminator.kind == nkSym
219217
var selectedBranch = -1
220218

221219
for i in 1 ..< recNode.len:
222220
let innerRecords = recNode[i][^1]
223-
let status = semConstructFields(c, innerRecords, initExpr, flags, selectedBranch == -1)
221+
let status = semConstructFields(c, innerRecords, initExpr, flags)
224222
if status notin {initNone, initUnknown}:
225223
mergeInitStatus(result, status)
226224
if selectedBranch != -1:
@@ -255,7 +253,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
255253
localError(c.config, discriminatorVal.info, ("possible values " &
256254
"$2are in conflict with discriminator values for " &
257255
"selected object branch $1.") % [$selectedBranch,
258-
formatUnsafeBranchVals(recNode.sons[0].typ, valsDiff)])
256+
formatUnsafeBranchVals(recNode[0].typ, valsDiff)])
259257

260258
let branchNode = recNode[selectedBranch]
261259
let flags = flags*{efAllowDestructor} + {efPreferStatic,
@@ -270,7 +268,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
270268
if discriminatorVal.kind notin nkLiterals and (
271269
not isOrdinalType(discriminatorVal.typ, true) or
272270
lengthOrd(c.config, discriminatorVal.typ) > MaxSetElements or
273-
lengthOrd(c.config, recNode.sons[0].typ) > MaxSetElements):
271+
lengthOrd(c.config, recNode[0].typ) > MaxSetElements):
274272
localError(c.config, discriminatorVal.info,
275273
"branch initialization with a runtime discriminator only " &
276274
"supports ordinal types with 2^16 elements or less.")
@@ -348,33 +346,28 @@ proc semConstructFields(c: PContext, recNode: PNode,
348346
checkMissingFields matchedBranch, true
349347
else:
350348
result = initPartial
349+
discriminatorVal = discriminatorVal.skipHidden
350+
debug discriminatorVal
351351
if discriminatorVal.kind == nkIntLit: #or discriminatorVal.typ.kind == tyRange:
352352
# When the discriminator is a compile-time value, we also know
353353
# which branch will be selected:
354354
matchedBranch = recNode.pickCaseBranch discriminatorVal
355355
if matchedBranch != nil: checkMissingFields matchedBranch, true
356+
elif discriminatorVal.typ.kind == tyRange:
357+
let matchedBranches = recNode.pickCaseBranches discriminatorVal.typ.n
358+
for m in matchedBranches:
359+
checkMissingFields m, matchedBranches.len == 0
356360
else:
357-
discriminatorVal = discriminatorVal.skipHidden
358-
if discriminatorVal.typ.kind == tyRange and not( #TODO: Maybe hint or warn when the type is too big to select the branch
359-
discriminatorVal.kind notin nkLiterals and (
360-
not isOrdinalType(discriminatorVal.typ, true) or
361-
lengthOrd(c.config, discriminatorVal.typ) > MaxSetElements or
362-
lengthOrd(c.config, recNode.sons[0].typ) > MaxSetElements)
363-
):
364-
let matchedBranches = recNode.pickCaseBranches discriminatorVal.typ.n
365-
for m in matchedBranches:
366-
checkMissingFields m, matchedBranches.len == 0
367-
else:
368-
# All bets are off. If any of the branches has a mandatory
369-
# fields we must produce an error:
370-
for i in 1 ..< recNode.len: checkMissingFields recNode[i], false
361+
# All bets are off. If any of the branches has a mandatory
362+
# fields we must produce an error:
363+
for i in 1 ..< recNode.len: checkMissingFields recNode[i], false
371364

372365
of nkSym:
373366
let field = recNode.sym
374-
var e = semConstrField(c, flags, field, initExpr)
375-
if wantsInit and e == nil: #Try to use default value
376-
e = field.ast
377-
result = if e != nil: initFull else: initNone
367+
let e = semConstrField(c, flags, field, initExpr)
368+
result = if e != nil: initFull
369+
elif field.ast != nil: initUnknown
370+
else: initNone
378371

379372
else:
380373
internalAssert c.config, false
@@ -388,12 +381,12 @@ proc semConstructType(c: PContext, initExpr: PNode,
388381
mergeInitStatus(result, status)
389382
if status in {initPartial, initNone, initUnknown}:
390383
checkForMissingFields c, t.n, initExpr, true
391-
let base = t.sons[0]
384+
let base = t[0]
392385
if base == nil: break
393386
t = skipTypes(base, skipPtrs)
394387

395388
proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
396-
var t = semTypeNode(c, n.sons[0], nil)
389+
var t = semTypeNode(c, n[0], nil)
397390
result = newNodeIT(nkObjConstr, n.info, t)
398391
for child in n: result.add child
399392

@@ -403,7 +396,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
403396

404397
t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned})
405398
if t.kind == tyRef:
406-
t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink, tyOwned})
399+
t = skipTypes(t[0], {tyGenericInst, tyAlias, tySink, tyOwned})
407400
if optOwnedRefs in c.config.globalOptions:
408401
result.typ = makeVarType(c, result.typ, tyOwned)
409402
# we have to watch out, there are also 'owned proc' types that can be used

compiler/semtypes.nim

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int,
635635
errorUndeclaredIdentifier(c, n.sons[0].info, typ.sym.name.s)
636636
elif not isOrdinalType(typ):
637637
localError(c.config, n.sons[0].info, "selector must be of an ordinal type, float or string")
638-
elif firstOrd(c.config, typ) != 0:
638+
if firstOrd(c.config, typ) != 0:
639639
localError(c.config, n.info, "low(" & $a.sons[0].sym.name.s &
640640
") must be 0 for discriminant")
641641
elif lengthOrd(c.config, typ) > 0x00007FFF:
@@ -745,6 +745,8 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
745745
if n[^1].kind != nkEmpty:
746746
n[^1] = semConstExpr(c, n[^1])
747747
fSym.sym.ast = n[^1]
748+
elif typ.kind in {tyRange, tyOrdinal}:
749+
fSym.sym.ast = newIntNode(nkIntLit, firstOrd(c.config, typ))
748750
if a.kind == nkEmpty: addSon(father, newSymNode(f))
749751
else: addSon(a, newSymNode(f))
750752
styleCheckDef(c.config, f)

compiler/transf.nim

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,46 @@ proc containsResult(n: PNode): bool =
930930
for i in 0..<n.safeLen:
931931
if (n[i].kind notin procDefs) and containsResult(n[i]): return true
932932

933+
#from semobjconstr import defaultFields
934+
935+
# proc defaultFields(c: PContext, recNode: PNode, initExpr: PNode, flags: TExprFlags): seq[PNode] =
936+
# case recNode.kind
937+
# of nkRecList:
938+
# for field in recNode:
939+
# result.add defaultFields(c, field, initExpr, flags)
940+
# of nkRecCase:
941+
# let discriminator = recNode.sons[0]
942+
# var matchedBranch: PNode
943+
944+
# var discriminatorVal = semConstrField(c, flags + {efPreferStatic}, discriminator.sym, initExpr)
945+
# if discriminatorVal == nil: #Try to use default value
946+
# discriminatorVal = discriminator.sym.ast
947+
# if discriminatorVal != nil:
948+
# result.add newTree(nkExprColonExpr, discriminator, discriminatorVal)
949+
950+
# if discriminatorVal == nil:
951+
# matchedBranch = recNode.pickCaseBranch newIntLit(c.graph, initExpr.info, 0)
952+
# else:
953+
# if discriminatorVal.kind == nkIntLit:
954+
# # When the discriminator is a compile-time value, we also know
955+
# # which branch will be selected:
956+
# matchedBranch = recNode.pickCaseBranch discriminatorVal
957+
# else:
958+
# echo "where does the wind take us?"
959+
# if matchedBranch != nil:
960+
# result.add defaultFields(c, matchedBranch[^1], initExpr, flags)
961+
# of nkSym:
962+
# let field = recNode.sym
963+
# if semConstrField(c, flags, field, initExpr) == nil:
964+
# if field.ast != nil: #Try to use default value
965+
# result.add newTree(nkExprColonExpr, recNode, field.ast)
966+
# else:
967+
# echo "init zero"
968+
# else:
969+
# echo recNode.kind; debug recNode; internalAssert c.config, false
970+
971+
972+
933973
proc transform(c: PTransf, n: PNode): PNode =
934974
when false:
935975
var oldDeferAnchor: PNode
@@ -1084,20 +1124,8 @@ proc transform(c: PTransf, n: PNode): PNode =
10841124
of nkExceptBranch:
10851125
result = transformExceptBranch(c, n)
10861126
of nkObjConstr:
1087-
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
1088-
let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpO"), c.transCon.owner, n.info)
1089-
sym.typ = n.typ
1090-
let obj = newSymNode(sym)
1091-
result.add newTree(nkVarSection, newTree(nkIdentDefs, obj, newNode(nkEmpty), n))
1092-
var providedFields: seq[PSym]
1093-
for i in 1..<n.len:
1094-
assert n[i].kind == nkExprColonExpr
1095-
result.add transform(c, newTree(nkAsgn, makeFieldTree(obj, n[i][0]), n[i][1]))
1096-
providedFields.add n[i][0].sym
1097-
let typ = obj.typ.skipTypes(abstractInst)
1098-
result.add transform(c, initDefaultFields(obj, (if typ.kind == tyRef: typ[0].n else: typ.n), providedFields))
1099-
n.sons.setLen(1)
1100-
result.add obj
1127+
result = n
1128+
#result.add defaultFields(c, result.typ.skipTypes(abstractInst).n, result, {})
11011129
else:
11021130
result = transformSons(c, n)
11031131
when false:

0 commit comments

Comments
 (0)