The main concept of Grasp is that the code (and data) is a directed multigraph (multidigraph) labeled nodes and edges. It is this mostly superficial similarity to Lisp (w.r.t. the "code and data both are lists" thing) that was an inspiration for the name. The name is an abbreviation of "GRAphS are being Processed".
Summary of the specification
Grasp scalar values (node labels) are either (double-precision floating point) numbers or strings; edge labels are always strings.
More complicated data structures are built as subgraphs.
Singly linked lists connected by
next edges is used to for stacks and (non-constant) strings by the instruction set.
A running Grasp system has a list of IPs that contain a call stack that refer to nodes in the graph.
At each "tick", the list of IPs is processed, and the current node of each IP is interpreted as a command and executed.
After the execution, a
next edge is followed to find the new current node.
cond can be used for conditional execution, and edges labeled
name assign names to nodes.
The instruction set provides instructions for manipulating the graph, as well as for doing simple arithmetics and IO.
Control structures are built by adjusting the
next edges, possibly conditionally.
For further details, see the full specification.
(This program was written against an old version of the spec; the "adde" and "dele" instructions should be "new" and "del" now.)
The "getc" node reads a single character and stores in the node (initially) containing "c". The "add" node increments the value by one, so that an EOF value (-1) becomes zero. The "dele" node unconditionally clears any next edge of the "adde" node, and the "adde" node adds it back if the "c+1" node contains a nonzero value, i.e., if EOF was not read. The "putc" node writes the character, and the loop continues.
Work in progress.