preserves_schema_nim: merged And patterns with optionals
This commit is contained in:
parent
a52e84dd70
commit
501d6cc012
|
@ -373,15 +373,28 @@ proc isDictionary(loc: Location; pat: Pattern): bool =
|
|||
else: discard
|
||||
|
||||
proc isDictionary(loc: Location; defAnd: DefinitionAnd): bool =
|
||||
result = isDictionary(loc, defAnd.field0.pattern0.pattern)
|
||||
result =
|
||||
isDictionary(loc, defAnd.field0.pattern0.pattern) and
|
||||
isDictionary(loc, defAnd.field0.pattern1.pattern)
|
||||
for np in defAnd.field0.patternN:
|
||||
if result: result = isDictionary(loc, np.pattern)
|
||||
|
||||
proc isDictionary(loc: Location; def: Definition): bool =
|
||||
case def.orKind
|
||||
of DefinitionKind.Pattern:
|
||||
result = isDictionary(loc, def.pattern)
|
||||
of DefinitionKind.or:
|
||||
result =
|
||||
isDictionary(loc, def.or.field0.pattern0.pattern) and
|
||||
isDictionary(loc, def.or.field0.pattern1.pattern)
|
||||
for np in def.or.field0.patternN:
|
||||
if result: result = isDictionary(loc, np.pattern)
|
||||
of DefinitionKind.and:
|
||||
result = isDictionary(loc, def.and)
|
||||
else: discard
|
||||
result =
|
||||
isDictionary(loc, def.and.field0.pattern0.pattern) and
|
||||
isDictionary(loc, def.and.field0.pattern1.pattern)
|
||||
for np in def.and.field0.patternN:
|
||||
if result: result = isDictionary(loc, np.pattern)
|
||||
|
||||
proc isAny(loc: Location; def: Definition): bool =
|
||||
case def.orKind
|
||||
|
@ -577,7 +590,9 @@ proc typeDef(loc: Location; name: string; def: Definition; ty: PNode): PNode =
|
|||
newEmpty(),
|
||||
ty)
|
||||
of DefinitionKind.and:
|
||||
let pragma = newEmpty()
|
||||
var pragma = nkPragma.newNode
|
||||
if isDictionary(loc, def):
|
||||
pragma.add(ident"preservesDictionary")
|
||||
nkTypeDef.newTree(
|
||||
nkPragmaExpr.newTree(
|
||||
name.ident.accQuote.toExport,
|
||||
|
@ -628,20 +643,25 @@ proc addField(recList: PNode; loc: Location; known: var TypeTable; parentName: s
|
|||
known[typePath] = typeDef(loc, typeName, pattern, fieldSpec.node)
|
||||
recList.add identDef(loc.schema, id, ident(typeName), isEmbedded(loc, pattern))
|
||||
|
||||
proc addField(recList: PNode; loc: Location; known: var TypeTable; parentName: string; nsp: NamedSimplePattern; index = 0) =
|
||||
proc addField(recList: PNode; loc: Location; known: var TypeTable; parentName: string; nsp: NamedSimplePattern; index: int; optional: bool) =
|
||||
let
|
||||
label = label(nsp, parentName, index)
|
||||
id = label.toFieldIdent
|
||||
pattern = nsp.pattern
|
||||
if pattern.isRef:
|
||||
addField(recList, loc, known, pattern, label)
|
||||
var node = typeIdent(loc, pattern).node
|
||||
if optional:
|
||||
node = nkBracketExpr.newTree(ident"Option", node)
|
||||
recList.add identDef(loc.schema, id, node, false)
|
||||
else:
|
||||
var
|
||||
typeName = parentName & capitalizeAscii(label)
|
||||
typePath = loc.schemaPath & @[Symbol typeName]
|
||||
fieldSpec = nimTypeOf(loc, known, label, pattern)
|
||||
if optional:
|
||||
fieldSpec.node = nkBracketExpr.newTree(ident"Option", fieldSpec.node)
|
||||
known[typePath] = typeDef(loc, typeName, pattern, fieldSpec.node)
|
||||
recList.add identDef(loc.schema, id, ident(typeName), false)
|
||||
recList.add identDef(loc.schema, id, fieldSpec.node, false)
|
||||
|
||||
proc addFields(recList: PNode; loc: Location; known: var TypeTable; parentName: string; cp: CompoundPattern): PNode {.discardable.} =
|
||||
let scm = loc.schema
|
||||
|
@ -677,7 +697,7 @@ proc addFields(recList: PNode; loc: Location; known: var TypeTable; parentName:
|
|||
variableType.isEmbedded)
|
||||
of CompoundPatternKind.dict:
|
||||
for nameVal, nsp in cp.dict.entries:
|
||||
recList.addField(loc, known, $nameVal, nsp)
|
||||
recList.addField(loc, known, $nameVal, nsp, 0, false)
|
||||
reclist
|
||||
|
||||
proc addFields(recList: PNode; loc: Location; known: var TypeTable; name: string; pat: SimplePattern): PNode {.discardable.} =
|
||||
|
@ -800,9 +820,88 @@ proc nimTypeOf(loc: Location; known: var TypeTable; name: string; orDef: Definit
|
|||
newEmpty(),
|
||||
nkRecList.newTree(recCase))
|
||||
|
||||
proc nimTypeOf(loc: Location; known: var TypeTable; name: string; def: DefinitionAnd): TypeSpec =
|
||||
proc isAny(sp: SimplePattern): bool =
|
||||
sp.orKind == SimplePatternKind.any
|
||||
|
||||
proc initSimpleAny: SimplePattern =
|
||||
SimplePattern(orKind: SimplePatternKind.any)
|
||||
|
||||
proc asAny(nsp: NamedSimplePattern): NamedSimplePattern =
|
||||
result = nsp
|
||||
case result.orKind
|
||||
of NamedSimplePatternKind.named:
|
||||
if not result.named.pattern.isAny:
|
||||
result.named.pattern = initSimpleAny()
|
||||
of NamedSimplePatternKind.anonymous:
|
||||
if not result.anonymous.isAny:
|
||||
result.anonymous = initSimpleAny()
|
||||
|
||||
type
|
||||
AndEntry = tuple[pattern: NamedSimplePattern, optional: bool]
|
||||
AndEntries = OrderedTable[Value, AndEntry]
|
||||
|
||||
proc collect(entries: var AndEntries; loc: Location; def: Definition; optional: bool) {.gcsafe.}
|
||||
|
||||
proc collect(entries: var AndEntries; loc: Location; pat: SimplePattern; optional: bool) =
|
||||
case pat.orKind
|
||||
of SimplePatternKind.Ref:
|
||||
let (loc, def) = deref(loc, pat.ref)
|
||||
collect(entries, loc, def, optional)
|
||||
else:
|
||||
raiseAssert "cannot collect dictionary entries from " & $pat
|
||||
|
||||
proc collect(entries: var AndEntries; loc: Location; comp: CompoundPattern; optional: bool) =
|
||||
case comp.orKind
|
||||
of CompoundPatternKind.dict:
|
||||
for key, nsp in comp.dict.entries.pairs:
|
||||
if entries.hasKey(key):
|
||||
entries[key] = (asAny nsp, optional)
|
||||
else:
|
||||
entries[key] = (nsp, optional)
|
||||
else:
|
||||
raiseAssert "cannot collect dictionary entries from " & $comp
|
||||
|
||||
proc collect(entries: var AndEntries; loc: Location; pat: Pattern; optional: bool) =
|
||||
case pat.orKind
|
||||
of PatternKind.SimplePattern:
|
||||
collect(entries, loc, pat.simplepattern, optional)
|
||||
of PatternKind.CompoundPattern:
|
||||
collect(entries, loc, pat.compoundpattern, optional)
|
||||
|
||||
proc collect(entries: var AndEntries; loc: Location; def: Definition; optional: bool) =
|
||||
case def.orKind
|
||||
of DefinitionKind.or:
|
||||
collect(entries, loc, def.or.field0.pattern0.pattern, true)
|
||||
collect(entries, loc, def.or.field0.pattern1.pattern, true)
|
||||
for np in def.or.field0.patternN:
|
||||
collect(entries, loc, np.pattern, true)
|
||||
of DefinitionKind.and:
|
||||
collect(entries, loc, def.and.field0.pattern0.pattern, optional)
|
||||
collect(entries, loc, def.and.field0.pattern1.pattern, optional)
|
||||
for np in def.and.field0.patternN:
|
||||
collect(entries, loc, np.pattern, optional)
|
||||
of DefinitionKind.Pattern:
|
||||
collect(entries, loc, def.pattern, optional)
|
||||
|
||||
proc toDef(a: DefinitionAnd): Definition =
|
||||
Definition(orKind: DefinitionKind.and, `and`: a)
|
||||
|
||||
proc nimTypeOf(loc: Location; known: var TypeTable; name: string; andDef: DefinitionAnd): TypeSpec =
|
||||
var def = andDef.toDef
|
||||
if isDictionary(loc, def):
|
||||
result.node = nkBracketExpr.newTree(ident"Table", ident"Symbol", ident"Value")
|
||||
var
|
||||
recList = nkRecList.newNode
|
||||
entries: AndEntries
|
||||
collect(entries, loc, def, false)
|
||||
sort(entries) do (x, y: (Value, AndEntry)) -> int:
|
||||
preserves.cmp(x[0], y[0])
|
||||
# TODO: sort the entries
|
||||
var i = 0
|
||||
for key, (nsp, opt) in entries.pairs:
|
||||
recList.addField(loc, known, name, nsp, i, opt)
|
||||
inc(i)
|
||||
result.node = nkObjectTy.newTree(
|
||||
newEmpty(), newEmpty(), recList)
|
||||
else:
|
||||
result.node = ident"Value"
|
||||
|
||||
|
@ -864,7 +963,7 @@ proc collectRefImports(imports: var StringSet; loc: Location; def: Definition) =
|
|||
collectRefImports(imports, loc, na.pattern)
|
||||
of DefinitionKind.and:
|
||||
if isDictionary(loc, def):
|
||||
incl(imports, "std/tables")
|
||||
incl(imports, "std/options")
|
||||
collectRefImports(imports, loc, def.and.field0.pattern0.pattern)
|
||||
collectRefImports(imports, loc, def.and.field0.pattern1.pattern)
|
||||
for np in def.and.field0.patternN:
|
||||
|
|
Loading…
Reference in New Issue