From f61adcb602205ef8e4c71405019d8260de346fb1 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 28 Dec 2023 18:34:40 +0200 Subject: [PATCH] preserves_schema_nim: use Table for And types --- src/preserves/preserves_schema_nim.nim | 70 +++++++++++++++++++------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/src/preserves/preserves_schema_nim.nim b/src/preserves/preserves_schema_nim.nim index 3cd7538..952c502 100644 --- a/src/preserves/preserves_schema_nim.nim +++ b/src/preserves/preserves_schema_nim.nim @@ -192,31 +192,26 @@ proc attrs(loc: Location; pat: Pattern; seen: RefSet): Attributes = of PatternKind.CompoundPattern: attrs(loc, pat.compoundPattern, seen) -proc attrs(loc: Location; orDef: DefinitionOr; seen: RefSet): Attributes = - result = attrs(loc, orDef.field0.pattern0, seen) + attrs(loc, orDef.field0.pattern1, seen) - for p in orDef.field0.patternN: +proc attrs(loc: Location; def: DefinitionOr|DefinitionAnd; seen: RefSet): Attributes = + result = attrs(loc, def.field0.pattern0, seen) + attrs(loc, def.field0.pattern1, seen) + for p in def.field0.patternN: result = result + attrs(loc, p, seen) proc attrs(loc: Location; def: Definition; seen: RefSet): Attributes = case def.orKind of DefinitionKind.or: result = attrs(loc, def.or, seen) - of DefinitionKind.and: - result = - attrs(loc, def.and.field0.pattern0, seen) + - attrs(loc, def.and.field0.pattern1, seen) - for p in def.and.field0.patternN: - result = result + attrs(loc, p, seen) + of DefinitionKind.and: result = attrs(loc, def.and, seen) of DefinitionKind.Pattern: result = attrs(loc, def.pattern, seen) -proc attrs(loc: Location; p: Definition|DefinitionOr|Pattern|CompoundPattern|SimplePattern): Attributes = +proc attrs(loc: Location; p: Definition|DefinitionOr|DefinitionAnd|Pattern|CompoundPattern|SimplePattern): Attributes = var seen: RefSet attrs(loc, p, seen) -proc isEmbedded(loc: Location; p: Definition|DefinitionOr|Pattern|CompoundPattern): bool = +proc isEmbedded(loc: Location; p: Definition|DefinitionOr|DefinitionAnd|Pattern|CompoundPattern|SimplePattern): bool = embedded in attrs(loc, p) -proc isRecursive(loc: Location; p: Definition|DefinitionOr|Pattern|CompoundPattern): bool = +proc isRecursive(loc: Location; p: Definition|DefinitionOr|DefinitionAnd|Pattern|CompoundPattern): bool = recursive in attrs(loc, p) proc isLiteral(loc: Location; def: Definition): bool {.gcsafe.} @@ -288,6 +283,35 @@ proc isSymbolEnum(loc: Location; sp: SimplePattern): bool = result = isSymbolEnum(loc, def) else: discard +proc isDictionary(loc: Location; def: Definition): bool {.gcsafe.} + +proc isDictionary(loc: Location; pat: Pattern): bool = + case pat.orKind + of PatternKind.SimplePattern: + case pat.simplePattern.orKind + of SimplePatternKind.Ref: + var (loc, def) = deref(loc, pat.simplePattern.ref) + result = isDictionary(loc, def) + of SimplePatternKind.dictof: + result = true + else: discard + of PatternKind.CompoundPattern: + case pat.compoundpattern.orKind + of CompoundPatternKind.dict: + result = true + else: discard + +proc isDictionary(loc: Location; defAnd: DefinitionAnd): bool = + result = isDictionary(loc, defAnd.field0.pattern0.pattern) + +proc isDictionary(loc: Location; def: Definition): bool = + case def.orKind + of DefinitionKind.Pattern: + result = isDictionary(loc, def.pattern) + of DefinitionKind.and: + result = isDictionary(loc, def.and) + else: discard + proc isAny(loc: Location; def: Definition): bool = case def.orKind of DefinitionKind.Pattern: @@ -305,9 +329,6 @@ proc isAny(loc: Location; def: Definition): bool = of CompoundPatternKind.rec: result = not isLiteral(loc, def.pattern.compoundpattern.rec.label) else: discard - of DefinitionKind.and: - # not actually "any" but it will be a Preserve[E] type - result = true else: discard proc typeIdent(atom: AtomKind): PNode = @@ -482,10 +503,13 @@ proc typeDef(loc: Location; name: string; def: Definition; ty: PNode): PNode = newEmpty(), ty) of DefinitionKind.and: + let pragma = newEmpty() nkTypeDef.newTree( - name.ident.toExport, + nkPragmaExpr.newTree( + name.ident.accQuote.toExport, + pragma), newEmpty(), - ident"Value") + ty) of DefinitionKind.Pattern: typeDef(loc, name, def.pattern, ty) @@ -577,7 +601,9 @@ proc addFields(recList: PNode; loc: Location; known: var TypeTable; parentName: nkPragma.newTree(ident"preservesTupleTail")), variableType.node, variableType.isEmbedded) - else: raiseAssert "not adding fields for " #& $cp + of CompoundPatternKind.dict: + for nameVal, nsp in cp.dict.entries: + recList.addField(loc, known, $nameVal, nsp) reclist proc addFields(recList: PNode; loc: Location; known: var TypeTable; name: string; pat: SimplePattern): PNode {.discardable.} = @@ -705,6 +731,12 @@ proc nimTypeOf(loc: Location; known: var TypeTable; name: string; orDef: Definit if result.node.kind == nkObjectTy and (recursive in attrs(loc, orDef)): result.node = nkRefTy.newTree(result.node) +proc nimTypeOf(loc: Location; known: var TypeTable; name: string; def: DefinitionAnd): TypeSpec = + if isDictionary(loc, def): + result.node = nkBracketExpr.newTree(ident"Table", ident"Symbol", ident"Value") + else: + result.node = ident"Value" + proc nimTypeOf(loc: Location; known: var TypeTable; name: string; def: Definition): TypeSpec = case def.orKind of DefinitionKind.or: @@ -762,6 +794,8 @@ proc collectRefImports(imports: var StringSet; loc: Location; def: Definition) = for na in def.or.field0.patternN: collectRefImports(imports, loc, na.pattern) of DefinitionKind.and: + if isDictionary(loc, def): + incl(imports, "std/tables") collectRefImports(imports, loc, def.and.field0.pattern0.pattern) collectRefImports(imports, loc, def.and.field0.pattern1.pattern) for np in def.and.field0.patternN: