···11+# This file is generated by dune, edit dune-project instead
22+opam-version: "2.0"
33+synopsis: "A short synopsis"
44+description: "A longer description"
55+maintainer: ["Maintainer Name <maintainer@example.com>"]
66+authors: ["Author Name <author@example.com>"]
77+license: "LICENSE"
88+tags: ["add topics" "to describe" "your" "project"]
99+homepage: "https://github.com/username/reponame"
1010+doc: "https://url/to/documentation"
1111+bug-reports: "https://github.com/username/reponame/issues"
1212+depends: [
1313+ "dune" {>= "3.22"}
1414+ "ocaml"
1515+ "odoc" {with-doc}
1616+]
1717+build: [
1818+ ["dune" "subst"] {dev}
1919+ [
2020+ "dune"
2121+ "build"
2222+ "-p"
2323+ name
2424+ "-j"
2525+ jobs
2626+ "@install"
2727+ "@runtest" {with-test}
2828+ "@doc" {with-doc}
2929+ ]
3030+]
3131+dev-repo: "git+https://github.com/username/reponame.git"
3232+x-maintenance-intent: ["(latest)"]
+26
dune-project
···11+(lang dune 3.22)
22+33+(name concrete-syntax)
44+55+(generate_opam_files true)
66+77+(source
88+ (github username/reponame))
99+1010+(authors "Author Name <author@example.com>")
1111+1212+(maintainers "Maintainer Name <maintainer@example.com>")
1313+1414+(license LICENSE)
1515+1616+(documentation https://url/to/documentation)
1717+1818+(package
1919+ (name concrete-syntax)
2020+ (synopsis "A short synopsis")
2121+ (description "A longer description")
2222+ (depends ocaml)
2323+ (tags
2424+ ("add topics" "to describe" your project)))
2525+2626+; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html
+31
lib/Algebra.ml
···11+module type Monoid = sig
22+ type t
33+ val empty : t
44+ val append : t -> t -> t
55+end
66+77+module type MonoidHom = sig
88+ module S : Monoid
99+ module T : Monoid
1010+ val hom : S.t -> T.t
1111+end
1212+1313+module String_monoid : Monoid with type t = string = struct
1414+ type t = string
1515+ let empty = ""
1616+ let append = ( ^ )
1717+end
1818+1919+module Int_additive_monoid : Monoid with type t = int = struct
2020+ type t = int
2121+ let empty = 0
2222+ let append = ( + )
2323+end
2424+2525+module String_length_hom :
2626+ MonoidHom with module S = String_monoid and module T = Int_additive_monoid =
2727+struct
2828+ module S = String_monoid
2929+ module T = Int_additive_monoid
3030+ let hom = String.length
3131+end
+74
lib/Concrete_syntax.ml
···11+open Algebra
22+33+module type S = sig
44+ type content
55+ type offset
66+ type token_info
77+ type node_info
88+99+ type token = {info: token_info; content: content}
1010+ type 'a node = {info: node_info; children: 'a list}
1111+ type 'a layer = Token of token | Node of 'a node
1212+ type tree = Tree of tree layer
1313+1414+ type cursor = {offset: offset; layer: cursor layer}
1515+1616+ val localise_tree : offset:offset -> tree -> cursor * offset
1717+ val tree_content : tree -> content
1818+end
1919+2020+module type Input = sig
2121+ module Content : MonoidHom
2222+ type token_info
2323+ type node_info
2424+end
2525+2626+module Make (I : Input) : S = struct
2727+ type content = I.Content.S.t
2828+ type offset = I.Content.T.t
2929+ type token_info = I.token_info
3030+ type node_info = I.node_info
3131+3232+ type token = {info: token_info; content: content}
3333+ type 'a node = {info: node_info; children: 'a list}
3434+ type 'a layer = Token of token | Node of 'a node
3535+ type tree = Tree of tree layer
3636+3737+ type cursor = {offset: offset; layer: cursor layer}
3838+3939+ let rec localise_tree ~offset (Tree layer) : cursor * offset =
4040+ let layer, new_offset = localise_layer ~offset layer in
4141+ ({offset; layer}, new_offset)
4242+4343+ and localise_children ~offset : tree list -> cursor list * offset = function
4444+ | [] -> ([], offset)
4545+ | child :: children ->
4646+ let head_cursor, offset = localise_tree ~offset child in
4747+ let tail_cursors, offset = localise_children ~offset children in
4848+ (head_cursor :: tail_cursors, offset)
4949+5050+ and localise_node ~offset (node : tree node) : cursor node * offset =
5151+ let children, offset = localise_children ~offset node.children in
5252+ ({node with children}, offset)
5353+5454+ and localise_layer ~offset : tree layer -> cursor layer * offset = function
5555+ | Token tok ->
5656+ (Token tok, I.Content.T.append offset (I.Content.hom tok.content))
5757+ | Node node ->
5858+ let node, offset = localise_node ~offset node in
5959+ (Node node, offset)
6060+6161+ let rec tree_content (Tree layer) = tree_layer_content layer
6262+6363+ and tree_layer_content : tree layer -> content = function
6464+ | Token tok -> tok.content
6565+ | Node node ->
6666+ List.fold_left
6767+ (fun acc tree -> I.Content.S.append acc (tree_content tree))
6868+ I.Content.S.empty node.children
6969+7070+ and tree_node_content (node : tree node) : content =
7171+ List.fold_left
7272+ (fun acc tree -> I.Content.S.append acc (tree_content tree))
7373+ I.Content.S.empty node.children
7474+end