Ripley Users Guide

Table of Contents
1. Introduction
2. Print things out
3. Do some math
3.1. More about stacks
3.2. A little more math
4. Variables
4.1. More About the Different Variable Types
4.2. Naming Variables in the User Dictionary
5. Making New Functions
6. Ifs and Elses
7. Loops and such
A. Ripley Operands
A.1. add
A.2. aload
A.3. astore
A.4. clear
A.5. count
A.6. debug_dump
A.7. debug_opstack
A.8. def
A.9. div
A.10. dump
A.11. dup
A.12. eq
A.13. exch
A.14. exec
A.15. exit
A.16. false
A.17. forall
A.18. ge
A.19. get
A.20. gets
A.21. gt
A.22. if
A.23. ifelse
A.24. keys
A.25. le
A.26. length
A.27. loop
A.28. lt
A.29. mul
A.30. not
A.31. pop
A.32. print
A.33. put
A.34. ripley_version
A.35. roll
A.36. sub
A.37. token
A.38. true
List of Tables
4-1. Ripley Variable Types
4-2. Example Simple Types
List of Examples
2-1. Printing Hello World
2-2. Using Ripley Interactively
2-3. Using Ripley With A File
3-1. Evaluating 1 + 2
3-2. Subtracting 1 for 2
3-3. Multiplying 2 by 10
3-4. Dividing 10 by 5
3-5. Evaluating (1+2)*10
4-1. Array Example 1
4-2. Array Example 2
4-3. Dictionary Example
4-4. 1+2 using named variables
5-1. Hello World function
5-2. Add 10 function
6-1. Always true conditional
6-2. Always false conditional
6-3. Greater than ten printer
6-4. Greater than ten printer (ifelse version)
7-1. Counter to 10
7-2. Walking an array with forall
7-3. Using exit within forall

Chapter 1. Introduction

This guide is intended to provide a simple introduction to the syntax and structure of programs written in Ripley. It's important to note, however, that Ripley is an experimental implementation of a language, and not a language intended for production code.

Ripley is an implementation of a variant of Forth / Postscript in Ruby.

The User's Guide is divided into chapters which follow how you might learn the language if you just started with an editor and the interpreter. As you might expect, the first thing to learn is how to "Printing things out", so that you can see what you are doing. After that you might want to learn how to "Do some math". This section will also teach you about the basic nature of Ripley, about the operand and execution stacks.

After print stuff out and doing some math, you will probably want to create some "Variables". Next, we modularize with "Making New Functions". After learning how to store stuff in memory and modularize, then next step would be to make decisions based on it, you will learn how to do that in "Ifs and Elses". Finally we loop and iterate over arrays using "Loops and stuff".

Chapter 2. Print things out

The first thing you need to do to start playing with any language is to find a way to print things out. An example of the use of the 'print' operator, which prints the item at the top of the stack out to the standard output, is shown below:

But how do we run this? There are two methods; the first is to use Ripley in an interactive mode. Where everything you type is immediately evaluated by Ripley. The example below shows how to do this:

The next method is to create a new text file with your Ripley commands, and then to use Ripley to execute it directly. The below shows how to do this:

Chapter 3. Do some math

The next thing to learn is how to do some simple math, for example, write a program to print the result of 1+2. Here is an example of how to 1 and 2 together and to print the result:

What does that mean? And why does it work?

3.1. More about stacks

To understand why this works you need to understand the system of stack evaluation that is at the core of Ripley. Ripley has two stacks, the execution stack and the operand stack. Both stacks start empty. When a program is evaluated it is placed into the execution stack. So in our example the stacks start as:

Operand Stack:
Execution Stack: 1.0 2.0 add print

The interpreter gets the first item on the execution stack and executes it. In this case it's a simple value '1'. In the case of simple values it pushes the value onto the operand stack. So after the first evaluation the stacks look like this:

Operand Stack: 1.0
Execution Stack: 2.0 add print

The same thing happens with the '2'.

Operand Stack: 2.0 1.0
Execution Stack: add print

The next item is a literal 'add'. The interpreter looks literals up in the dictionaries and then executes the result. 'add' is a registered operand in the system dictionary. (More about dictionaries in a bit.) The 'add' operand pops two elements off the operand stack, adds them together pushes the result back onto the operand stack. After the evaluation of 'add' the stacks look like this:

Operand Stack: 3.0
Execution Stack: print

Ripley then evaluates the 'print' literal, which is another operator found in the system dictionary. Print pops the operand stack and prints the result out to STDOUT. It does not push anything back onto the operand stack. After '3' is printed out by the 'print' operator the stacks look like this:

Operand Stack: 
Execution Stack: 

Next we do a little more math.

Chapter 4. Variables

There are only a few simple types of variables in the Ripley system.

The variable types are discussed in more details, with examples, in the following sections.

4.1. More About the Different Variable Types

The next sections talk in detail about each of the different variable types.

Chapter 5. Making New Functions

Function in Ripley are just executable arrays that have been assigned as elements in the user dictionary. To define a function we use an executable array and the 'def' operator that we used in the variable assignment section from before. Here is an example where I create a function that prints "Hello World!":

Arguments to functions are implemented using the operand stack, just like every other Ripley function. Here is an example add10 function, which adds 10 to whatever you give it:

Chapter 6. Ifs and Elses

Understanding how conditionals are implemented in Ripley requires knowing how executable arrays work, and the system dictionary values of true and false.

First is the 'if' operand, which takes two operands. The first is a boolean value, then second is an executable array. For example, this code block will always execute:

The next example never prints because the boolean is negative.

Well, that's great, if you want a conditional that is not conditional. So we need some comparison operators. Which is where eq, lt, le, gt, and ge come in handy. These functions take two operands off the operand stack, then push one boolean value back onto the operand stack. Here is an example of a function that prints a string if the value 'passed' in on the stack is greater than ten.

If we have an if then else type of syntax then we could implement a printer that prints out one string if it's greater than 10 and another if it's less. This is where the ifelse operator comes in handy. It takes three operands off the operand stack; the first is a boolean, the next an executable array that is executed if the boolean is true, and the next is an executable array that is executed if the value is false. (An easy way to remember which one is which is by matching the first executable array with the 'if' portion of the name and the second executable array with the 'else' portion.) Here is an example of the geTenPrint implemented using 'ifelse'.

Chapter 7. Loops and such

The last thing you need for minimal language completeness is some sort of looping construct. Ripley comes with two. The first is a 'loop' operand that continues executing an executable array until the 'exit' operator is called. The 'exit' operator sets a flag which is caught by the while when it is next executed and the while halts. Below is an example of the loop operator:

In this example we use the 'loop' operand in concert with the 'if' and 'exit' operators to count from 0 to 10 and to print the values as we count up.

The other looping operator is the forall operator which iterates over an array, adding each item to the operand stack each time through, then executing an executable array. Below is an example of using the 'forall' operator to print out an array:

Forall takes two operands off the operand stack. The first is the array to iterate over, the second is an executable array to invoke with each item. As each item is iterated over the item is pushed onto the operand stack. That's why the first 'print' works in the executable array in the previous example.

The 'exit' operand can also be used within a 'forall' construct. In the example below the code iterates through the array but breaks if the value is above 50:

Appendix A. Ripley Operands

The following sections go into detail about the Ripley operands.