From 640f9a3f5be5528dd4f8ed658cfe4d06d833e4c9 Mon Sep 17 00:00:00 2001 From: Preston Pan Date: Mon, 15 Jan 2024 21:36:03 -0800 Subject: make other thing readme --- Doxyfile | 4 +-- MAINPAGE.md | 50 ---------------------------------- Makefile | 2 ++ README.md | 50 ++++++++++++++++++++++++++++++++++ README.org | 76 ---------------------------------------------------- examples/stdlib.stem | 9 +++++++ 6 files changed, 63 insertions(+), 128 deletions(-) delete mode 100644 MAINPAGE.md create mode 100644 README.md delete mode 100644 README.org diff --git a/Doxyfile b/Doxyfile index 66eac04..e1d638f 100644 --- a/Doxyfile +++ b/Doxyfile @@ -949,7 +949,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = include/ src/ MAINPAGE.md +INPUT = include/ src/ README.md # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -1165,7 +1165,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = MAINPAGE.md +USE_MDFILE_AS_MAINPAGE = README.md # The Fortran standard specifies that for fixed formatted Fortran code all # characters from position 72 are to be considered as comment. A common diff --git a/MAINPAGE.md b/MAINPAGE.md deleted file mode 100644 index efea70a..0000000 --- a/MAINPAGE.md +++ /dev/null @@ -1,50 +0,0 @@ -# Introduction {#mainpage} -Stem aims to be a minimal interpreted stack based programming language -that allows for metaprogramming and a foreign language interface. It features -a C API that is elegant and simple. Additionally, garbage collection is -not needed in this language as the responsibility of writing memory safe -operations is put in the hands of the maintainers of the builtin functions -and FLI library maintainers. Therefore, the end user does not need to worry -about memory allocation while the implementation remains extremely simple. - -# Installation -`make` and `sudo make install`. To generate the html documentation, one must first -install `doxygen` as an optional dependency. If you are on a BSD or MacOS, you -must use `gmake`. - -# Quickstart -Because this is a stack based language, all operations are done in reverse polish. For example, to add two numbers together: -``` -3 4 + -``` -would return the result `7`. `3` and `4` get pushed onto the stack when they are written out as literals in the language, and `+` is a builtin -that adds the top two elements of the stack. In this language, there are two kinds of objects: literals -(strings, ints, floats, words, and literals of type `VERROR` are built in), and quotes that contain these literals (arrays of valid statements that can be evaluated). -Words might be new to you if you're coming from another language. If you're coming from lisp, a words are analogous to symbols. If you're coming from another -language, a word is a literal that has the special property that they can be bound to functions. For example, the `+` symbol is a word, which is bound -to the action of adding two numbers when called. - -Let's look at a real example of a REPL implementation in this language: -``` -repl [ "> " . read strquote eval repl ] func -repl -``` -`repl` is a word, which means it is a literal, and everything that is a literal gets pushed onto the stack. -Everything between the `[` and `]` is an element in a quote. Then, we see the `func` word. If a word is already bound to a function, -the function gets called instead of getting pushed to the stack, so the `func` function gets called, which takes the top two -elements off the stack, and creates a function called `repl` where now every time `repl` is called in the future, the quote is evaluated -instead. - -Let's take a closer look at the quote: -``` -"> " . read strquote eval repl -``` -`.` takes the first thing off the stack and prints it. In this case, it would print a prompt `> ` every REPL loop. `read` reads a value from stdin, -then `strquote` turns that string into a quote. `eval` pops the first thing off the stack and evaluates the quote in the same way calling a function -does, and then finally `repl` gets called again at the end so we can loop forever. - -## Factorial -Let's take a closer look at the factorial function: -``` - -``` diff --git a/Makefile b/Makefile index 74ffb56..dc940c6 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,8 @@ clean: install: cp $(TARGET) /usr/local/bin/ + mkdir -p /usr/local/lib/share/stem/ + cp -r stemlib/ /usr/local/share/stem/stdlib/ doc: doxygen diff --git a/README.md b/README.md new file mode 100644 index 0000000..efea70a --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# Introduction {#mainpage} +Stem aims to be a minimal interpreted stack based programming language +that allows for metaprogramming and a foreign language interface. It features +a C API that is elegant and simple. Additionally, garbage collection is +not needed in this language as the responsibility of writing memory safe +operations is put in the hands of the maintainers of the builtin functions +and FLI library maintainers. Therefore, the end user does not need to worry +about memory allocation while the implementation remains extremely simple. + +# Installation +`make` and `sudo make install`. To generate the html documentation, one must first +install `doxygen` as an optional dependency. If you are on a BSD or MacOS, you +must use `gmake`. + +# Quickstart +Because this is a stack based language, all operations are done in reverse polish. For example, to add two numbers together: +``` +3 4 + +``` +would return the result `7`. `3` and `4` get pushed onto the stack when they are written out as literals in the language, and `+` is a builtin +that adds the top two elements of the stack. In this language, there are two kinds of objects: literals +(strings, ints, floats, words, and literals of type `VERROR` are built in), and quotes that contain these literals (arrays of valid statements that can be evaluated). +Words might be new to you if you're coming from another language. If you're coming from lisp, a words are analogous to symbols. If you're coming from another +language, a word is a literal that has the special property that they can be bound to functions. For example, the `+` symbol is a word, which is bound +to the action of adding two numbers when called. + +Let's look at a real example of a REPL implementation in this language: +``` +repl [ "> " . read strquote eval repl ] func +repl +``` +`repl` is a word, which means it is a literal, and everything that is a literal gets pushed onto the stack. +Everything between the `[` and `]` is an element in a quote. Then, we see the `func` word. If a word is already bound to a function, +the function gets called instead of getting pushed to the stack, so the `func` function gets called, which takes the top two +elements off the stack, and creates a function called `repl` where now every time `repl` is called in the future, the quote is evaluated +instead. + +Let's take a closer look at the quote: +``` +"> " . read strquote eval repl +``` +`.` takes the first thing off the stack and prints it. In this case, it would print a prompt `> ` every REPL loop. `read` reads a value from stdin, +then `strquote` turns that string into a quote. `eval` pops the first thing off the stack and evaluates the quote in the same way calling a function +does, and then finally `repl` gets called again at the end so we can loop forever. + +## Factorial +Let's take a closer look at the factorial function: +``` + +``` diff --git a/README.org b/README.org deleted file mode 100644 index e223f66..0000000 --- a/README.org +++ /dev/null @@ -1,76 +0,0 @@ -#+title: Stem - -* Credits -Big thanks to Andrei Sova for contributing ~fib.stem~ in the ~examples/~ directory. -* Introduction -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 strquote eval loop ] func loop -#+end_example -Where read takes in a string and prints it before reading a value, strquote turns a string into a quote, 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 ]~. -* CLib -This language has a foreign language interface (FLI). The FLI functions via including ~parser.h~ and creating the functions -~add_funcs~ and ~add_objs~. Each custom object needs to have its own free, print, and copy functions. For some implementation examples, -see the ~builtins.c~ file. Later on there will be more documentation. -* Install -~make~ and ~sudo make install~. diff --git a/examples/stdlib.stem b/examples/stdlib.stem index a063c9b..df81cd8 100644 --- a/examples/stdlib.stem +++ b/examples/stdlib.stem @@ -1,6 +1,9 @@ evalstr [ strquote eval ] func include [ fread evalstr ] func +# Author: Preston Pan +neg [ 0 swap - ] func + # Author of loop function: Andrei S loop [ swap dup 0 > [ @@ -15,6 +18,12 @@ dupd [ [ dup ] keep ] func over [ dupd swap ] func dup2 [ over over ] func dip2 [ swap [ dip ] dip ] func +while [ dup2 [ [ ] if ] dip2 over [ while ] [ dsc dsc ] if ] func loop-times [ dup2 [ swap [ ] if ] dip2 dup [ 1 - loop-times ] [ dsc dsc ] if ] func + +d>base [ [ pow * "" swap ] keep2 + +[ [ over ] [ [ dup2 / floor * swap over - ] keep [ [ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "↊" "↋" ] vat swap + ] with dip2 ] while dsc2 dup len(str-len) ] dip +- dup2 tail [ head "." ] dip + + ] func -- cgit