aboutsummaryrefslogtreecommitdiff
path: root/README.org
diff options
context:
space:
mode:
Diffstat (limited to 'README.org')
-rw-r--r--README.org66
1 files changed, 65 insertions, 1 deletions
diff --git a/README.org b/README.org
index 3337be5..3782540 100644
--- a/README.org
+++ b/README.org
@@ -1,4 +1,68 @@
#+title: Stem
* Introduction
-Stem aims to be a small implementation of something like the forth programming language.
+Stem aims to be a small implementation of something like the forth programming language,
+meaning it operates on a virtual stack. There are words, quotes, and literal types in this
+language; this allows for metaprogramming.
+
+** Quickstart
+In this language, words are anything that are not literals (strings, ints, floats), and are
+not the special characters [ and ]. Literals include the types above and they work just
+like in other languages, and quotes are just lists of these words and literals.
+
+Any literal in the language by itself gets pushed onto the stack. For example, the value:
+#+begin_example
+"hello world"
+#+end_example
+gets pushed onto the stack once it is created.
+
+Note that words can also act like literals, but they are different in that you can bind them to funtions:
+#+begin_example
+helloworld [ "hello world" . ] func
+#+end_example
+Where . is a builtin function that pops the first value off the stack and prints it. In this example, the helloworld
+word is pushed onto the stack, then the quote ~[ "hello world" . ]~, which is just an array of these two values. Then,
+the ~func~ builtin is called, which takes these two values off of the stack. As a result, whenever ~helloworld~ is used
+in the future, it is expanded into whatever is in the quote.
+
+a useful way to know what's on the stack:
+#+begin_example
+?
+#+end_example
+is a builtin function that prints everything on the stack, where the very last thing printed is the top of the stack.
+
+*** Quoting and Escaping
+If you want to push a word to the stack after it has been bound, you must escape it:
+#+begin_example
+\helloworld
+#+end_example
+
+quotes are somewhat related to escaping. They allow the language to talk about itself, along with the ~eval~ keyword.
+To get an idea of what you can do with it, consider the following example:
+#+begin_example
+[ hello [ "hello" . ] func ] eval
+#+end_example
+this statement is essentially the same statement as the above, but you can represent the entire code in a quote
+before evaluation. This allows for many possibilities. For example, you may try writing a program that automatically
+names functions and automatically changes what those functions do.
+
+*** Loops
+Looping in this language is done via recursion. Because the language is stack-based, recursion is not more memory efficient
+than looping if using tail recursion. For example, the REPL for this language is implemented like so:
+#+begin_example
+loop [ "> " read evalstr loop ] func loop
+#+end_example
+Where read takes in a string and prints it before reading a value, evalstr evaluates a string, and loop is the function that calls
+itself.
+
+*** Curry, Compose, Qstack, Quote
+These functions are important for manipulating quotes. For example:
+#+begin_example
+[ a b ] 6 5 quote curry compose
+#+end_example
+first turns 5 into ~[ 5 ]~, then curry adds 6 to the end of the quote. Compose takes two quotes and adjoins them together. Qstack
+simply turns everything on the stack into a quote, then puts it on the stack. For example:
+#+begin_example
+1 2 3 4 5 6 7 qstack
+#+end_example
+Returns the quote ~[ 1 2 3 4 5 6 7 ]~.