diff --git a/.gitmodules b/.gitmodules
index d556bfa..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "upstream"]
-	path = upstream
-	url = https://gitlab.com/preserves/preserves.git
diff --git a/schema.bin b/schema.bin
new file mode 100644
index 0000000..a248064
--- /dev/null
+++ b/schema.bin
@@ -0,0 +1,8 @@
+´³schema·³version‘³definitions·³Ref´³rec´³lit³ref„´³tupleµ´³named³module´³refµ„³
+ModulePath„„´³named³name´³atom³Symbol„„„„„³Bundle´³rec´³lit³bundle„´³tupleµ´³named³modules´³refµ„³Modules„„„„„³Schema´³rec´³lit³schema„´³tupleµ´³dict·³version´³named³version´³refµ„³Version„„³definitions´³named³definitions´³refµ„³Definitions„„³embeddedType´³named³embeddedType´³refµ„³EmbeddedTypeName„„„„„„„³Binding´³rec´³lit³named„´³tupleµ´³named³name´³atom³Symbol„„´³named³pattern´³refµ„³
SimplePattern„„„„„³Modules´³dictof´³refµ„³
+ModulePath„´³refµ„³Schema„„³Pattern´³orµµ±
SimplePattern´³refµ„³
SimplePattern„„µ±CompoundPattern´³refµ„³CompoundPattern„„„„³Version´³lit‘„³AtomKind´³orµµ±Boolean´³lit³Boolean„„µ±Float´³lit³Float„„µ±Double´³lit³Double„„µ±
SignedInteger´³lit³
SignedInteger„„µ±String´³lit³String„„µ±
+ByteString´³lit³
+ByteString„„µ±Symbol´³lit³Symbol„„„„³
+Definition´³orµµ±or´³rec´³lit³or„´³tupleµ´³tuplePrefixµ´³named³pattern0´³refµ„³NamedAlternative„„´³named³pattern1´³refµ„³NamedAlternative„„„´³named³patternN´³seqof´³refµ„³NamedAlternative„„„„„„„„µ±and´³rec´³lit³and„´³tupleµ´³tuplePrefixµ´³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µ„³Binding„„µ±	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„„„„„„„µ±tuplePrefix´³rec´³lit³tuplePrefix„´³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µ„³Binding„„µ±	anonymous´³refµ„³
SimplePattern„„„„„³embeddedType€„„
\ No newline at end of file
diff --git a/schema.prs b/schema.prs
new file mode 100644
index 0000000..5db39dc
--- /dev/null
+++ b/schema.prs
@@ -0,0 +1,92 @@
+@<EmacsMode "-*- preserves -*-">
+
+; TODO: some kind of constants
+; TODO: rename "version" to "schema-version" ?
+
+version 1 .
+
+Bundle = <bundle @modules Modules>.
+Modules = { ModulePath: Schema ...:... }.
+
+Schema = <schema {
+  version: Version
+  embeddedType: EmbeddedTypeName
+  definitions: Definitions
+}>.
+
+; version 1 .
+Version = 1 .
+
+EmbeddedTypeName = Ref / #f.
+
+Definitions = { symbol: Definition ...:... }.
+
+Definition =
+  ; Pattern / Pattern / ...
+  / <or [@pattern0 NamedAlternative @pattern1 NamedAlternative @patternN NamedAlternative ...]>
+
+  ; Pattern & Pattern & ...
+  / <and [@pattern0 NamedPattern @pattern1 NamedPattern @patternN NamedPattern ...]>
+
+  ; Pattern
+  / Pattern
+.
+
+Pattern = SimplePattern / CompoundPattern .
+
+SimplePattern =
+  ; any
+  / =any
+
+  ; special builtins: bool, float, double, int, string, bytes, symbol
+  / <atom @atomKind AtomKind>
+
+  ; matches an embedded value in the input: #!p
+  / <embedded @interface SimplePattern>
+
+  ; =symbol, <<lit> any>, or plain non-symbol atom
+  / <lit @value any>
+
+  ; [p ...] ----> <seqof <ref p>>; see also tuplePrefix below.
+  / <seqof @pattern SimplePattern>
+
+  ; #{p} ----> <setof <ref p>>
+  / <setof @pattern SimplePattern>
+
+  ; {k: v, ...:...} ----> <dictof <ref k> <ref v>>
+  / <dictof @key SimplePattern @value SimplePattern>
+
+  ; symbol, symbol.symbol, symbol.symbol.symbol, ...
+  / Ref
+.
+
+CompoundPattern =
+  ; <label a b c> ----> <rec <lit label> <tuple [<ref a> <ref b> <ref c>]>>
+  ; except for record labels
+  ; <<rec> x y> ---> <rec <ref x> <ref y>>
+  / <rec @label NamedPattern @fields NamedPattern>
+
+  ; [a b c] ----> <tuple [<ref a> <ref b> <ref c>]>
+  / <tuple @patterns [NamedPattern ...]>
+
+  ; [a b c ...] ----> <tuplePrefix [<ref a> <ref b>] <seqof <ref c>>>
+  ; TODO: [@fixed0 NamedPattern @fixedN NamedPattern ...]
+  / <tuplePrefix @fixed [NamedPattern ...] @variable NamedSimplePattern>
+
+  ; {a: b, c: d} ----> <dict {a: <ref b>, c: <ref d>}>
+  / <dict @entries DictionaryEntries>
+.
+
+DictionaryEntries = { any: NamedSimplePattern ...:... }.
+
+AtomKind = =Boolean / =Float / =Double / =SignedInteger / =String / =ByteString / =Symbol .
+
+NamedAlternative = [@variantLabel string @pattern Pattern].
+
+NamedSimplePattern = @named Binding / @anonymous SimplePattern .
+NamedPattern = @named Binding / @anonymous Pattern .
+
+Binding = <named @name symbol @pattern SimplePattern>.
+
+Ref = <ref @module ModulePath @name symbol>.
+ModulePath = [symbol ...].
diff --git a/src/preserves/preserves_schema_nim.nim b/src/preserves/preserves_schema_nim.nim
index 944f975..6290977 100644
--- a/src/preserves/preserves_schema_nim.nim
+++ b/src/preserves/preserves_schema_nim.nim
@@ -4,7 +4,7 @@
 ## This module implements Nim code generation from Preserves schemas.
 # This module imports code that it generates! After making any changes here
 # the schema module must be regenerated!
-# nim c -r ./preserves_schema_nim ../../upstream/schema/schema.bin
+# nim c -r ./preserves_schema_nim ../../schema.bin
 
 import std/[hashes, sequtils, strutils, sets, tables]
 
diff --git a/src/preserves/schema.nim b/src/preserves/schema.nim
index a4ed819..babccba 100644
--- a/src/preserves/schema.nim
+++ b/src/preserves/schema.nim
@@ -52,7 +52,7 @@ type
         `ref`*: Ref
 
 
-  `AtomKind`* {.preservesOr.} = enum
+  `AtomKind`* {.preservesOr, pure.} = enum
     `Boolean`, `Float`, `Double`, `SignedInteger`, `String`, `ByteString`,
     `Symbol`
   Definitions*[E] = Table[string, Definition[E]]
@@ -162,8 +162,8 @@ type
     `pattern`*: Pattern[E]
 
   SchemaData*[E] {.preservesDictionary.} = ref object
-    `embeddedType`*: EmbeddedTypeName
     `version`* {.preservesLiteral: "1".}: bool
+    `embeddedType`*: EmbeddedTypeName
     `definitions`*: Definitions[E]
 
   Schema*[E] {.preservesRecord: "schema".} = ref object
@@ -194,7 +194,7 @@ proc `$`*[E](x: Bundle[E] | CompoundPattern[E] | Modules[E] | Definitions[E] |
     Schema[E] |
     Pattern[E] |
     Binding[E]): string =
-  `$`(toPreserve(x))
+  `$`(toPreserve(x, E))
 
 proc encode*[E](x: Bundle[E] | CompoundPattern[E] | Modules[E] | Definitions[E] |
     DictionaryEntries[E] |
diff --git a/tests/test_schemas.nim b/tests/test_schemas.nim
index 6f12e07..1d961ef 100644
--- a/tests/test_schemas.nim
+++ b/tests/test_schemas.nim
@@ -10,8 +10,8 @@ if dirExists "tests": setCurrentDir "tests"
 suite "schema":
 
   const
-    binPath = "../upstream/schema/schema.bin"
-    textPath = "../upstream/schema/schema.prs"
+    binPath = "../schema.bin"
+    textPath = "../schema.prs"
 
   test "convertability":
     if not fileExists(binPath): skip()
diff --git a/upstream b/upstream
deleted file mode 160000
index 2ff489d..0000000
--- a/upstream
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 2ff489d9753169ef57446d22cfd4722ca1264e2e
