Mini Stack Language in Python
Posted Thu, Apr 10, 2008 in:Are you tired of the lack of challenge in programming? Do you pine for a syntax reminiscent of your old HP RPN calculator? Well then do I have the programming language for you!
Over the last few days I’ve been working on a little stack-based language in Python.
I’ve got lots of idea for programming languages, but a lot of them are pretty complex. I don’t really have any experience implementing programming languages, so I figured I’d start small and work my way up.
In this case, small means 135 lines of code (not counting the GPL notice) without many docstrings or comments. It’s small, so you should be able to figure it all out by the code (I hope you can, because I didn’t comment it that much).
Here’s an outline of some of the features of the language:
Programs are written in Reverse Polish Notation. Datum, made up of strings, numbers, or code blocks are pushed onto the stack as they are encountered. When a ‘word’ is encountered, it is executed, and may do stuff to the stack.
There is a consistent syntax, or rather, mostly a lack thereof. The only reserved characters are single and double quotes and curly brackets (‘{’ and ‘}’), after whitespace. Quote characters can be used as parts of words, even, just not as the first character.
All other language functionality is handled through the calling of words. There is no distinction made between built-in words and user_defined ones.
Examples
The ever-popular Hello world program: [code lang=“python”] ‘Hello, World!’ echo_nl [/code] Pretty straightforward. Push the string onto the stack and then print it out (with a newline). The echo and echo_nl commands both pop the top item from the stack and print it out.
Defining new words is as simple as pushing a name and block onto the stack and then calling the add_word word. [code lang=“python”] ‘square’ {dup *} add_word [/code] This example calls dup, which pushes a copy of the top item on the stack. It then calls * which pops to top two items from the stack and pushes the result of their multiplication.
Some user input and if and else: [code lang=“python”] ‘story’ { ‘do you want to hear a story?’ echo_nl read_string ‘yes’ = {‘Once upon a time…TODO: write story’ echo_nl} if {“Aww, you don’t want to hear my story.” echo_nl} else } add_word story [/code] Note that since it’s postfix notation that the words ‘if’ and ‘else’ appear after the block which will be run. Also, these are not keywords, they are just like any other built-in word. ‘if’ pushes a 1 to the stack after running its block, or a 0 if it doesn’t run its block. Then ‘else’ (once I actually write it) will run its block if the top value on the stack is a 0, otherwise it won’t run it’s block. I might also add an ‘elif’ function which will do the same as else while also pushing a result back onto the stack as well.
(I just realized that I didn’t actually implement the else function..I’ll fix that later.)
Check out the code for more details. Really, it’s not so hard to read..I think.
Work in progress
This language is somewhat usable at the moment, but it’s still in progress. I’ll probably change the names of all the words, and probably just start calling them functions rather than words, since that name is confusing (shame on you, FORTH, for inspiring me to call them that).
I’ll probably add in more words..err…functions to enable functional programming a-la Joy.
I don’t yet have a specific goal for this language, since I’m writing it for my own education. It might dawn on me that there is a perfect application for this language, which will then shape the future direction. If nothing else, it will be a fun toy for those who would like to create their own simple programming language, since it’s such a small piece of code at the moment.
I might also try to write a compiler to compile it down into Python bytecode, again as an exercise in personal education.
If you’re interested, the code can be gotten with git:
git clone http://paulbonser.com/code/stacklang.git
or the current version (0.0.1.1) is available here: stacklang.py