diff --git a/.ikc3_history b/.ikc3_history
index 13d2a34..dda62a2 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,4 +1,3 @@
-a = 1; 2
a = ?; 2
a
a = ?; 2
@@ -97,3 +96,4 @@ List.sort([1, 2, 3, 4])
List.sort([4, 3, 2, 1])
List.sort(["1. a", "2. bc", "3. cde", "4. fghi"])
List.sort(["1. abcd", "2. efg", "3. hi", "4. j"])
+license()
diff --git a/doc/1 KC3/1.1 Introduction.en.md b/doc/1 KC3/1.1 Introduction.en.md
deleted file mode 100644
index 00e45ab..0000000
--- a/doc/1 KC3/1.1 Introduction.en.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# 1 Introduction
-
-KC3 is currently a programming language project, inspired by C, Elixir
-and Common Lisp. It could be described as C with Elixir modules,
-pattern matching, and a semantic object system. The idea is to plug
-modules, closures, pattern matching, a graph database and
-metaprogramming into C99 with an extremely small set of dependencies.
-
-Supported operating systems (additionnal dependencies) :
- - BSD
- - Linux (libbsd, libmd)
- - MacOS X (libmd)
- - Windows (MSys2)
-
-Supported architectures :
- - aarch64 (arm64, Apple M1, Apple M2)
- - amd64
- - i386
- - sparc64
-
-
-## 1.1 Modules
-
-Everything in KC3 is in a module. A module is a namespace,
-and is named with a symbol starting with a uppercase character.
-For instance `Sym` and `Str` are valid module names.
-
-Each module can define a type and a module name can also be a
-type name if the corresponding module defines a type.
-
-The module can also include definitions for functions for
-operating on the module type or other types.
-
-The default module is `KC3`, which is defined as facts (triples)
-in `lib/kc3/0.1/kc3.facts`.
-
-
-## 1.2 Data types
-
-Basic data types in KC3 are :
- - Strings : `Str`, e.g. `"Hello, world !"`
- - Symbols : `Sym`, e.g. `:hello` or `Hello`
- - Booleans : `Bool`, `true` or `false`
- - Numbers
- - Integers
- - Small integers
- - Signed small integers : `S8`, `S16`, `S32`, `S64`, `Sw`
- - Unsigned small integers : `U8`, `U16`, `U32`, `U64`, `Uw`
- - Large integers : `Integer`
- - Rational numbers (fractions of integers) : `Ratio`, e.g. `-2/3`
- - Floating point numbers : `F32`, `F64`, `F128`
- - Complex numbers (i = √(-1)) : `Complex`, e.g. `1 +i 2`
- - Lists : `List`, e.g. `[1, 2, 3]`
- - Tuples : `Tuple`, e.g. `{:ok, 123}`
- - Maps : `Map`, e.g. `%{id: 1, login: "dx"}`
- - Structs : e.g. `%GL.Sphere{}`
- - Quoted code : `Quote`, e.g. `quote 1 + 2`
- - Identifiers : `Ident`, e.g. `quote hello`
- - Function or operator call : `Call`, e.g. `quote sqrt(1)`, `quote 1 + 2`
- - Code blocks : `Block`, e.g. `{ 1 + 2; 3 + 4 }`
- - Function : `Fn`, e.g. `fn (x) { x * 2 }`
- - C function : `Cfn`, e.g. `cfn Tag "tag_add" (Tag, Tag, Result)`
- - Unquoted code: `Unquote`, e.g. `quote 1 + unquote(x)`
- - Variables : `Var`, e.g. `?`
- - Void : `Void`, e.g. `void`
diff --git a/doc/1 KC3/1.2 Integer.en.md b/doc/1 KC3/1.2 Integer.en.md
deleted file mode 100644
index 4b6b2b4..0000000
--- a/doc/1 KC3/1.2 Integer.en.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# 2 Integers
-
-## 2.1 Small integers
-
-IKC3 supports all C integer type sizes from `U8` (matching the C type `uint8_t`)
-to `U64` (matching the C type `uint64_t`) for unsigned integers,
-and from `S8` to `S64` for signed integers.
-
-In addition to these 8 basic integer types there are 2 pointer-sized
-integer types :
-`Uw` for unsigned pointer-sized integers,
-and `Sw` for signed pointer-sized integers.
-
-Small integers take little space, are static, they are passed directly and
-not as a pointer, and for these reasons are fast.
-
-They do not need to be cleaned after use and thus can be used in arrays like
-is usually done in C.
-
-```
-ikc3> type(-1)
-S8
-ikc3> type(-128)
-S16
-ikc3> type(-32768)
-S32
-ikc3> type(-2147483648)
-S64
-ikc3> type(-9223372036854775807)
-S64
-ikc3> type(0)
-U8
-ikc3> type(256)
-U16
-ikc3> type(65536)
-U32
-ikc3> type(4294967296)
-U64
-ikc3> type(18446744073709551615)
-U64
-```
-
-## 2.2 Large integers
-
-IKC3 supports large integers and they are compatible with small integers.
-Their type is `Integer` and can support numbers as large as memory allows.
-They are slow because they are allocated dynamically on the heap
-using malloc.
-
-```
-ikc3> type(1000000000000000000000000000000)
-Integer
-```
-
-
-## 2.3 Operations on integers
-
-### 2.3.1 Operator `~`
-
-Binary not.
-
-```
-ikc3> ~ 1
-254
-ikc3> ~ -1
-0
-ikc3> ~ 0
-255
-ikc3> ~ 255
-0
-ikc3> ~ (U16) 1
-65534
-ikc3> ~ (S16) 1
--2
-```
-
-### 2.3.2 Operator `+`
-
-Integer addition.
-
-All positive integers can be defined in terms of addition of :
-zero or a positive integer, and one. E.g.
-
-```
-1 = 0 + 1
-2 = 0 + 1 + 1
-3 = 0 + 1 + 1 + 1
-etc.
-```
-
-### 2.3.3 Operator `-`
-
-Integer subtraction. Take an integer and remove another integer from it.
-
-### 2.3.4 Operator `*`
-
-Integer multiplication. Init result to zero, add an integer `a` and
-repeat `b` times.
-
-### 2.3.5 Operator `/`
-
-Integer division. The inverse of multiplication :
-for all integers `a` and `b` there is a couple `q` and `r` that satisfies
-`a = b * q + r`. Integer division returns `q`.
-
-### 2.3.6 Operator `mod`
-
-Integer modulo. Returns `r` in the previous equation (see Operator `/`)
-
-### 2.3.7 Operator `<<`
-
-Left shift
-
-
-## 2.4 Examples
-
-```
-ikc3> type(1)
-U8
-ikc3> type(1000000000000000000000000000000)
-Integer
-ikc3> a = 1 + 100000000000000000000000000000000
-100000000000000000000000000000001
-ikc3> a * a
-10000000000000000000000000000000200000000000000000000000000000001
-ikc3> a * a / 1000000000000000000000000000000000000000000000000000
-10000000000000
-```
diff --git a/doc/1 KC3/1.3 Map.en.md b/doc/1 KC3/1.3 Map.en.md
deleted file mode 100644
index 27cc576..0000000
--- a/doc/1 KC3/1.3 Map.en.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# 3 Map
-
-KC3 maps are like Elixir maps, they are key-values enclosed in `%{}` :
-
-```
-ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
-%{id: 1, title: "My title", message: "Hello, world !"}
-```
-
-Destructuring works with maps to extract values :
-
-```
-ikc3> %{id: id, title: "My title", message: message} = ^ a
-%{id: 1, title: "My title", message: "Hello, world !"}
-ikc3> id
-1
-ikc3> message
-"Hello, world !"
-```
-
-
-You can use the dot syntax to access map values from a `Sym` key :
-
-```
-ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
-%{id: 1, title: "My title", message: "Hello, world !"}
-ikc3> a.id
-1
-ikc3> a.message
-"Hello, world !"
-```
-
-You can also use the `KC3.access` function for the same result :
-
-```
-ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
-%{id: 1, title: "My title", message: "Hello, world !"}
-ikc3> access(a, :id)
-1
-ikc3> access(a, :message)
-"Hello, world !"
-```
diff --git a/doc/1 KC3/1.4 Ratio.en.md b/doc/1 KC3/1.4 Ratio.en.md
deleted file mode 100644
index 0b889ce..0000000
--- a/doc/1 KC3/1.4 Ratio.en.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# 4 Ratio
-
-Ratios are made with a couple of large integers : the numerator
-which can be any number, and the denominator which has to be positive.
-They represent fractions of integral numbers.
-They are written with a slash and no space.
-
-```
-ikc3> 1/2 + 2/3
-7/6
-ikc3> 1/2 * 2/3
-1/3
-ikc3> 1/2 / 2/3
-3/4
-ikc3> 1/2 - 2/3
--1/6
-```
diff --git a/doc/1 KC3/1.5 List.en.md b/doc/1 KC3/1.5 List.en.md
deleted file mode 100644
index 259d1b1..0000000
--- a/doc/1 KC3/1.5 List.en.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# 5 List
-
-Linked lists owning the data (each node contains a couple of tags :
-one for data and one for next pointer.
-
-Regular lists can be :
- - multiple elements : `[1, 2, 3]`
- - an element and a list : `[1 | [2, 3]]`
- - multiple elements and a list : `[1, 2 | [3]]`
- - the empty list : `[]`
-
-Regular lists end with the empty list : `[1] == [1 | []]`.
-
-You can also contruct dotted lists like in Common Lisp where
-the next list pointer is an arbitrary form. E.g. :
- - an element and an element : `[1 | 2]`
- - multiple elements and an element : `[1, 2, 3 | 4]`
- - the empty list and an element : `[[] | 1]`
-
-All these list formats are supported in pattern matching.
-
-## 5.1 Functions
-
-```
-List List.map (List, Fn)
-```
-
-```
-List List.reverse (List)
-```
diff --git a/doc/1 KC3/1.6 Variable.en.md b/doc/1 KC3/1.6 Variable.en.md
deleted file mode 100644
index 7c38729..0000000
--- a/doc/1 KC3/1.6 Variable.en.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# 6 Variables
-
-Variables in KC3 can be defined using the litteral value for a variable
-which is always `?`. You can cast this litteral value and it will not
-really be casted but it will give you a typed variable litteral value.
-E.g. `(List) ?`.
-The typed variable litteral value will only accept to be set once to
-one value of the variable's type (in this example the type of a linked
-list).
-
-It's actually a syntax so you cannot rename `?` by mistake and
-so is an easy task to do static analysis of variable creation.
-
-The default type for a variable which you can also specify explicitly
-is `Tag` which is an enum-tagged union type of any other KC3 types
-currently defined in the environment. So `?` is exactly equivalent to
-`(Tag) ?` and they will both accept to be set once to one value of any
-type.
-
-A variable is settable once and cannot be changed afterwards (there is
-an exception if you write C code and link to it but it is not easy nor
-silent).
-
-This way you do not need to lock or trust any behaviour, once your
-variable is set to a value the value of the variable will never change,
-it really is read-only.
-
-You can also use the assignment operator which is `<-` which in turn calls
-`tag_init_copy`. It works like the C assignment operator (`=`).
-
-Examples :
-```
-# Declare a unsigned byte 8 bits variable "x".
-x = (U8) ?
-# Set the variable "x" to zero.
-x <- 0
-# Allocate again for the same binding name "x"
-x = (U8) ?
-# Also set the new variable "x" to zero with just one Unicode symbol
-# that is AltGr+Y on my keyboard.
-x ← 0
-```
-
-
-## So how do I change anything if it is read-only ?
-
-You can always reset an existing binding at will to another variable
-litteral and another variable will be created for the same name and it
-will be in a different memory location, settable once and then
-read-only again so you can use it without locking.
diff --git a/doc/1 KC3/index.en.html b/doc/1 KC3/index.en.html
deleted file mode 100644
index e08dff1..0000000
--- a/doc/1 KC3/index.en.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<div>
- <div class="KC3-1">
- <div>
- <p>
- <b>KC3</b> is a programming language with meta-programmation
- and a graph database embedded into the language.
- It aims to be the language for semantic programming,
- and programming the semantic web.
- </p>
- <p>
- There is a working prototype available at
- <a target="_blank" href="https://git.kmx.io/kc3-lang/kc3/">https://git.kmx.io/kc3-lang/kc3/</a>.
- </p>
- <p>
- Please see the
- <a target="_blank" href="https://www.kmx.io/en/donations.html">https://www.kmx.io/en/donations.html</a>
- page if you want to help out.
- </p>
- <p>KC3 is currently a programming language project, inspired by C,
- Elixir and Common Lisp. It could be described as C with Elixir
- modules, pattern matching, and a semantic object system. The
- idea is to plug modules, closures, pattern matching, a graph
- database and metaprogramming into C99 with an extremely small
- set of dependencies.
- </p>
- <p>
- Supported operating systems (additionnal dependencies) :
- <ul>
- <li>BSD</li>
- <li>Linux (libbsd, libmd)</li>
- <li>MacOS X (libmd)</li>
- <li>Windows (MSys2)</li>
- </ul>
- </p>
- <p>
- Supported architectures :
- <ul>
- <li>aarch64 (arm64, Apple M1, Apple M2)</li>
- <li>amd64</li>
- <li>i386</li>
- <li>sparc64</li>
- </ul>
- </p>
- </div>
- </div>
-</div>
diff --git a/doc/1_KC3/1.1_Introduction.en.md b/doc/1_KC3/1.1_Introduction.en.md
new file mode 100644
index 0000000..00e45ab
--- /dev/null
+++ b/doc/1_KC3/1.1_Introduction.en.md
@@ -0,0 +1,65 @@
+# 1 Introduction
+
+KC3 is currently a programming language project, inspired by C, Elixir
+and Common Lisp. It could be described as C with Elixir modules,
+pattern matching, and a semantic object system. The idea is to plug
+modules, closures, pattern matching, a graph database and
+metaprogramming into C99 with an extremely small set of dependencies.
+
+Supported operating systems (additionnal dependencies) :
+ - BSD
+ - Linux (libbsd, libmd)
+ - MacOS X (libmd)
+ - Windows (MSys2)
+
+Supported architectures :
+ - aarch64 (arm64, Apple M1, Apple M2)
+ - amd64
+ - i386
+ - sparc64
+
+
+## 1.1 Modules
+
+Everything in KC3 is in a module. A module is a namespace,
+and is named with a symbol starting with a uppercase character.
+For instance `Sym` and `Str` are valid module names.
+
+Each module can define a type and a module name can also be a
+type name if the corresponding module defines a type.
+
+The module can also include definitions for functions for
+operating on the module type or other types.
+
+The default module is `KC3`, which is defined as facts (triples)
+in `lib/kc3/0.1/kc3.facts`.
+
+
+## 1.2 Data types
+
+Basic data types in KC3 are :
+ - Strings : `Str`, e.g. `"Hello, world !"`
+ - Symbols : `Sym`, e.g. `:hello` or `Hello`
+ - Booleans : `Bool`, `true` or `false`
+ - Numbers
+ - Integers
+ - Small integers
+ - Signed small integers : `S8`, `S16`, `S32`, `S64`, `Sw`
+ - Unsigned small integers : `U8`, `U16`, `U32`, `U64`, `Uw`
+ - Large integers : `Integer`
+ - Rational numbers (fractions of integers) : `Ratio`, e.g. `-2/3`
+ - Floating point numbers : `F32`, `F64`, `F128`
+ - Complex numbers (i = √(-1)) : `Complex`, e.g. `1 +i 2`
+ - Lists : `List`, e.g. `[1, 2, 3]`
+ - Tuples : `Tuple`, e.g. `{:ok, 123}`
+ - Maps : `Map`, e.g. `%{id: 1, login: "dx"}`
+ - Structs : e.g. `%GL.Sphere{}`
+ - Quoted code : `Quote`, e.g. `quote 1 + 2`
+ - Identifiers : `Ident`, e.g. `quote hello`
+ - Function or operator call : `Call`, e.g. `quote sqrt(1)`, `quote 1 + 2`
+ - Code blocks : `Block`, e.g. `{ 1 + 2; 3 + 4 }`
+ - Function : `Fn`, e.g. `fn (x) { x * 2 }`
+ - C function : `Cfn`, e.g. `cfn Tag "tag_add" (Tag, Tag, Result)`
+ - Unquoted code: `Unquote`, e.g. `quote 1 + unquote(x)`
+ - Variables : `Var`, e.g. `?`
+ - Void : `Void`, e.g. `void`
diff --git a/doc/1_KC3/1.2_Integer.en.md b/doc/1_KC3/1.2_Integer.en.md
new file mode 100644
index 0000000..4b6b2b4
--- /dev/null
+++ b/doc/1_KC3/1.2_Integer.en.md
@@ -0,0 +1,128 @@
+# 2 Integers
+
+## 2.1 Small integers
+
+IKC3 supports all C integer type sizes from `U8` (matching the C type `uint8_t`)
+to `U64` (matching the C type `uint64_t`) for unsigned integers,
+and from `S8` to `S64` for signed integers.
+
+In addition to these 8 basic integer types there are 2 pointer-sized
+integer types :
+`Uw` for unsigned pointer-sized integers,
+and `Sw` for signed pointer-sized integers.
+
+Small integers take little space, are static, they are passed directly and
+not as a pointer, and for these reasons are fast.
+
+They do not need to be cleaned after use and thus can be used in arrays like
+is usually done in C.
+
+```
+ikc3> type(-1)
+S8
+ikc3> type(-128)
+S16
+ikc3> type(-32768)
+S32
+ikc3> type(-2147483648)
+S64
+ikc3> type(-9223372036854775807)
+S64
+ikc3> type(0)
+U8
+ikc3> type(256)
+U16
+ikc3> type(65536)
+U32
+ikc3> type(4294967296)
+U64
+ikc3> type(18446744073709551615)
+U64
+```
+
+## 2.2 Large integers
+
+IKC3 supports large integers and they are compatible with small integers.
+Their type is `Integer` and can support numbers as large as memory allows.
+They are slow because they are allocated dynamically on the heap
+using malloc.
+
+```
+ikc3> type(1000000000000000000000000000000)
+Integer
+```
+
+
+## 2.3 Operations on integers
+
+### 2.3.1 Operator `~`
+
+Binary not.
+
+```
+ikc3> ~ 1
+254
+ikc3> ~ -1
+0
+ikc3> ~ 0
+255
+ikc3> ~ 255
+0
+ikc3> ~ (U16) 1
+65534
+ikc3> ~ (S16) 1
+-2
+```
+
+### 2.3.2 Operator `+`
+
+Integer addition.
+
+All positive integers can be defined in terms of addition of :
+zero or a positive integer, and one. E.g.
+
+```
+1 = 0 + 1
+2 = 0 + 1 + 1
+3 = 0 + 1 + 1 + 1
+etc.
+```
+
+### 2.3.3 Operator `-`
+
+Integer subtraction. Take an integer and remove another integer from it.
+
+### 2.3.4 Operator `*`
+
+Integer multiplication. Init result to zero, add an integer `a` and
+repeat `b` times.
+
+### 2.3.5 Operator `/`
+
+Integer division. The inverse of multiplication :
+for all integers `a` and `b` there is a couple `q` and `r` that satisfies
+`a = b * q + r`. Integer division returns `q`.
+
+### 2.3.6 Operator `mod`
+
+Integer modulo. Returns `r` in the previous equation (see Operator `/`)
+
+### 2.3.7 Operator `<<`
+
+Left shift
+
+
+## 2.4 Examples
+
+```
+ikc3> type(1)
+U8
+ikc3> type(1000000000000000000000000000000)
+Integer
+ikc3> a = 1 + 100000000000000000000000000000000
+100000000000000000000000000000001
+ikc3> a * a
+10000000000000000000000000000000200000000000000000000000000000001
+ikc3> a * a / 1000000000000000000000000000000000000000000000000000
+10000000000000
+```
diff --git a/doc/1_KC3/1.3_Map.en.md b/doc/1_KC3/1.3_Map.en.md
new file mode 100644
index 0000000..27cc576
--- /dev/null
+++ b/doc/1_KC3/1.3_Map.en.md
@@ -0,0 +1,42 @@
+# 3 Map
+
+KC3 maps are like Elixir maps, they are key-values enclosed in `%{}` :
+
+```
+ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
+%{id: 1, title: "My title", message: "Hello, world !"}
+```
+
+Destructuring works with maps to extract values :
+
+```
+ikc3> %{id: id, title: "My title", message: message} = ^ a
+%{id: 1, title: "My title", message: "Hello, world !"}
+ikc3> id
+1
+ikc3> message
+"Hello, world !"
+```
+
+
+You can use the dot syntax to access map values from a `Sym` key :
+
+```
+ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
+%{id: 1, title: "My title", message: "Hello, world !"}
+ikc3> a.id
+1
+ikc3> a.message
+"Hello, world !"
+```
+
+You can also use the `KC3.access` function for the same result :
+
+```
+ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
+%{id: 1, title: "My title", message: "Hello, world !"}
+ikc3> access(a, :id)
+1
+ikc3> access(a, :message)
+"Hello, world !"
+```
diff --git a/doc/1_KC3/1.4_Ratio.en.md b/doc/1_KC3/1.4_Ratio.en.md
new file mode 100644
index 0000000..0b889ce
--- /dev/null
+++ b/doc/1_KC3/1.4_Ratio.en.md
@@ -0,0 +1,17 @@
+# 4 Ratio
+
+Ratios are made with a couple of large integers : the numerator
+which can be any number, and the denominator which has to be positive.
+They represent fractions of integral numbers.
+They are written with a slash and no space.
+
+```
+ikc3> 1/2 + 2/3
+7/6
+ikc3> 1/2 * 2/3
+1/3
+ikc3> 1/2 / 2/3
+3/4
+ikc3> 1/2 - 2/3
+-1/6
+```
diff --git a/doc/1_KC3/1.5_List.en.md b/doc/1_KC3/1.5_List.en.md
new file mode 100644
index 0000000..259d1b1
--- /dev/null
+++ b/doc/1_KC3/1.5_List.en.md
@@ -0,0 +1,30 @@
+# 5 List
+
+Linked lists owning the data (each node contains a couple of tags :
+one for data and one for next pointer.
+
+Regular lists can be :
+ - multiple elements : `[1, 2, 3]`
+ - an element and a list : `[1 | [2, 3]]`
+ - multiple elements and a list : `[1, 2 | [3]]`
+ - the empty list : `[]`
+
+Regular lists end with the empty list : `[1] == [1 | []]`.
+
+You can also contruct dotted lists like in Common Lisp where
+the next list pointer is an arbitrary form. E.g. :
+ - an element and an element : `[1 | 2]`
+ - multiple elements and an element : `[1, 2, 3 | 4]`
+ - the empty list and an element : `[[] | 1]`
+
+All these list formats are supported in pattern matching.
+
+## 5.1 Functions
+
+```
+List List.map (List, Fn)
+```
+
+```
+List List.reverse (List)
+```
diff --git a/doc/1_KC3/1.6_Variable.en.md b/doc/1_KC3/1.6_Variable.en.md
new file mode 100644
index 0000000..7c38729
--- /dev/null
+++ b/doc/1_KC3/1.6_Variable.en.md
@@ -0,0 +1,50 @@
+# 6 Variables
+
+Variables in KC3 can be defined using the litteral value for a variable
+which is always `?`. You can cast this litteral value and it will not
+really be casted but it will give you a typed variable litteral value.
+E.g. `(List) ?`.
+The typed variable litteral value will only accept to be set once to
+one value of the variable's type (in this example the type of a linked
+list).
+
+It's actually a syntax so you cannot rename `?` by mistake and
+so is an easy task to do static analysis of variable creation.
+
+The default type for a variable which you can also specify explicitly
+is `Tag` which is an enum-tagged union type of any other KC3 types
+currently defined in the environment. So `?` is exactly equivalent to
+`(Tag) ?` and they will both accept to be set once to one value of any
+type.
+
+A variable is settable once and cannot be changed afterwards (there is
+an exception if you write C code and link to it but it is not easy nor
+silent).
+
+This way you do not need to lock or trust any behaviour, once your
+variable is set to a value the value of the variable will never change,
+it really is read-only.
+
+You can also use the assignment operator which is `<-` which in turn calls
+`tag_init_copy`. It works like the C assignment operator (`=`).
+
+Examples :
+```
+# Declare a unsigned byte 8 bits variable "x".
+x = (U8) ?
+# Set the variable "x" to zero.
+x <- 0
+# Allocate again for the same binding name "x"
+x = (U8) ?
+# Also set the new variable "x" to zero with just one Unicode symbol
+# that is AltGr+Y on my keyboard.
+x ← 0
+```
+
+
+## So how do I change anything if it is read-only ?
+
+You can always reset an existing binding at will to another variable
+litteral and another variable will be created for the same name and it
+will be in a different memory location, settable once and then
+read-only again so you can use it without locking.
diff --git a/doc/2 HTTPd/index.en.md b/doc/2 HTTPd/index.en.md
deleted file mode 100644
index 3edfe5b..0000000
--- a/doc/2 HTTPd/index.en.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# 2 KC3 HTTPd web server
-
-The source files for the KC3 HTTPd web server are in `/httpd`.
-
-## 2.1 Dependencies
-
-The web server depends on :
- - KC3
- - libkc3
- - event
- - socket
- - http
- - [SASS](https://sass-lang.com/) for CSS rendering
- - [ESBuild](https://esbuild.github.io/) for Javascript rendering
-
-## 2.2 Configuration
-
-The web server must be started in a directory containing the following
-files :
-
-```
-./app/controllers/ # controllers directory (.kc3)
-./app/templates/ # templates directory (.ekc3)
-./app/views/ # views directory (.kc3)
-./assets/ # assets directory
-./assets/css/ # css directory
-./assets/css/app.scss # application css, compiled to ./static/_assets/app.css
-./assets/js/ # javascript directory
-./assets/js/app.js # application javascript, compiled to ./static/_assets/app.js
-./assets/node_modules/ # from npm
-./config/routes.kc3 # dynamic routes
-./static/ # for static files
-./static/_assets/ # for static asset files
-./static/_fonts/ # for static font files
-./static/_images/ # for static image files
-```
-
-## 2.3 Example
-
-Run `make test_httpd` to run the KC3 HTTPd web server (`httpd/kc3_httpd`)
-starting in the `test/httpd` working directory.
-
-This directory contains an example of configuring and using `kc3_httpd`.
-
-Static files are served from ./static and is mapped to root URL (`/`).
-
-Documentation in Markdown and HTML format is served from the `/doc/` URL.
-The documentation has a custom route defined in `./config/routes.kc3`,
-a controller defined in `./app/controllers/doc_controller.kc3` and
-a few templates defined in `./app/templates/doc/`.
-
-The main layout for the application is stated in
-`./app/templates/layout.html.ekc3` and `./app/templates/nav.html.ekc3`.
-Notice the `.html.ekc3` extension, these are HTML files with embedded KC3.
-See the [EKC3](/doc/EKC3) documentation for more information on these files.
diff --git a/doc/2_HTTPd/index.en.md b/doc/2_HTTPd/index.en.md
new file mode 100644
index 0000000..3edfe5b
--- /dev/null
+++ b/doc/2_HTTPd/index.en.md
@@ -0,0 +1,55 @@
+# 2 KC3 HTTPd web server
+
+The source files for the KC3 HTTPd web server are in `/httpd`.
+
+## 2.1 Dependencies
+
+The web server depends on :
+ - KC3
+ - libkc3
+ - event
+ - socket
+ - http
+ - [SASS](https://sass-lang.com/) for CSS rendering
+ - [ESBuild](https://esbuild.github.io/) for Javascript rendering
+
+## 2.2 Configuration
+
+The web server must be started in a directory containing the following
+files :
+
+```
+./app/controllers/ # controllers directory (.kc3)
+./app/templates/ # templates directory (.ekc3)
+./app/views/ # views directory (.kc3)
+./assets/ # assets directory
+./assets/css/ # css directory
+./assets/css/app.scss # application css, compiled to ./static/_assets/app.css
+./assets/js/ # javascript directory
+./assets/js/app.js # application javascript, compiled to ./static/_assets/app.js
+./assets/node_modules/ # from npm
+./config/routes.kc3 # dynamic routes
+./static/ # for static files
+./static/_assets/ # for static asset files
+./static/_fonts/ # for static font files
+./static/_images/ # for static image files
+```
+
+## 2.3 Example
+
+Run `make test_httpd` to run the KC3 HTTPd web server (`httpd/kc3_httpd`)
+starting in the `test/httpd` working directory.
+
+This directory contains an example of configuring and using `kc3_httpd`.
+
+Static files are served from ./static and is mapped to root URL (`/`).
+
+Documentation in Markdown and HTML format is served from the `/doc/` URL.
+The documentation has a custom route defined in `./config/routes.kc3`,
+a controller defined in `./app/controllers/doc_controller.kc3` and
+a few templates defined in `./app/templates/doc/`.
+
+The main layout for the application is stated in
+`./app/templates/layout.html.ekc3` and `./app/templates/nav.html.ekc3`.
+Notice the `.html.ekc3` extension, these are HTML files with embedded KC3.
+See the [EKC3](/doc/EKC3) documentation for more information on these files.
diff --git a/lib/kc3/0.1/str.facts b/lib/kc3/0.1/str.facts
index 755bc8d..404d311 100644
--- a/lib/kc3/0.1/str.facts
+++ b/lib/kc3/0.1/str.facts
@@ -23,3 +23,6 @@ replace {Str.starts_with?, :symbol_value,
add {Str, :symbol, Str.has_str?}
replace {Str.has_str?, :symbol_value,
cfn Bool "str_has_str" (Str, Str, Result)}
+add {Str, :symbol, Str.subst}
+replace {Str.subst, :symbol_value,
+ cfn Str "str_init_subst" (Result, Str, Str, Str)}
diff --git a/libkc3/str.c b/libkc3/str.c
index 755251f..9606d9e 100644
--- a/libkc3/str.c
+++ b/libkc3/str.c
@@ -592,6 +592,67 @@ s_str * str_init_slice (s_str *str, const s_str *src, sw start, sw end)
return str;
}
+s_str * str_init_subst (s_str *str, const s_str *src,
+ const s_str *search, const s_str *replace)
+{
+ character c;
+ s_buf in;
+ s_buf out;
+ sw r;
+ sw size;
+ assert(str);
+ assert(src);
+ assert(search);
+ assert(replace);
+ if ((size = str_init_subst_size(src, search, replace)) < 0)
+ return NULL;
+ if (! buf_init_alloc(&out, size))
+ return NULL;
+ buf_init_str_const(&in, src);
+ while (in.wpos - in.rpos >= search->size) {
+ if (buf_read_str(&in, search) > 0) {
+ if ((r = buf_write_str(&out, replace)) < 0)
+ goto clean;
+ }
+ else {
+ if ((r = buf_read_character_utf8(&in, &c)) < 0)
+ break;
+ if ((r = buf_write_character_utf8(&out, c)) < 0)
+ goto clean;
+ }
+ }
+ if ((r = buf_xfer(&out, &in, in.wpos - in.rpos)) < 0)
+ goto clean;
+ buf_to_str(&out, str);
+ return str;
+ clean:
+ buf_clean(&out);
+ return NULL;
+}
+
+sw str_init_subst_size (const s_str *src, const s_str *search,
+ const s_str *replace)
+{
+ character c;
+ s_buf in;
+ sw r;
+ sw result = 0;
+ assert(src);
+ assert(search);
+ assert(replace);
+ buf_init_str_const(&in, src);
+ while (in.wpos - in.rpos >= search->size) {
+ if (buf_read_str(&in, search) > 0)
+ result += replace->size;
+ else {
+ if ((r = buf_read_character_utf8(&in, &c)) < 0)
+ return -1;
+ result += r;
+ }
+ }
+ return result;
+}
+
s_str * str_init_to_lower (s_str *str, const s_str *src)
{
s_buf buf;
diff --git a/libkc3/str.h b/libkc3/str.h
index 1b9b7b8..2b7e707 100644
--- a/libkc3/str.h
+++ b/libkc3/str.h
@@ -66,6 +66,10 @@ PROTOTYPE_STR_INIT_INT(s64);
s_str * str_init_slice (s_str *str, const s_str *src, sw start, sw end);
s_str * str_init_slice_utf8 (s_str *str, const s_str *src, sw start,
sw end);
+s_str * str_init_subst (s_str *str, const s_str *src,
+ const s_str *search, const s_str *replace);
+sw str_init_subst_size (const s_str *src, const s_str *search,
+ const s_str *replace);
PROTOTYPE_STR_INIT_STRUCT(struct);
PROTOTYPE_STR_INIT_INT(sw);
s_str * str_init_to_lower (s_str *str, const s_str *src);
diff --git a/test/httpd/app/controllers/doc_controller.kc3 b/test/httpd/app/controllers/doc_controller.kc3
index 1d8e589..8d6ed32 100644
--- a/test/httpd/app/controllers/doc_controller.kc3
+++ b/test/httpd/app/controllers/doc_controller.kc3
@@ -17,7 +17,7 @@ defmodule DocController do
doc_index(rest, path_md, dir, acc)
else
path = dir + file
- name = ^ file
+ name = Str.subst(file, "_", " ")
url = Str.slice(path, 1, -1)
if File.is_directory?(path) do
items = doc_index(List.sort(File.list(path)), path_md,
@@ -54,7 +54,7 @@ defmodule DocController do
}
(path, path_md, dir, acc) {
if (type(path) == Str) do
- doc_index(File.list(path), path_md, dir, acc)
+ doc_index(List.sort(File.list(path)), path_md, dir, acc)
end
}
}