diff --git a/implementations/javascript/packages/schema/src/gen/schema.ts b/implementations/javascript/packages/schema/src/gen/schema.ts index 737bb25..2513129 100644 --- a/implementations/javascript/packages/schema/src/gen/schema.ts +++ b/implementations/javascript/packages/schema/src/gen/schema.ts @@ -74,7 +74,7 @@ export type Pattern = ( export type SimplePattern = ( {"_variant": "any"} | {"_variant": "atom", "atomKind": AtomKind} | - {"_variant": "embedded"} | + {"_variant": "embedded", "interface": SimplePattern} | {"_variant": "lit", "value": _val} | {"_variant": "seqof", "pattern": SimplePattern} | {"_variant": "setof", "pattern": SimplePattern} | @@ -179,7 +179,7 @@ export namespace Pattern { export namespace SimplePattern { export function any(): SimplePattern {return {"_variant": "any"};}; export function atom(atomKind: AtomKind): SimplePattern {return {"_variant": "atom", "atomKind": atomKind};}; - export function embedded(): SimplePattern {return {"_variant": "embedded"};}; + export function embedded($interface: SimplePattern): SimplePattern {return {"_variant": "embedded", "interface": $interface};}; export function lit(value: _val): SimplePattern {return {"_variant": "lit", "value": value};}; export function seqof(pattern: SimplePattern): SimplePattern {return {"_variant": "seqof", "pattern": pattern};}; export function setof(pattern: SimplePattern): SimplePattern {return {"_variant": "setof", "pattern": pattern};}; @@ -562,56 +562,60 @@ export function toSimplePattern(v: _val): undefined | SimplePattern { if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp3: (null) | undefined; _tmp3 = _.is(v.label, $embedded) ? null : void 0; - if (_tmp3 !== void 0) {result = {"_variant": "embedded"};}; + if (_tmp3 !== void 0) { + let _tmp4: (SimplePattern) | undefined; + _tmp4 = toSimplePattern(v[0]); + if (_tmp4 !== void 0) {result = {"_variant": "embedded", "interface": _tmp4};}; + }; }; if (result === void 0) { if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { - let _tmp4: (null) | undefined; - _tmp4 = _.is(v.label, $lit) ? null : void 0; - if (_tmp4 !== void 0) { - let _tmp5: (_val) | undefined; - _tmp5 = v[0]; - if (_tmp5 !== void 0) {result = {"_variant": "lit", "value": _tmp5};}; + let _tmp5: (null) | undefined; + _tmp5 = _.is(v.label, $lit) ? null : void 0; + if (_tmp5 !== void 0) { + let _tmp6: (_val) | undefined; + _tmp6 = v[0]; + if (_tmp6 !== void 0) {result = {"_variant": "lit", "value": _tmp6};}; }; }; if (result === void 0) { if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { - let _tmp6: (null) | undefined; - _tmp6 = _.is(v.label, $seqof) ? null : void 0; - if (_tmp6 !== void 0) { - let _tmp7: (SimplePattern) | undefined; - _tmp7 = toSimplePattern(v[0]); - if (_tmp7 !== void 0) {result = {"_variant": "seqof", "pattern": _tmp7};}; + let _tmp7: (null) | undefined; + _tmp7 = _.is(v.label, $seqof) ? null : void 0; + if (_tmp7 !== void 0) { + let _tmp8: (SimplePattern) | undefined; + _tmp8 = toSimplePattern(v[0]); + if (_tmp8 !== void 0) {result = {"_variant": "seqof", "pattern": _tmp8};}; }; }; if (result === void 0) { if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { - let _tmp8: (null) | undefined; - _tmp8 = _.is(v.label, $setof) ? null : void 0; - if (_tmp8 !== void 0) { - let _tmp9: (SimplePattern) | undefined; - _tmp9 = toSimplePattern(v[0]); - if (_tmp9 !== void 0) {result = {"_variant": "setof", "pattern": _tmp9};}; + let _tmp9: (null) | undefined; + _tmp9 = _.is(v.label, $setof) ? null : void 0; + if (_tmp9 !== void 0) { + let _tmp10: (SimplePattern) | undefined; + _tmp10 = toSimplePattern(v[0]); + if (_tmp10 !== void 0) {result = {"_variant": "setof", "pattern": _tmp10};}; }; }; if (result === void 0) { if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { - let _tmp10: (null) | undefined; - _tmp10 = _.is(v.label, $dictof) ? null : void 0; - if (_tmp10 !== void 0) { - let _tmp11: (SimplePattern) | undefined; - _tmp11 = toSimplePattern(v[0]); - if (_tmp11 !== void 0) { - let _tmp12: (SimplePattern) | undefined; - _tmp12 = toSimplePattern(v[1]); - if (_tmp12 !== void 0) {result = {"_variant": "dictof", "key": _tmp11, "value": _tmp12};}; + let _tmp11: (null) | undefined; + _tmp11 = _.is(v.label, $dictof) ? null : void 0; + if (_tmp11 !== void 0) { + let _tmp12: (SimplePattern) | undefined; + _tmp12 = toSimplePattern(v[0]); + if (_tmp12 !== void 0) { + let _tmp13: (SimplePattern) | undefined; + _tmp13 = toSimplePattern(v[1]); + if (_tmp13 !== void 0) {result = {"_variant": "dictof", "key": _tmp12, "value": _tmp13};}; }; }; }; if (result === void 0) { - let _tmp13: (Ref) | undefined; - _tmp13 = toRef(v); - if (_tmp13 !== void 0) {result = {"_variant": "Ref", "value": _tmp13};}; + let _tmp14: (Ref) | undefined; + _tmp14 = toRef(v); + if (_tmp14 !== void 0) {result = {"_variant": "Ref", "value": _tmp14};}; }; }; }; @@ -626,7 +630,7 @@ export function fromSimplePattern(_v: SimplePattern): _val { switch (_v._variant) { case "any": {return $any;}; case "atom": {return _.Record($atom, [fromAtomKind(_v["atomKind"])]);}; - case "embedded": {return _.Record($embedded, []);}; + case "embedded": {return _.Record($embedded, [fromSimplePattern(_v["interface"])]);}; case "lit": {return _.Record($lit, [_v["value"]]);}; case "seqof": {return _.Record($seqof, [fromSimplePattern(_v["pattern"])]);}; case "setof": {return _.Record($setof, [fromSimplePattern(_v["pattern"])]);}; diff --git a/implementations/javascript/packages/schema/src/reader.ts b/implementations/javascript/packages/schema/src/reader.ts index 76e05ea..ba4bccb 100644 --- a/implementations/javascript/packages/schema/src/reader.ts +++ b/implementations/javascript/packages/schema/src/reader.ts @@ -1,4 +1,4 @@ -import { Reader, Annotated, Dictionary, is, peel, preserves, Record, strip, Tuple, Position, position, ReaderOptions, stringify, isCompound, KeyedDictionary, annotate, annotations } from '@preserves/core'; +import { Reader, Annotated, Dictionary, is, peel, preserves, Record, strip, Tuple, Position, position, stringify, isCompound, KeyedDictionary, annotate, annotations, isEmbedded, GenericEmbedded, genericEmbeddedTypeDecode } from '@preserves/core'; import { Input, Pattern, Schema, Definition, CompoundPattern, SimplePattern } from './meta'; import * as M from './meta'; import { SchemaSyntaxError } from './error'; @@ -46,18 +46,19 @@ function invalidPattern(name: string, item: Input, pos: Position | null): never } export type SchemaReaderOptions = { + name?: string | Position; readInclude?(includePath: string): string; }; -function _readSchema(source: string, options?: ReaderOptions): Array { - return new Reader(source, { - ... options ?? {}, - includeAnnotations: true +function _readSchema(source: string, options?: SchemaReaderOptions): Array { + return new Reader(source, { + name: options?.name, + includeAnnotations: true, + embeddedDecode: genericEmbeddedTypeDecode, }).readToEnd(); } -export function readSchema(source: string, - options?: ReaderOptions & SchemaReaderOptions): Schema +export function readSchema(source: string, options?: SchemaReaderOptions): Schema { const checked = checkSchema(parseSchema(_readSchema(source, options), options ?? {})); if (checked.ok) return checked.schema; @@ -65,8 +66,7 @@ export function readSchema(source: string, checked.problems.map(c => ' - ' + c).join('\n')); } -export function parseSchema(toplevelTokens: Array, - options: ReaderOptions & SchemaReaderOptions): Schema +export function parseSchema(toplevelTokens: Array, options: SchemaReaderOptions): Schema { let version: M.Version | undefined = void 0; let embeddedType: M.EmbeddedTypeName = M.EmbeddedTypeName.$false(); @@ -224,7 +224,6 @@ function parsePattern(name: symbol, body0: Array): Pattern { case 'string': return ks(M.SimplePattern.atom(M.AtomKind.String())); case 'bytes': return ks(M.SimplePattern.atom(M.AtomKind.ByteString())); case 'symbol': return ks(M.SimplePattern.atom(M.AtomKind.Symbol())); - case 'embedded': return ks(M.SimplePattern.embedded()); default: return ks((str[0] === '=') ? M.SimplePattern.lit(Symbol.for(str.slice(1))) : M.SimplePattern.Ref(parseRef(str, pos))); @@ -259,6 +258,8 @@ function parsePattern(name: symbol, body0: Array): Pattern { return ks(M.SimplePattern.dictof({ key: walkSimple(kp), value: walkSimple(vp) })); } else if (isCompound(item)) { return kf(); + } else if (isEmbedded(item)) { + return ks(M.SimplePattern.embedded(walkSimple(item.embeddedValue))); } else { return ks(M.SimplePattern.lit(strip(item))); } diff --git a/implementations/racket/preserves/preserves-schema/gen/schema.rkt b/implementations/racket/preserves/preserves-schema/gen/schema.rkt index e8c635c..e6dd4f9 100644 --- a/implementations/racket/preserves/preserves-schema/gen/schema.rkt +++ b/implementations/racket/preserves/preserves-schema/gen/schema.rkt @@ -1,5 +1,8 @@ (module gen-schema racket/base - (provide (all-defined-out)) + (provide (except-out (all-defined-out) :parse-embedded :embedded->preserves) + (rename-out + (:parse-embedded :parse-embedded:gen-schema) + (:embedded->preserves :embedded->preserves:gen-schema))) (define :parse-embedded values) (define :embedded->preserves values) (require preserves) @@ -62,7 +65,7 @@ (struct SimplePattern-setof (pattern) #:prefab) (struct SimplePattern-seqof (pattern) #:prefab) (struct SimplePattern-lit (value) #:prefab) - (struct SimplePattern-embedded () #:prefab) + (struct SimplePattern-embedded (interface) #:prefab) (struct SimplePattern-atom (atomKind) #:prefab) (struct SimplePattern-any () #:prefab) (define (SimplePattern? p) @@ -338,7 +341,12 @@ 'atom (list (app parse-AtomKind (and $atomKind (not (== eof))))))) (SimplePattern-atom $atomKind)) - ((and dest (record 'embedded (list))) (SimplePattern-embedded)) + ((and dest + (record + 'embedded + (list + (app parse-SimplePattern (and $interface (not (== eof))))))) + (SimplePattern-embedded $interface)) ((and dest (record 'lit (list $value))) (SimplePattern-lit $value)) ((and dest (record @@ -507,7 +515,8 @@ ((SimplePattern-any) 'any) ((SimplePattern-atom $atomKind) (record 'atom (list (AtomKind->preserves $atomKind)))) - ((SimplePattern-embedded) (record 'embedded (list))) + ((SimplePattern-embedded $interface) + (record 'embedded (list (SimplePattern->preserves $interface)))) ((SimplePattern-lit $value) (record 'lit (list $value))) ((SimplePattern-seqof $pattern) (record 'seqof (list (SimplePattern->preserves $pattern)))) diff --git a/implementations/racket/preserves/preserves-schema/parser.rkt b/implementations/racket/preserves/preserves-schema/parser.rkt index 8fdef8e..8f95779 100644 --- a/implementations/racket/preserves/preserves-schema/parser.rkt +++ b/implementations/racket/preserves/preserves-schema/parser.rkt @@ -63,7 +63,7 @@ [(AtomKind-String) 'string?] [(AtomKind-ByteString) 'bytes?] [(AtomKind-Symbol) 'symbol?])))] - [(SimplePattern-embedded) + [(SimplePattern-embedded _interface) `(embedded (app :parse-embedded ,(maybe-dest dest-pat-stx `(not (== eof)))))] [(SimplePattern-lit v) (maybe-dest dest-pat-stx (literal->pattern v))] [(SimplePattern-seqof variable-pat) diff --git a/implementations/racket/preserves/preserves-schema/reader.rkt b/implementations/racket/preserves/preserves-schema/reader.rkt index 4219b5d..a77f11f 100644 --- a/implementations/racket/preserves/preserves-schema/reader.rkt +++ b/implementations/racket/preserves/preserves-schema/reader.rkt @@ -121,7 +121,6 @@ ['string (ks (SimplePattern-atom (AtomKind-String)))] ['bytes (ks (SimplePattern-atom (AtomKind-ByteString)))] ['symbol (ks (SimplePattern-atom (AtomKind-Symbol)))] - ['embedded (ks (SimplePattern-embedded))] [(? symbol? sym) (define str (symbol->string sym)) (if (and (> (string-length str) 0) (string=? (substring str 0 1) "=")) @@ -138,6 +137,7 @@ (ks (SimplePattern-setof (walk-simple (car (set->list s)))))] [(hash-table ((peel-annotations '...) (peel-annotations '...)) (kp vp)) (ks (SimplePattern-dictof (walk-simple kp) (walk-simple vp)))] + [(embedded interface-pat) (ks (SimplePattern-embedded (walk-simple interface-pat)))] [(or (? list?) (? set?) (? dict?) (? record?)) (kf)] [(strip-annotations v) (ks (SimplePattern-lit v))])) diff --git a/implementations/racket/preserves/preserves-schema/schema.prs b/implementations/racket/preserves/preserves-schema/schema.prs index 9fba3e2..6602008 100644 --- a/implementations/racket/preserves/preserves-schema/schema.prs +++ b/implementations/racket/preserves/preserves-schema/schema.prs @@ -41,8 +41,8 @@ SimplePattern = ; special builtins: bool, float, double, int, string, bytes, symbol / - ; matches an embedded value in the input: embedded - / + ; matches an embedded value in the input: #!p + / ; =symbol, < any>, or plain non-symbol atom / diff --git a/implementations/racket/preserves/preserves-schema/type.rkt b/implementations/racket/preserves/preserves-schema/type.rkt index e6d9641..68a2ad4 100644 --- a/implementations/racket/preserves/preserves-schema/type.rkt +++ b/implementations/racket/preserves/preserves-schema/type.rkt @@ -78,7 +78,7 @@ (match (unwrap p) [(SimplePattern-any) (ty-value)] [(SimplePattern-atom _atomKind) (ty-value)] - [(SimplePattern-embedded) (ty-value)] + [(SimplePattern-embedded _interface) (ty-value)] [(SimplePattern-lit _value) (ty-unit)] [(SimplePattern-seqof pat) (ty-array (pattern-ty pat))] [(SimplePattern-setof pat) (ty-set (pattern-ty pat))] diff --git a/implementations/racket/preserves/preserves-schema/unparser.rkt b/implementations/racket/preserves/preserves-schema/unparser.rkt index 36041e6..b8ddd88 100644 --- a/implementations/racket/preserves/preserves-schema/unparser.rkt +++ b/implementations/racket/preserves/preserves-schema/unparser.rkt @@ -48,7 +48,7 @@ [(NamedSimplePattern_ n p) (pattern->unparser p (escape n))] [(SimplePattern-any) src-stx] [(SimplePattern-atom _) src-stx] - [(SimplePattern-embedded) `(embedded (:embedded->preserves ,src-stx))] + [(SimplePattern-embedded _interface) `(embedded (:embedded->preserves ,src-stx))] [(SimplePattern-lit v) `',v] [(SimplePattern-seqof variable-pat) `(for/list [(item (in-list ,src-stx))] ,(pattern->unparser variable-pat 'item))] diff --git a/preserves-schema.md b/preserves-schema.md index 77fc281..13792af 100644 --- a/preserves-schema.md +++ b/preserves-schema.md @@ -225,10 +225,12 @@ Specifying the name of a kind of `Atom` matches that kind of atom: AtomKindPattern = "bool" / "float" / "double" / "int" / "string" / "bytes" / "symbol" -Specifying `embedded` matches an `Embedded` value, following the -schema-wide `embeddedType`, if any: +Embedded input `Value`s are matched with embedded patterns. The +portion under the `#!` prefix is the *interface* schema for the +embedded value.[^interface-schema] The result of a match is an +instance of the schema-wide `embeddedType`, if one is supplied. - EmbeddedPattern = "embedded" + EmbeddedPattern = "#!" SimplePattern A literal pattern may be expressed in any of three ways: non-symbol atoms stand for themselves directly; symbols, prefixed with an equal @@ -256,6 +258,18 @@ Periods "`.`" in such symbols are special: - `Name` refers to the definition named `Name` in the current schema. - `Mod.Submod.Name` refers to definition `Name` in `Mod.Submod`, some other schema in the bundle. +[^interface-schema]: Embedded patterns are experimental. One + interpretation is that an embedded value denotes a reference to + some stateful actor in a potentially-distributed system, and that + the interface schema associated with an embedded value describes + the messages that may be sent to that actor. + + **Examples.** `#!any` may denote a reference to an Actor able to + receive any value as a message; `#!#t`, a reference to an Actor + expecting *only* the "true" message; `#!Session`, a reference to + an Actor expecting any message matching a schema defined as + `Session` in this file. + #### Compound patterns CompoundPattern = RecordPattern @@ -368,8 +382,8 @@ Simple patterns are as described above: ; special builtins: bool, float, double, int, string, bytes, symbol / - ; matches an embedded value in the input: embedded - / + ; matches an embedded value in the input: #!p + / ; =symbol, < any>, or plain non-symbol atom / @@ -515,7 +529,7 @@ metaschema. SimplePattern: ], ["atom", >]>>], - ["embedded", >], + ["embedded", >]>>], ["lit", ]>>], ["seqof", >]>>], ["setof", >]>>], @@ -595,7 +609,7 @@ definitions for the metaschema. export type SimplePattern = ( {"_variant": "any"} | {"_variant": "atom", "atomKind": AtomKind} | - {"_variant": "embedded"} | + {"_variant": "embedded", "interface": SimplePattern} | {"_variant": "lit", "value": _val} | {"_variant": "seqof", "pattern": SimplePattern} | {"_variant": "setof", "pattern": SimplePattern} | @@ -690,7 +704,7 @@ definitions for the metaschema. (struct SimplePattern-setof (pattern) #:prefab) (struct SimplePattern-seqof (pattern) #:prefab) (struct SimplePattern-lit (value) #:prefab) - (struct SimplePattern-embedded () #:prefab) + (struct SimplePattern-embedded (interface) #:prefab) (struct SimplePattern-atom (atomKind) #:prefab) (struct SimplePattern-any () #:prefab) @@ -708,5 +722,27 @@ definitions for the metaschema. - Should `include` accept URLs, to be able to retrieve schema from the web? + - It'd be nice to firm up the interpretation of embedded interface + schemas. I have in mind something like the + [higher-order contracts of Dimoulas](https://www2.ccs.neu.edu/racket/pubs/dissertation-dimoulas.pdf). + Essentially, a schema *is* a contract, and embedded + pointers-to-behaviour are like closures/channels/objects/etc, which + demand higher-order contracts. Future work could pin this down + further; also, consideration of *dependent* schemas (analogous to + dependent contracts) could be of interest. + + **Example.** In the following fragment, `#!Session` is the handle a + connected user uses to interact with a chatroom. In the + implementation, `Says` messages are dropped if their `who` doesn't + match the `uid` supplied in the `Join` assertion. It'd be nice to + capture that using a dependent schema, passing in the specific + `uid` value to the `Session` constructor, something like + `#!(Session uid)`. + + Join = . + Session = @observeSpeech / Says . + Says = . + + ## Notes diff --git a/schema/schema.bin b/schema/schema.bin index 2e9531a..b05f0a0 100644 --- a/schema/schema.bin +++ b/schema/schema.bin @@ -5,4 +5,4 @@ ByteString ByteString„„µ±Symbol´³lit³Symbol„„„„³ Definition´³orµµ±or´³rec´³lit³or„´³tupleµ´³tuple*µ´³named³pattern0´³refµ„³NamedAlternative„„´³named³pattern1´³refµ„³NamedAlternative„„„´³named³patternN´³seqof´³refµ„³NamedAlternative„„„„„„„„µ±and´³rec´³lit³and„´³tupleµ´³tuple*µ´³named³pattern0´³refµ„³ NamedPattern„„´³named³pattern1´³refµ„³ NamedPattern„„„´³named³patternN´³seqof´³refµ„³ NamedPattern„„„„„„„„µ±Pattern´³refµ„³Pattern„„„„³ ModulePath´³seqof´³atom³Symbol„„³ Definitions´³dictof´³atom³Symbol„´³refµ„³ -Definition„„³ NamedPattern´³orµµ±named´³refµ„³NamedSimplePattern_„„µ± anonymous´³refµ„³Pattern„„„„³ SimplePattern´³orµµ±any´³lit³any„„µ±atom´³rec´³lit³atom„´³tupleµ´³named³atomKind´³refµ„³AtomKind„„„„„„µ±embedded´³rec´³lit³embedded„´³tupleµ„„„„µ±lit´³rec´³lit³lit„´³tupleµ´³named³value³any„„„„„µ±seqof´³rec´³lit³seqof„´³tupleµ´³named³pattern´³refµ„³ SimplePattern„„„„„„µ±setof´³rec´³lit³setof„´³tupleµ´³named³pattern´³refµ„³ SimplePattern„„„„„„µ±dictof´³rec´³lit³dictof„´³tupleµ´³named³key´³refµ„³ SimplePattern„„´³named³value´³refµ„³ SimplePattern„„„„„„µ±Ref´³refµ„³Ref„„„„³CompoundPattern´³orµµ±rec´³rec´³lit³rec„´³tupleµ´³named³label´³refµ„³ NamedPattern„„´³named³fields´³refµ„³ NamedPattern„„„„„„µ±tuple´³rec´³lit³tuple„´³tupleµ´³named³patterns´³seqof´³refµ„³ NamedPattern„„„„„„„µ±tuple*´³rec´³lit³tuple*„´³tupleµ´³named³fixed´³seqof´³refµ„³ NamedPattern„„„´³named³variable´³refµ„³NamedSimplePattern„„„„„„µ±dict´³rec´³lit³dict„´³tupleµ´³named³entries´³refµ„³DictionaryEntries„„„„„„„„³EmbeddedTypeName´³orµµ±Ref´³refµ„³Ref„„µ±false´³lit€„„„„³NamedAlternative´³tupleµ´³named³ variantLabel´³atom³String„„´³named³pattern´³refµ„³Pattern„„„„³DictionaryEntries´³dictof³any´³refµ„³NamedSimplePattern„„³NamedSimplePattern´³orµµ±named´³refµ„³NamedSimplePattern_„„µ± anonymous´³refµ„³ SimplePattern„„„„³NamedSimplePattern_´³rec´³lit³named„´³tupleµ´³named³name´³atom³Symbol„„´³named³pattern´³refµ„³ SimplePattern„„„„„„³ embeddedType€„„ \ No newline at end of file +Definition„„³ NamedPattern´³orµµ±named´³refµ„³NamedSimplePattern_„„µ± anonymous´³refµ„³Pattern„„„„³ SimplePattern´³orµµ±any´³lit³any„„µ±atom´³rec´³lit³atom„´³tupleµ´³named³atomKind´³refµ„³AtomKind„„„„„„µ±embedded´³rec´³lit³embedded„´³tupleµ´³named³ interface´³refµ„³ SimplePattern„„„„„„µ±lit´³rec´³lit³lit„´³tupleµ´³named³value³any„„„„„µ±seqof´³rec´³lit³seqof„´³tupleµ´³named³pattern´³refµ„³ SimplePattern„„„„„„µ±setof´³rec´³lit³setof„´³tupleµ´³named³pattern´³refµ„³ SimplePattern„„„„„„µ±dictof´³rec´³lit³dictof„´³tupleµ´³named³key´³refµ„³ SimplePattern„„´³named³value´³refµ„³ SimplePattern„„„„„„µ±Ref´³refµ„³Ref„„„„³CompoundPattern´³orµµ±rec´³rec´³lit³rec„´³tupleµ´³named³label´³refµ„³ NamedPattern„„´³named³fields´³refµ„³ NamedPattern„„„„„„µ±tuple´³rec´³lit³tuple„´³tupleµ´³named³patterns´³seqof´³refµ„³ NamedPattern„„„„„„„µ±tuple*´³rec´³lit³tuple*„´³tupleµ´³named³fixed´³seqof´³refµ„³ NamedPattern„„„´³named³variable´³refµ„³NamedSimplePattern„„„„„„µ±dict´³rec´³lit³dict„´³tupleµ´³named³entries´³refµ„³DictionaryEntries„„„„„„„„³EmbeddedTypeName´³orµµ±Ref´³refµ„³Ref„„µ±false´³lit€„„„„³NamedAlternative´³tupleµ´³named³ variantLabel´³atom³String„„´³named³pattern´³refµ„³Pattern„„„„³DictionaryEntries´³dictof³any´³refµ„³NamedSimplePattern„„³NamedSimplePattern´³orµµ±named´³refµ„³NamedSimplePattern_„„µ± anonymous´³refµ„³ SimplePattern„„„„³NamedSimplePattern_´³rec´³lit³named„´³tupleµ´³named³name´³atom³Symbol„„´³named³pattern´³refµ„³ SimplePattern„„„„„„³ embeddedType€„„ \ No newline at end of file diff --git a/schema/schema.prs b/schema/schema.prs index 9fba3e2..6602008 100644 --- a/schema/schema.prs +++ b/schema/schema.prs @@ -41,8 +41,8 @@ SimplePattern = ; special builtins: bool, float, double, int, string, bytes, symbol / - ; matches an embedded value in the input: embedded - / + ; matches an embedded value in the input: #!p + / ; =symbol, < any>, or plain non-symbol atom /