Skip to content
gvx edited this page Apr 13, 2011 · 4 revisions

Strings

Strings are the only things in Déjà Vu syntax that can contain # characters without starting a comment, so they are processed before comments. Strings start and end with double quote characters ("). Strings do not to be seperated with whitespace from anything, even other strings. So this works:

>> . ."a""b"
a
b

Comments

Comments are started by # and run to the end of the line.

Words

Words are seperated by whitespace. Not counting strings and special cases, there are three kind of words:

  • Numbers. Examples: 0, 3, -504
  • Proper words. Examples: +, drop, []
  • Idents. They represent proper words, without calling them. Think of them as references. Examples: '+', 'name-error', '('

Numbers, strings and idents are pushed to the stack, proper words are called.

Calling a word can result in two things: if the word refers to a number, string or ident, that value is pushed to the stack. If it refers to a function of any kind, that function is called.

There are two kinds of functions: Déjà Vu functions and Python functions. The Standard Library is implemented in Python.

Statements

Functions

A function can be defined in four ways:

func something:
    something-else

something:
    something-else

local something:
    something-else

labda:
    something-else

The first two are synonymous, as the second is simply syntactic sugar for the first.

The third is similar to the first two, only it binds the function to the local closure, instead of the global environment.

The fourth is what is generally called an anonymous function or lambda expression. Note it is spelled labda in Déjà Vu. (Those who have studied Ancient Greek know why.)

A labda is pushed on the stack instead of bound to a name. The following expressions are therefore equal:

func this:
     that

labda:
     that
set 'this'

Conditionals

Déjà Vu has if, elseif and else, which work like you would expect:

if < x 0:
    . "x is negative"
elseif > x 0:
    . "x is positive"
else:
    . "x is zero"

Loops

There are two types of loops: while and for.

While-loops work as you would expect:

set 'x' 5
while > x 0:
    . x
    set 'x' - x 1

For loops are a bit more interesting. The basic form is:

for counter-name some-code:
    body

When the loop is entered, some-code is run. Next, a value is taken from the stack. This can be either a reference to a function, or an ident for a function. This function is called. It is expected to push three values to the stack, like this:

[things already on the stack] func hidden item

func can be either (an ident to) a function, in which case that will be called next iteration, or zero, in which case the loop will end. Whether or not body will be executed one last time or not depends on the truth-value of hidden. If func is non-zero, hidden will be kept around as hidden state and pushed onto the stack before func is called. If func is non-zero or hidden is true, item is then locally bound to the name counter-name, after which body is executed.

A useful function is stop-iter, defined in the standard library, which simply pushes three zeros to the stack.

If you don't intend to write your own iterators, in and range are still useful:

>> for x range 1 4:
..      . x
.. 
1
2
3

>> for n in [ 1 9 5 ]:
..      . n
..
1
9
5

Like many stdlib functions, in destructively updates the stack passed to it.

Note that unlike in a while-loop, the some-code part is run only once and can be safely moved to the line above:

>> in [ 4 2 ]
>> for n:
..      n
..
4
2

Error handling

This will be replaced by a better explanation of error handling in Déjà Vu. Here's an example:

>> catch . pop-from . :
..      this-word-does-not-exist
name-error
this-word-does-not-exist

Also very nice: catch-if, which re-raises the exception if it isn't of the proper type:

>> catch catch-if 'name-error':
..      this-word-does-not-exist
Clone this wiki locally