Adhere to new rules of object variants (re)initialization

This commit is contained in:
k0zmo 2019-06-16 13:43:08 +02:00 committed by flyx
parent 90f47e1043
commit fd4a718586
4 changed files with 34 additions and 32 deletions

View File

@ -170,8 +170,7 @@ template setCurAnchor(val: AnchorId) =
template eventStart(k: YamlStreamEventKind) {.dirty.} = template eventStart(k: YamlStreamEventKind) {.dirty.} =
assertInStream() assertInStream()
yieldEvent() yieldEvent()
reset(curEvent) curEvent = YamlStreamEvent(kind: k)
curEvent.kind = k
setTag(yTagQuestionMark) setTag(yTagQuestionMark)
setAnchor(yAnchorNone) setAnchor(yAnchorNone)
inEvent = true inEvent = true

View File

@ -148,9 +148,9 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
try: try:
case start.kind case start.kind
of yamlStartMap: of yamlStartMap:
result.tag = tagLib.uri(start.mapTag) result = YamlNode(tag: tagLib.uri(start.mapTag),
result.kind = yMapping kind: yMapping,
result.fields = newTable[YamlNode, YamlNode]() fields: newTable[YamlNode, YamlNode]())
while s.peek().kind != yamlEndMap: while s.peek().kind != yamlEndMap:
let let
key = composeNode(s, tagLib, c) key = composeNode(s, tagLib, c)
@ -161,16 +161,16 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
discard s.next() discard s.next()
addAnchor(c, start.mapAnchor) addAnchor(c, start.mapAnchor)
of yamlStartSeq: of yamlStartSeq:
result.tag = tagLib.uri(start.seqTag) result = YamlNode(tag: tagLib.uri(start.seqTag),
result.kind = ySequence kind: ySequence,
result.elems = newSeq[YamlNode]() elems: newSeq[YamlNode]())
while s.peek().kind != yamlEndSeq: while s.peek().kind != yamlEndSeq:
result.elems.add(composeNode(s, tagLib, c)) result.elems.add(composeNode(s, tagLib, c))
addAnchor(c, start.seqAnchor) addAnchor(c, start.seqAnchor)
discard s.next() discard s.next()
of yamlScalar: of yamlScalar:
result.tag = tagLib.uri(start.scalarTag) result = YamlNode(tag: tagLib.uri(start.scalarTag),
result.kind = yScalar kind: yScalar)
shallowCopy(result.content, start.scalarContent) shallowCopy(result.content, start.scalarContent)
addAnchor(c, start.scalarAnchor) addAnchor(c, start.scalarAnchor)
of yamlAlias: of yamlAlias:

View File

