diff --git a/Makefile b/Makefile
index 626870d..0bb4177 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,10 @@ test:
site: clean
mkdir build
mkdir build/site
+ mkdir build/site/core
cp -r _site/* build/site/.
+ go run ./cmd/gendocs/main.go ./_docs/index.md > build/site/index.html
+ go run ./cmd/gendocs/main.go ./_docs/core.md > build/site/core/index.html
GOOS=js GOARCH=wasm go build -o build/site/playwasm.wasm ./cmd/playwasm/.
site-deploy: site
diff --git a/_docs/core.md b/_docs/core.md
new file mode 100644
index 0000000..27b4ed4
--- /dev/null
+++ b/_docs/core.md
@@ -0,0 +1,119 @@
+---
+---
+
+# Core Functions
+
+### call
+
+```
+call BLOCK [ARGS...]
+```
+
+Invokes block, passing in the arguments. This is as if block was invoked as a command. This may not always be necessary
+unless these are need to call BLOCK with exactly 0 arguments.
+
+### echo
+
+```
+echo [ARGS...]
+```
+
+Displays the string representation of ARGS to stdout followed by a new line.
+
+### foreach
+
+```
+foreach SEQ BLOCK
+```
+
+Iterates BLOCK over every element of the sequence.
+
+The values pass to BLOCK will depend on the type of SEQ. If SEQ is a list, BLOCK receives the element value.
+If SEQ is a hash, BLOCK receives both the key and value of each element.
+
+BLOCK can call `break` and `continue` which will exit out of the loop, or jump to the start of the next iteration
+respectively.
+
+The return value of `foreach` will be the result of the last iteration, unless `break` is called with a value.
+
+```
+foreach [1 2 3] { |e|
+ echo "Element = $e"
+}
+
+foreach [a:"one" b:"two"] { |k v|
+ echo "Key $k = $v"
+}
+```
+
+### keys
+
+```
+keys HASH
+```
+
+Returns the keys of the passed in hash as a list. The order of keys are non-deterministic.
+If HASH is not a hash, then nil will be returned.
+
+### len
+
+```
+len SEQ
+```
+
+Returns the length of SEQ. If SEQ is a list or hash, SEQ will be the number of
+elements. If SEQ is a string, SEQ will be the string's length. All other values will
+return a length of 0.
+
+### map
+
+```
+map SEQ BLOCK
+```
+
+Returns a new list of elements mapped from SEQ according to the result of BLOCK. SEQ can be any listable data
+structure, however the result will always be a concrete list.
+
+```
+map [1 2 3] { |x| str $x | len }
+```
+
+### proc
+
+```
+proc [NAME] BLOCK
+```
+
+Defines a new function optionally with the given name. When called without NAME, this will define a new
+lambda which can be invoked using `call`.
+
+When NAME is set, this function defining a function a name will always declare it at the top-level scope.
+
+### reduce
+
+```
+reduce SEQ [INIT] BLOCK
+```
+
+Returns the result of reducing the elements of SEQ with the passed in block.
+
+BLOCK will receive at least two argument, with the current value of the accumulator always being the last argument.
+If SEQ is a list, the arguments will be _|element accumulator|_, and if SEQ is a hash, the arguments will be
+_|key value accumulator|_.
+
+The block result will be set as the value of the accumulator for the next iteration. Once all elements are process
+the accumulator value will be returned as the result of `reduce`.
+
+If INIT is not set, and SEQ is a list, the accumulator will be set to the first value and BLOCK will be called
+from the second element, if any. If SEQ is a hash, then the accumulator will be set to nil.
+
+### set
+
+```
+set NAME VALUE
+```
+
+Sets the value of variable NAME to VALUE. Any variable with NAME will be checked
+within the scope first, including any parent scopes, before a new variable is defined.
+Any new variables will only be defined with the current scope.
+
diff --git a/_docs/index.md b/_docs/index.md
new file mode 100644
index 0000000..f535869
--- /dev/null
+++ b/_docs/index.md
@@ -0,0 +1,22 @@
+# Universal Command Language
+
+Universal Command Language, or UCL, is a scripting language designed for use with REPLs or batch jobs.
+It's heavily inspired by the likes of TCL and Bash, and it's purpose is to be usable as an interactive command
+language while at the same time being useful enough as a scripting language for simple automation tasks.
+
+The flavour of a particular UCL instance will depend heavily on the host environment. Most likely additional commands
+will be defined, and some commands may be removed. But this page describes the features of a "typical" UCL instance.
+
+## Example
+
+```
+proc greet { |someone|
+ echo "Hello, $someone"
+}
+
+greet "world"
+```
+
+## Status
+
+This is very much still in development and is subject to change.
\ No newline at end of file
diff --git a/_site/index.html b/_site/index.html
index 15ea466..6508f95 100644
--- a/_site/index.html
+++ b/_site/index.html
@@ -12,23 +12,10 @@
- Playground
-
-
-
-
-