diff --git a/preserves.nimble b/preserves.nimble index 0f5f150..941d976 100644 --- a/preserves.nimble +++ b/preserves.nimble @@ -1,6 +1,6 @@ # Package -version = "20230516" +version = "20230517" author = "Emery Hemingway" description = "data model and serialization format" license = "Unlicense" diff --git a/src/preserves/Tupfile b/src/preserves/Tupfile index ba0890c..84f7fb2 100644 --- a/src/preserves/Tupfile +++ b/src/preserves/Tupfile @@ -1,4 +1,4 @@ include_rules -: foreach preserves_schema_nim.nim schemac.nim |> !nim |> $(BIN_DIR)/%B | $(BIN_DIR)/<%B> NIM_FLAGS += --path:$(TUP_CWD)/.. +: foreach preserves_schema_nim.nim schemac.nim schemaparse.nim |> !nim_bin |> $(BIN_DIR)/%B | $(BIN_DIR)/<%B> : foreach *hooks.nim |> !nim_check |> diff --git a/src/preserves/preserves_schema_nim.nim b/src/preserves/preserves_schema_nim.nim index f4fa01f..6b83dae 100644 --- a/src/preserves/preserves_schema_nim.nim +++ b/src/preserves/preserves_schema_nim.nim @@ -240,6 +240,7 @@ proc isRecursive(loc: Location; p: Definition|DefinitionOr|Pattern|CompoundPatte recursive in attrs(loc, p) proc isLiteral(loc: Location; def: Definition): bool {.gcsafe.} +proc isLiteral(loc: Location; pat: Pattern): bool {.gcsafe.} proc isLiteral(loc: Location; sp: SimplePattern): bool = case sp.orKind @@ -253,6 +254,13 @@ proc isLiteral(loc: Location; sp: SimplePattern): bool = result = isLiteral(loc, sp.embedded.interface) else: discard +proc isLiteral(loc: Location; np: NamedPattern): bool = + case np.orKind + of NamedPatternKind.named: + isLiteral(loc, np.named.pattern) + of NamedPatternKind.anonymous: + isLiteral(loc, np.anonymous) + proc isLiteral(loc: Location; pat: Pattern): bool = case pat.orKind of PatternKind.SimplePattern: @@ -303,7 +311,8 @@ proc isSymbolEnum(loc: Location; sp: SimplePattern): bool = proc isAny(loc: Location; def: Definition): bool = case def.orKind of DefinitionKind.Pattern: - if def.pattern.orKind == PatternKind.SimplePattern: + case def.pattern.orKind + of PatternKind.SimplePattern: case def.pattern.simplePattern.orKind of SimplePatternKind.Ref: var (loc, def) = deref(loc, def.pattern.simplePattern.ref) @@ -311,6 +320,11 @@ proc isAny(loc: Location; def: Definition): bool = of SimplePatternKind.any: result = true else: discard + of PatternKind.CompoundPattern: + case def.pattern.compoundpattern.orKind + 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 @@ -458,15 +472,18 @@ proc typeDef(loc: Location; name: string; pat: Pattern; ty: PNode): PNode = of PatternKind.CompoundPattern: case pat.compoundPattern.orKind of CompoundPatternKind.rec: - nn(nkTypeDef, - nn(nkPragmaExpr, - id, - nn(nkPragma, - nn(nkExprColonExpr, - ident"preservesRecord", - PNode(kind: nkStrLit, strVal: pat.compoundPattern.rec.label.idStr)))), - embedParams, - ty) + if isLiteral(loc, pat.compoundPattern.rec.label): + nn(nkTypeDef, + nn(nkPragmaExpr, + id, + nn(nkPragma, + nn(nkExprColonExpr, + ident"preservesRecord", + PNode(kind: nkStrLit, strVal: pat.compoundPattern.rec.label.idStr)))), + embedParams, + ty) + else: + nn(nkTypeDef, name.ident.toExport, embedParams, ty) of CompoundPatternKind.tuple, CompoundPatternKind.tuplePrefix: nn(nkTypeDef, nn(nkPragmaExpr, id, nn(nkPragma, ident"preservesTuple")), @@ -584,12 +601,18 @@ proc nimTypeOf(loc: Location; known: var TypeTable; nsp: NamedSimplePattern; nam of NamedsimplepatternKind.anonymous: nimTypeOf(loc, known, nsp.anonymous, name) +proc nimTypeOf(loc: Location; known: var TypeTable; rec: CompoundPatternRec; name: string): TypeSpec = + if isLiteral(loc, rec.label): + result.node = nn(nkObjectTy, + newEmpty(), newEmpty(), + nn(nkRecList).addFields(loc, known, rec.fields.pattern, name)) + else: + result.node = preserveIdent(loc.schema) + proc nimTypeOf(loc: Location; known: var TypeTable; cp: CompoundPattern; name: string): TypeSpec = case cp.orKind of CompoundPatternKind.`rec`: - result.node = nn(nkObjectTy, - newEmpty(), newEmpty(), - nn(nkRecList).addFields(loc, known, cp.rec.fields.pattern, name)) + result = nimTypeOf(loc, known, cp.rec, name) of CompoundPatternKind.`tuple`, CompoundPatternKind.`tupleprefix`: result.node = nn(nkObjectTy, newEmpty(), newEmpty(),