@ -774,13 +774,21 @@ macro constructFieldValue(t: typedesc, tIndex: int, stream: untyped,
discriminant = newDotExpr(o, newIdentNode($child[0])) discriminant = newDotExpr(o, newIdentNode($child[0]))
discType = newCall("type", discriminant) discType = newCall("type", discriminant)
var disOb = newNimNode(nnkOfBranch).add(newStrLitNode($child[0])) var disOb = newNimNode(nnkOfBranch).add(newStrLitNode($child[0]))
var objConstr = newNimNode(nnkObjConstr).add(newCall("type", o))
objConstr.add(newColonExpr(newIdentNode($child[0]), newIdentNode(
"value")))
for otherChild in tDesc[2].children:
if otherChild == child:
continue
objConstr.add(newColonExpr(newIdentNode($otherChild), newDotExpr(o,
newIdentNode($otherChild))))
disOb.add(newStmtList( disOb.add(newStmtList(
checkDuplicate(stream, tName, $child[0], fieldIndex, matched), checkDuplicate(stream, tName, $child[0], fieldIndex, matched),
newNimNode(nnkVarSection).add( newNimNode(nnkVarSection).add(
newNimNode(nnkIdentDefs).add( newNimNode(nnkIdentDefs).add(
newIdentNode("value"), discType, newEmptyNode())), newIdentNode("value"), discType, newEmptyNode())),
newCall("constructChild", stream, context, newIdentNode("value")), newCall("constructChild", stream, context, newIdentNode("value")),
newAssignment(discriminant, newIdentNode("value")), newAssignment(o, objConstr),
markAsFound(fieldIndex, matched))) markAsFound(fieldIndex, matched)))
caseStmt.add(disOb) caseStmt.add(disOb)
var alreadyUsedSet = newNimNode(nnkCurly) var alreadyUsedSet = newNimNode(nnkCurly)
@ -875,7 +883,6 @@ proc constructObjectDefault*[O: object|tuple](
if e.kind != startKind: if e.kind != startKind:
raise s.constructionError("While constructing " & raise s.constructionError("While constructing " &
typetraits.name(O) & ": Expected " & $startKind & ", got " & $e.kind) typetraits.name(O) & ": Expected " & $startKind & ", got " & $e.kind)
when isVariantObject(getType(O)): reset(result) # make discriminants writeable
injectIgnoredKeyList(O, ignoredKeyList) injectIgnoredKeyList(O, ignoredKeyList)
injectFailOnUnknownKeys(O, failOnUnknown) injectFailOnUnknownKeys(O, failOnUnknown)
while s.peek.kind != endKind: while s.peek.kind != endKind:
@ -1063,12 +1070,15 @@ macro constructImplicitVariantObject(s, c, r, possibleTagIds: untyped,
yAssert tDesc.kind == nnkObjectTy yAssert tDesc.kind == nnkObjectTy
let recCase = tDesc[2][0] let recCase = tDesc[2][0]
yAssert recCase.kind == nnkRecCase yAssert recCase.kind == nnkRecCase
let discriminant = newDotExpr(r, newIdentNode($recCase[0])) result = newNimNode(nnkIfStmt)
var ifStmt = newNimNode(nnkIfStmt)
for i in 1 .. recCase.len - 1: for i in 1 .. recCase.len - 1:
yAssert recCase[i].kind == nnkOfBranch yAssert recCase[i].kind == nnkOfBranch
var branch = newNimNode(nnkElifBranch) var branch = newNimNode(nnkElifBranch)
var branchContent = newStmtList(newAssignment(discriminant, recCase[i][0])) var branchContent = newStmtList(newAssignment(r,
newNimNode(nnkObjConstr).add(
newCall("type", r),
newColonExpr(newIdentNode($recCase[0]), recCase[i][0])
)))
case recCase[i][1].recListLen case recCase[i][1].recListLen
of 0: of 0:
branch.add(infix(newIdentNode("yTagNull"), "in", possibleTagIds)) branch.add(infix(newIdentNode("yTagNull"), "in", possibleTagIds))
@ -1082,7 +1092,7 @@ macro constructImplicitVariantObject(s, c, r, possibleTagIds: untyped,
block: block:
internalError("Too many children: " & $recCase[i][1].recListlen) internalError("Too many children: " & $recCase[i][1].recListlen)
branch.add(branchContent) branch.add(branchContent)
ifStmt.add(branch) result.add(branch)
let raiseStmt = newNimNode(nnkRaiseStmt).add( let raiseStmt = newNimNode(nnkRaiseStmt).add(
newCall(bindSym("constructionError"), s, newCall(bindSym("constructionError"), s,
infix(newStrLitNode("This value type does not map to any field in " & infix(newStrLitNode("This value type does not map to any field in " &
@ -1091,12 +1101,11 @@ macro constructImplicitVariantObject(s, c, r, possibleTagIds: untyped,
newNimNode(nnkBracketExpr).add(possibleTagIds, newIntLitNode(0))) newNimNode(nnkBracketExpr).add(possibleTagIds, newIntLitNode(0)))
) )
)) ))
ifStmt.add(newNimNode(nnkElse).add(newNimNode(nnkTryStmt).add( result.add(newNimNode(nnkElse).add(newNimNode(nnkTryStmt).add(
newStmtList(raiseStmt), newNimNode(nnkExceptBranch).add( newStmtList(raiseStmt), newNimNode(nnkExceptBranch).add(
newIdentNode("KeyError"), newIdentNode("KeyError"),
newNimNode(nnkDiscardStmt).add(newEmptyNode()) newNimNode(nnkDiscardStmt).add(newEmptyNode())
)))) ))))
result = newStmtList(newCall("reset", r), ifStmt)
macro isImplicitVariantObject(o: typed): untyped = macro isImplicitVariantObject(o: typed): untyped =
result = newCall("compiles", newCall(implicitVariantObjectMarker, o)) result = newCall("compiles", newCall(implicitVariantObjectMarker, o))

View File

@ -51,27 +51,21 @@ proc jsonFromScalar(content: string, tag: TagId): JsonNode
try: try:
case mappedType case mappedType
of yTypeInteger: of yTypeInteger:
result.kind = JInt result = JsonNode(kind: JInt, num: parseBiggestInt(content))
result.num = parseBiggestInt(content)
of yTypeFloat: of yTypeFloat:
result.kind = JFloat result = JsonNode(kind: JFloat, fnum: parseFloat(content))
result.fnum = parseFloat(content)
of yTypeFloatInf: of yTypeFloatInf:
result.kind = JFloat result = JsonNode(kind: JFloat, fnum: if content[0] == '-': NegInf else: Inf)
result.fnum = if content[0] == '-': NegInf else: Inf
of yTypeFloatNaN: of yTypeFloatNaN:
result.kind = JFloat result = JsonNode(kind: JFloat, fnum: NaN)
result.fnum = NaN
of yTypeBoolTrue: of yTypeBoolTrue:
result.kind = JBool result = JsonNode(kind: JBool, bval: true)
result.bval = true
of yTypeBoolFalse: of yTypeBoolFalse:
result.kind = JBool result = JsonNode(kind: JBool, bval: false)
result.bval = false
of yTypeNull: of yTypeNull:
result.kind = JNull result = JsonNode(kind: JNull)
else: else:
result.kind = JString result = JsonNode(kind: JString)
shallowCopy(result.str, content) shallowCopy(result.str, content)
except ValueError: except ValueError:
var e = newException(YamlConstructionError, "Cannot parse numeric value") var e = newException(YamlConstructionError, "Cannot parse numeric value")