commit e1790c55bd011eca3251c46766cc759a47039091
Author: Lassi Kortela Welcome to
+
+
+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB)
+
+ Scheme is a dialect of Lisp that stresses conceptual elegance and simplicity.
+It is specified in R4RS and IEEE standard P1178. Scheme is much smaller
+than Common Lisp; the specification is about 50 pages, compared to Common
+Lisp's 1300 page draft standard. (See the Lisp FAQ for details on standards
+for Common Lisp.) Advocates of Scheme often find it amusing that the entire
+Scheme standard is shorter than the index to Guy Steele's "Common
+Lisp: the Language, 2nd Edition". Scheme is often used in computer science curricula and programming language
+research, due to its ability to represent many programming abstractions
+with its simple primitives. There are a lot of traditional SCHEME interpreter available such as
+Chez, ELK 2.1, GAMBIT, MITScheme, scheme->C, Scheme48, T3.1, VSCM and
+Scm4e. Many free Scheme implementations (as well as SCM) are available
+from swiss-ftp.ai.mit.edu [18.43.0.246]. Galapagos is built over the SCM interpreter version 4e4 written by Aubrey
+Jaffer <jaffer@ai.mit.edu>. LOGO is a programming language designed for use by learners, including
+children. It is a dialect of LISP which has a more natural syntax, using
+infix arithmetics and (almost) no parentheses. LOGO features a "turtle"
+which can be instructed to move across the screen and draw shapes. This
+became known as "Turtle Graphics" or "Turtle Geometry"
+- a geometry that describes paths "from within" rather than "from
+outside" or "from above." For example, "turn right"
+means turn right relative to whatever direction you were heading before;
+by contrast, "turn east" specifies an apparently absolute direction.
+A Logo user or program manipulates the graphical turtle by telling it to
+move forward or back some number of steps, or by telling it to turn left
+or right some number of degrees. Turtle geometry has two major advantages. One is that many paths are
+more simply described in relative than in absolute terms. For example,
+it's easy to indicate the absolute coordinates of the corners of a square
+with vertical and horizontal sides, but it's not so easy to find the corners
+of an inclined square. In turtle geometry the same commands (go forward,
+turn right 90 degrees, etc.) work for squares with any orientation.
+The second advantage is pedagogic rather than computational: turtle geometry
+is compatible with a learner's own experience of moving in the world -
+it's "body syntonic." The two major goals behind Galapagos were: First, we wanted to create an environment suitable for teaching programming,
+patterned after Logo's environment and its easy-to-understand, easy-to-use
+turtle geometry. We chose Scheme as the programming language because of
+its educational value, as noted before. We added Turtle Graphics because
+of its ability to visualize computations, and thus help understanding them
+better. Second, we wanted to add parallel programming. The importance of multiprocessor
+machines and of multithreading is becoming more apparent every day, and
+so is the need for tools to help understanding parallel programming paradigms.
+By extending Scheme to be multithreaded, we wanted to create such a tool. Galapagos was developed to run under Windows 95, and should work under
+Window NT as well. (It uses 32-bit specific code so Win32s is not enough
+to run Galapagos). Both binary and source are available at the
+homepage:
+
+
+
+ We have extended Scheme in two main
+directions: Turtle graphics and multithreading: The turtle object lives on a board on which it can move and draw.
+A turtle can also communicate with the board and "see" colors
+or other turtles. Galapagos Scheme provides a set of primitives to create
+and manage such turtles and the boards they live on. A set of additional primitives enable the programmer to create multiple
+interpreters that run concurrently. The environment model was extended
+to support shared or thread-specific environments, and primitives to handle
+multiple environments were also added. A frame is a table which maps (or binds) names to values. An
+environment is a chained list of frames in which the interpreter works.
+ For example the command: (define x 7) creates a binding between x and the value 7. A typical environment looks like this:
+
+
+Spring 1997
+Graduation project
+Department of Math & Computer Science,
+Ben-Gurion University of the Negev
+
+Written by Elad Eyal and Miki
+Tebeka.
+
+Supervisor: Dr. Michael Elhadad
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122448/~elad/GALAPAGOS/stone.jpg b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122448/~elad/GALAPAGOS/stone.jpg
new file mode 100644
index 0000000..692b2ef
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122448/~elad/GALAPAGOS/stone.jpg differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122512/~elad/GALAPAGOS/gps.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122512/~elad/GALAPAGOS/gps.gif
new file mode 100644
index 0000000..5ec3570
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122512/~elad/GALAPAGOS/gps.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122524/~elad/GALAPAGOS/bgu_logo_tiny.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122524/~elad/GALAPAGOS/bgu_logo_tiny.gif
new file mode 100644
index 0000000..44b8d31
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122524/~elad/GALAPAGOS/bgu_logo_tiny.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122533/~elad/GALAPAGOS/background.html b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122533/~elad/GALAPAGOS/background.html
new file mode 100644
index 0000000..f606cb2
--- /dev/null
+++ b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970806122533/~elad/GALAPAGOS/background.html
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+Background
+
+
+
+
+
+
+
+SCHEME
+
+
+
+
+
+
+
+LOGO AND TURTLE GEOMETRY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+SCHEME EXTENSIONS
+
+
+
+
+
+
+
+
+
+THE NEW ENVIRONMENT MODEL
+
+
+
+
+
+
+Each rectangle denotes a frame and inside it are the bindings it holds.
+The rightmost rectangle is the global environment.
+
When a variable is evaluated, the interpreter first tries to find it
+in the current frame. If a suitable binding can't be found, the interpreter
+moves to the next frame in the environment and searched for a binding there.
+
In our example if we write x in the command line we'll get 12
+as the answer because all such computations take place at the global environment.
+
+
A function application is always evaluated with respect to the environment +the in which it was defined. (A function "holds" its environment, +hence the name "closure") This means that if we write
+ +(define (f) x)
+ +and then
+ +(f)
+ +the result will be
+ +12.
+
+
+
+
+

Under Galapagos's environment model, every interpreter works on its
+branch of an "environments tree", but can also evaluate an expression
+in any other environment in the tree. If two interpreters have a shared
+node on the tree, then from that point up (towards the global environment)
+all the bindings are the same for the two interpreters. The global environment
+is shared by all interpreters. If an interpreter changes the value of some
+variable, the binding is changed in all other interpreters that have access
+to the frame where the variable was declared. Obviously, caution should
+be taken when writing to a shared variable.
+
As an example, if a user created two new threads, called A and B, and +then evaluated:
+ +First thread> (define +x 7)
+ +(define (f) ...)
+ +Thread A> (define (g) +x)
+ +Thread B> (define x 4) +
+ +this is how the environment model would look like:
+

+
Now consider what happens when the user evaluates this:
+ +Thread A> (set! f g) +
+ +
+
+
Now, evaluating (f) in thread B will call the function defined
+in thread A. It will return 12 which is the value of x in f's environment.
+If thread A defines a new x (using define), it will affect the result
+of subsequent calls to f.
+
Sharing environments and frames are Galapagos's way of allowing shared
+data. By default, however, most calculations are done at thread-specific
+frames. (More on this subject in the next section). Primitives are supplied
+to explicitly reference and manage environments: clone-environment
+can create a copy of an environment (so changing a binding in one copy
+does not alter the other); extend-environment and pop-environment
+can add and remove frames to and from environments. More environment functions
+are found in the next section of this document.
+
A thread is a SCHEME interpreter. The base environment of a thread
+is the thread's topmost environment. All forms entered at the thread's
+console or as arguments to new-thread are evaluated in the base
+environment. In traditional SCHEME there is only one thread of execution.
+It is a single thread and its base environment is the global environment.
+In Galapagos many interpreters can run concurrently, and each have its
+own environment (changing dynamically as computation progresses) and a
+base environment (which can be explicitly changed).
+
One thread is created by Galapagos upon startup. It is called the main
+thread, and it lasts for the whole Galapagos session. Its base environment
+is the global one - much like a traditional Scheme interpreter. Additional
+threads can be created using new-thread. These have their base environment
+set to a new environment, containing a single fresh frame pointing to the
+global environment. Any calculation done at the new thread's console takes
+place in this thread-local environment. However, if closure functions are
+used, then their evaluation may take place at the global environment or
+at some other thread's space, depending on where that function was defined.
+
+
When a thread finishes the execution of its commands it terminates. +There are two exceptions to this rule:
+ +Threads can communicate using the predicate tell-thread or by
+using the asynchronous message-queues system described later. In addition,
+SCM's arbiters were improved to be multithread safe. An arbiter
+object can serve as a guard on a critical section (where only one thread
+can work at a given time) of the program. The relevant primitves are make-arbiter,
+try-arbiter, and release-arbiter.
+
Note: Galapagos supports Scheme's notation of continuations. +However, two restrictions apply:
+ +A console is a text window where the user can type commands (when
+the interpreter is idle) and see output. A console has a name which can
+be changed dynamically, which appears on its title bar. A thread may or
+may not be bound to a console. Information printed by a non-bound thread
+is lost; a non-bound thread waiting for input is stuck (unless provisions
+were made to allow a new console to be created by means of inter-thread
+communications.) If a non-bound thread has nothing to do, instead of waiting
+for input like a bound thread, it will terminate.
+
The main thread is always bound to a console. To bind a thread to a
+console use the command bind-to-console from within the thread.
+
A board (window) is the graphical board on which the turtles and the
+user draw. It is a bitmap on which the user can draw interactively, by
+using the supplied GUI, or by creating turtles and instructing them to
+do the drawings.
+
The controls of the graphical user interface are located on the toolbar.
+The "shapes" of drawing are either a rectangle, a line or free
+hand drawing. The user pen can have three widths which are found under
+the User Pen menu. The numbers next to the sizes are the widths
+in pixels.
+
The colors of the user pen can be changes either from the User Pen
+menu or from the toolbar's color buttons. When choosing from a toolbar
+button, the user can know exactly what color (in RGB format) is used.
+
Each window has a name which is written on its title bar which can be
+changed using the rename-window! command. The board can be cleaned
+from all drawings using the clear-window command.
+
Since the board is a bitmap it can be saved to a BMP file using the
+save-bitmap command. A new background from a bitmap file can be
+loaded using the load-bitmap command.
+
A turtle is an object which is connected to a certain board. Each turtle
+has a pen with which it can draw on that board. The user can change the
+state of the turtle's pen including giving it the color of the board's
+background color (using the pen-erase! command). The pen will draw
+when it is "down" and will not draw when it is "up".
+Turtles can move between boards using the move-turtle-to-window
+command.
+
Each turtle holds its location as the a pair of coordinates where 0,0
+is the upper left corner of the board and 800,600 is the bottom-right corner
+of the board. The turtle's location can be changed by giving the turtle
+commands such as forward!, backwards!, move-to! or by using the
+move button from the toolbar.
+
A turtle also has a heading which is the direction it will move on the
+forward! command. The heading is in degrees, 0 meaning upwards and
+increasing clockwise, thus 90 means rightwards and so on. A turtle's heading
+can be changed by commands such as right!, left!, and set-heading!
+or interactively, by using the move button on the toolbar and pressing
+the control key.
+
A turtle can be visible on the board or be hidden. When it is visible
+the user can decide if it wants a "solid" or "hollow"
+turtle using the make-hollow! and make-solid! commands.
+
A turtle is always connected to a certain board, which is the board
+it is drawing on. To create a new turtle on a board use the make-turtle
+or the clone-turtle commands. A new turtle (created with the make-turtle
+command) will be black, solid, heading north and with it's pen down, in
+the center of the board. A cloned turtle will have exactly the same inner
+state as its parent.
+
A turtle can also look at the board and see other turtles or colors. +By using the command look the user can tell the turtle the area +in which to look and what to look in this area.
+ +Example:
+ +The command
+ +(look t 50 20 '(0 0 0))
+ +will cause the turtle t to look for black pixels in the area +in radius 50 from the turtle and 20 degrees to each side of the heading +line, shown here in blue:
+ +![]()
+
A turtle can have interrupts. Each interrupt is defined in terms of
+turtle's vision. Whenever a turtle starts or stops seeing a given target,
+a predefined message is sent to the thread which asked the interrupt. The
+user can determine if the interrupt will notify on every change (like a
+"can see"- "can't see" toggle) or only when one change
+happens (only "can see" or "can't see" toggle). A message
+can be any valid SCHEME object.
+
Example:
+ +The command
+ +(turtle-notify t "I-see" "I-don't-see" 50 20 +color-black)
+ +tells the turtle t that every time it sees the color black it +should send the message "I-see" and when it doesn't see +the color black any more it should send the message "I-don't-see". +
+ +Below is an example of what messages (or no message) t will send
+while it is moving forward, encountering two black lines on its way:
+
+
+
+
+If the interrupt was of kind "can see" (notify-when command)
+only the "I-see" messages were sent, and if it was a the
+"can't see" interrupt (notify-when-not command) only the
+"I-can't-see" style messages were sent.
+
A special "user interrupt" is invoked when the user right-clicks
+the turtle or a window. The notify-on-click command is used to enable
+this.
+
A thread can tell the turtle to delete a certain interrupt using the
+turtle-no-notify command. It can also tell the turtle to disable
+all interrupts using the stop-notifying command.
+
In order to process the messages sent from a turtle's interrupt (or
+from another thread, as presented later) the thread must install a message
+handler which is a one argument function. If no handler is installed
+the turtle's messages are lost. There can be only one handler per thread.
+If the handler is installed then every time an interrupt is invoked, the
+handler function in called with the message sent by the interrupt as its
+argument.
+
+
Example:
+ +We declare the function:
+ +(define (my-print x) (write x) (newline))
+ +and then install my-print as the current handler with:
+ +(install-handler my-print)
+ +from now on every message a turtle's interrupt sends will be printed
+on screen. If my-print was installed in the previous example then
+we would have seen:
+
"I-see"
+ +"I-don't-see"
+ +"I-see"
+
on the screen.
+
A good example to view the interrupts in action is to make a turtle
+turn each time it sees a color and then let it wander aimlessly. Then use
+the user pen to draw lines the turtle's way and watch it change direction.
+See the PINGPONG.SCM file for a demo program.
+
The message-handler concept can be used as a mean of synchronous inter-thread
+communications. The tell-thread functions sends a message to a thread,
+which will be treated as an interrupt-generated message: It will cause
+the thread's message handler function to be called with tell-thread's argument
+as its own. This allows one thread to initiate a computation in a different
+thread's environment and CPU space synchronously and without sharing environments.
+
+
In order to let threads communicate between themselves asynchronously
+a system of message queues was developed. A queue is an object which stores
+and relieves messages, stored in FIFO (First In First Out) style, meaning
+messages are read in the order of arrival to the queue. Supported messages
+are pairs of type and body, both of which can be any valid SCHEME object.
+Looking for messages of a certain type is also supported, allowing implementation
+of more flexible communication schemes than plain FIFO.
+
A thread can check if there are any messages in a given queue, if it
+does get-message without checking first if there are messages in
+the queue it will wait a given time-out or forever if no time-out is given.
+If by the end of the time-out no message were in the queue the result will
+be false.
+
Example:
+ +In this example a queue q is created then a message is posted
+into the queue and read from it.
+
(define q (make-queue))
+ +(post-message q (cons 'type-circus 'bozo-the-clown))
+ +(define msg (get-message q))
+
now the command
+ +(car msg)
+ +will give
+ +type-circus
+ +and the command
+ +(cdr msg)
+ +will yield
+ +bozo-the-clown.
+ + ++
+
+
+
+
+
+
++ +
In order to make Galapagos more fun to learn with, an interactive GUI
+(Graphical User Interface) is provided. Users can make changes on the board
+while a computation is in progress and effect its execution. Drawing tools
+enable the user to draw on the board while a program is being executed.
+If a line is drawn in front of a turtle which has a relevant interrupt,
+the interrupt will be invoked if needed.
+
The user has a special user pen that can draw line, rectangles
+or free hand. These modes are available from the toolbar. The User's pen
+width and color can be modified using the User Pen menu or the toolbar.
+
Color buttons are provided on the toolbar to give a known RGB color +to the user pen. It is useful when the user draw an object on the board +and wants a turtle to see this object. The colors are:
+ +White - (255 255 255)
+ +Black - (0 0 0)
+ +Blue - (0 0 255)
+ +Red - (255 0 0)
+ +Green - (0 255 0)
+ +Yellow - (255 255 0)
+
Another option available is changing a turtle's heading and position, +using the Move Turtle button:
+ +![]()
+
If this button is pressed then a turtle can be dragged to a new location +simply by dragging it with the mouse. In order to change the turtle's heading, +hold down a control key and move the move towards the desired location, +the turtle will follow the movement of the mouse.
+ ++
+
+
+
+
+
+
++ +
Galapagos was written using Microsoft Visual C++, and is designed to
+run under Windows 95. We chose Windows 95 because it seems to have the
+largest potential Galapagos users base. The following sections describe
+some implementation details of Galapagos.
+
The SCM interpreter we used as a base is written in C. Most of the original
+code we added was written in C++. The parts we used from SCM are almost
+identical to the original. In fact, by changing the scmconfig.h file (which
+contain machine-specific configuration) and #defining THREAD to be null,
+the C files should become equivalent to the sources we used.
+
We have implemented two MT-safe FIFO message queue classes. Both will
+block when trying to read from an empty queue. CMsgQx, the extended
+message queue, supports the same interface as the one provided in Scheme,
+plus an additional support for "Urgent Messages". These take
+precedence over all other messages. CMessageQueue is message queue
+with exactly the same interface as the Scheme level message queues, but
+which contain internal logic to handle "Urgent" messages used
+to deal with cases where synchronous respond is needed, such as I/O, Garbage
+collection, and Scheme-level inter-thread communications.
+
Galapagos is based on SCM, which is a single-thread, read-evaluate-print-loop
+(repl) based Scheme interpreter. The most important issue in migrating
+SCM was how to maintain the interpreter's natural repl-based approach,
+yet allow for multiple threads to interact, and for Windows messages to
+be processed quickly.
+
We used WIN32's multithreading capabilities to solve these problems.
+A single thread handles all aspects of the GUI - in a sense, "all
+that is Windows": graphic boards, turtles, consoles, menus and so
+on. Each interpreter runs in a thread of its own, interacting with the
+GUI using a message queue similar to the one provided at the Scheme level.
+

+
The GUI thread manages both commands received from the OS and from the
+different interpreters running on their own threads. To ensure as fast
+responses as possible, priorities are used: OS messages (such as windows
+updates and input devices) gets highest priority; Console (text messages)
+come second, and graphics messages are last. This allows the interpreters
+to run interactively in a satisfactory manner.
+
SCM interpreter threads each run in the old-fashion repl mode. When
+a computation is over, the interpreter blocks until new input comes from
+the GUI thread. All blocking functions were modified to allow synchronous
+messages (such as the one generated by tell-thread) to work. In
+addition, SCM's "poll routine" is used to force checking for
+such messages even during computations.
+
An additional thread is used for Garbage Collection. It is described
+in detail in the section dealing with garbage collection.
+
In this section we will briefly describe SCM's garbage collector, and
+then discuss the modifications done to adapt it to Galapagos's multithreading
+computations. It should be noted that the garbage collector used is a portable
+garbage collector taken from "SCHEME IN ONE DEFUN, BUT IN C THIS TIME",
+by George J Carrette <gjc@world.std.com>.
+
SCM uses a conservative Mark & Sweep garbage collector (GC). All
+Scheme data objects share some common configuration (called "cells"):
+They are 8-byte aligned; they reside is specially-allocated memory segments
+(called hplims); they are the size of two pointers (so a scheme cons is
+exactly a cell); and they contain a special GC bit used by the garbage
+collector. This bit is 0 during actual computations. When a new cell is
+needed and all the hplims are used, garbage collection is initiated. If
+it does not free enough space to pass a certain threshold, a new hplim
+is allocated.
+
The first stage in garbage collection is marking all cells which are
+not to be deleted. Some terminology might be helpful here:
+
Obviously, all unreachable data is dead. Conservative garbage collectors
+treat all reachable data as alive.
+
The Mark stage of the garbage collector scans the sys_protects[]
+array and the machine's stack and registers for anything that looks like
+a valid cell. All cell pointer have their 3 least significant bits zero,
+and are in one of few known ranges (the hplims). The garbage collector
+searches for anything matching a cell's bit pattern, and treats it as an
+immediately reachable cell pointer. In some cases, this may mean an integer,
+for example, happens to match the binary pattern and thus be interpreted
+as a cell pointer. However, this will only mean some cell or cells are
+marked as reachable though they are not such. Because of the uniform structure
+of the cell and its limited range of possible locations, such an accident
+is guarantied not to corrupt memory. Furthermore, if we accept the assumption
+that integers are usually relatively small, and memory addresses are relatively
+big, we conclude that such accidents are not very likely to happen often
+anyway.
+
During mark stage, the garbage collector recursively finds (a superset
+of) all live cells, and marks them by setting their special GC bit to 1.
+The second stage is the Sweep stage, in which all the hplims are scanned
+linearly, and every cell which is not marked is recognized as dead, and
+as such is reclaimed as free. Marked cells get unmarked so they are ready
+for the next garbage collection.
+
Mark & Sweep garbage collection has two main disadvantages: One,
+that it requires all computation to stop while garbage collection is in
+progress. In Galapagos, since all threads use a shared memory heap, it
+means all threads must synchronize and halt while garbage is collected.
+Second, Mark & Sweep is very likely to cause memory fragmentation.
+However, since cells are equally sized, fragmentation is only rarely a
+problem.
+
We chose to stick with Mark & Sweep in Galapagos because of its
+two major advantages: Simplicity and efficiency. Mark & Sweep GC does
+not affect computation speed, because direct pointers are used. Most concurrent
+garbage collectors work by making all pointers indirect, which may slow
+computations down considerably. The need to halt all threads for GC is
+accepted. Since memory is shared, it would only be fair to stop all threads
+when GC is needed: Threads will probably halt anyway since cells are allocated
+continuously during computations.
+
Two major issues are introduced when trying to multithread the garbage
+collector. One is the synchronization of the different threads, which run
+almost completely unaware one of the other; the second is the need to mark
+data from every thread's specific stack, registers, and sys_protects[].
+We solved these two issues by combining them to one.
+
The intuitive approach might be to let each thread mark its own information,
+and then sweep centrally. However, since synchronization of threads is
+mandatory, letting every thread mark its own data will lead only to redundant
+marking and to excessive context switches, since each threads has to become
+active. Therefore we created the "Garbage Collection daemon"
+(GCd), which runs in a distinct thread and lasts for the whole Galapagos
+session. The GCd is not an interpreter, but a mechanism which keeps track
+of live threads and their need of GC. The GCd thread is always blocked,
+except when a thread notifies it on its birth or death, or when a thread
+indicates the need for garbage collection. Since the GC daemon is blocked
+whenever it is not needed, and then becomes the exclusive running thread
+during actual GC (with the exception of the GUI thread), its existence
+does not hurt performance.
+
To explain how the GCd synchronizes all threads, let us examine the
+three-way protocol involved. freelist
+is a global pointer which holds a linked list of free cells - it can be
+either a cell pointer, a value indicating "busy" (thus implementing
+busy/wait protection over it) or "end of memory" which is found
+at the end of the linked list. MIB stands for Memory Information
+Block, which is a block of memory containing all of a thread's
+immediately reachable data.
+
GCd scenario: GCd is blocked until a threads sends a GC +request.
+ +Scenario 1: A thread needs to allocate a cell but can't. +
+ +Scenario 2: A thread receives a MIB request. This +may happen within a computation or when considered otherwise blocked - +waiting for input, for example.
+ +The important thing to note about this protocol is its indifference
+to the GC "initiator". Several threads can "initiate"
+GC, and each request is "satisfied", although of course only
+one GC takes place. The GCd itself is unaware of the initiating thread
+identity, and completely ignores any further GC requests. It treats all
+threads identically. This is important because it allows each thread meeting
+a low memory condition to initiate GC immediately. This is in fact the
+mechanism which saves us from explicitly checking for a third-party GC
+request during computation: If a thread runs out of memory, the freelist
+variable is kept at "out of memory" state, causing any other
+thread trying to allocate memory to initiate GC as well. This simplifies
+the GC protocol (technically, if not conceptually), and does it with almost
+no affect on computation speed.
+
A board or a view as it called in MFC is the environment where a turtle
+moves and interact with. It hold two main data structures. The first is
+the bitmap of the drawing. It is a 800X600 bitmap. Every time a turtle
+draws on the board it makes its pen the active pen on the board and draws
+on it. Every time the picture needs refreshing (as signaled by the operating
+system) it is the board's duty to copy the relevant section from the bitmap
+to the screen. The second data object is the turtles list, an expandable
+array of turtles which holds pointers to all turtles on the specific board.
+
The most important part in the board's work is to notify the turtles
+on any event that happened on the board such as drawing, changing background
+or moving of a turtle. If for example a user draws a line on the board,
+the board (after drawing the line) goes through the turtles list and tell
+each one that some event happened at a rectangle that contains the line.
+Each turtle will decide if this has any importance to it or not.
+
Apart from that, the board handles all the user interface from the menus
+and the toolbar. The most obvious example is the move turtle button, which,
+when pressed, causes the board to find a turtle close enough to the click's
+location. Then, on every movement of the mouse it gives the turtle a command
+to move to this point.
+
In order to support scrolling of the picture, we derived the CBoardView
+class from CScrollView. The interface with the interpreter threads
+is done via a message queue. The main function is ReadAndEval,
+which gets a message and then interprets its and act upon the result.
+
In addition to a pointer to its current board, and to inner-state variable
+which affects its graphical aspects, every turtle holds an expandable array
+of interrupts. When a turtle gets from the window that a message signifying
+that some change has happened, it sends this change to each of its interrupts
+(only if the interrupt flag is on) and the interrupt is responsible to
+send an appropriate message if necessary. The turtle's location are stored
+as floating points on x,y axes, to allow for accuracy on the turtle's location
+and heading.
+
The turtles interacts with the interpreter thread using a message queue.
+As with the board, the main function here is the ReadAndEval,
+which translates these messages to valid function calls.
+
Every turtle holds a pointer to the bitmap it is drawing on. When it
+is "looking" for a color it calculates the minimal rectangle
+that holds the desired area. Then it iterates on all the pixels in this
+rectangle. First it checks if the pixel is in the vision area using the
+sign rule to determine if a point is clockwise or anti clockwise from a
+line, and then check for distance. If the point is in the relevant area
+the turtle gets its color from the bitmap and compares it with the sought
+color.
+
When looking for a specific turtle, the turtle gets this turtle's position
+and calculates if this location is in the relevant area using the same
+algorithm. When looking for any turtle, the turtle passes the relevant
+arguments to the view, which then uses the same algorithm for each turtle
+on its turtles array.
+
Each turtle holds an expandable array of interrupts. Each interrupts
+is an object that is much like a turtle vision. The interrupts has the
+view area argument and what it is looking for. It also has the message
+it needs to send and a pointer to the given queue. When the turtle notifies
+the interrupt that a change has happened, the interrupt first checks if
+the change is an area which is of interest to it. If so it calls the turtle
+look function with its location and the sought object. According to the
+turtle's answer and to the data stored inside the interrupt, the interrupt
+sends the needed message, if any.
+
+

Message-passing mechanisms:
+
+
+
+
+
+
+
+
+
++ +
+
Welcome to Galapagos Scheme. This chapter is intended
+as a quick reference to Galapagos's extensions over traditional Scheme.
+Knowledge of Scheme is assumed. Galapagos Scheme is compliant with both
+R4RS and IEEE standard P1178. If you've read the chapter titled
+"Scheme extensions", you can and should skip the short introduction
+in each section. This complete chapter appears as on-line help in Galapagos,
+just a F1 click away.
+
An environment is a list of frames, +with the global environment in its tail. A frame is a list +of bindings, which map variables to their values. (define...) +adds a binding to the frame at the top of the current environment. +(set!...) family of commands modify +an existing binding, in the frame where it was defined. When a variable +is referenced, the current environment is searched from head to tail, and +the first binding found dictates the value of the variable.
+ +The first interpreter, which pops up as Galapagos
+is started, runs at the global environment (the way traditional Scheme
+works). Additional interpreters (threads) run at distinct environments,
+which contain a single initially empty frame, and a pointer to the global
+environment.
+
+
(clone-environment
+env [depth])
+
Clone-environment will make an exact copy of the
+environment env, by copying its frames
+one by one. If depth is specified then the new environment will be the
+collection of frames which is up to depth
+frames from the current frame. And the last frame will point to the depth
++ 1 frames from the current one in env.
+
+
This means that if we are now in environment e1 +and done (define x 7). Then if we'll +write
+ +(define e2 (clone-environment +(current-environment))),
+ +the result of
+ +(eval@ e2 x) +
+ +will return 7.
+
But if we are not in a lower frame than the one +x was defined in and write
+ +(define e2 (clone-environment +(current-environment) 1))
+ +and write the value of x is undefined.
+ +(Unless it was defined in the global environment)
+
+
Note: Only the bindings are copied. The bound values +are not. Example:
+ +(define x (cons 1 2)) +
+ +(define e (clone-environment +(current-environment)))
+ +(eval@ e (set-cdr! X 6)) +
+ +will change the 2 into 6 at both environments. +However,
+ +(set! x 7) +
+ +will only affect one copy.
+
(pop-environment
+env)
+
Returns the current environment without the first +frame. This means the first frame on the list of frames is "popped" +out.
+ +If env was +made from f3->f2->f1->Global, the result will be f2->f1->Global. +
+ +(fx means frame number x)
+ +Example:
+ +(define e2 (pop-environment
+(current-environment)))
+
(extend-environment
+env)
+
Extends env with +a new empty frame (where nothing is defined yet).
+ +This means the if env +was f2->f1->Global the result will be f3->f2->f1->Global. +
+ +(fx means frame number x)
+ +Example:
+ +(define e2 (extend-environment
+(current-environment)))
+
(current-environment)
+
+
Returns the current environment.
+
(environment?
+env)
+
A predicate that is true if env +is an environment.
+ +Example:
+ +(environment? (current-environment)) +
+ +Will return true.
+
(parent-environment)
+
+
Returns the parent environment. This is the environment +where (new-thread) was called to create +this thread. The First thread returns the global environment.
+ +Example:
+ +(eval@ (parent-environment) +y)
+ +Will return the value of y in the parent environment.
+
(base-environment)
+
+
The environment where the interpreter runs.
+
(set-base-environment
+env)
+
Sets the base environment (where the interpreter +runs) to be env
+ +Example:
+ +(set-base-environment +(parent-environment))
+ +Will make this thread run in the same environment
+as its father)
+
(eval@ env forms...)
+
+
Evaluates forms in given environment.
+ +Example:
+ +(define x 7) +
+ +(define e2 (clone-environment +(current-environment)))
+ +(eval@ e2 x)
+
The result will be 7
+
(eval@p forms...)
+
+
Evaluates forms in parent environment.
+ +Example:
+ +Say we want to make our turtle walk 30 degrees +more than the father's turtle. Then we can write:
+ +(set-heading! T (+ 30
+(eval@p (turtle-heading t))))
+
Message queues are MT-safe mechanisms used to pass
+messages, possibly between threads. Messages accepted must be cons, its
+car being the message type and the cdr is the message body. Both can be
+any kind of Scheme object.
+
+
(make-queue) +
Creates a new message queue.
+ +Example:
+ +(define q (make-queue))
+
+
(message-queue? +q)
A predicate that is true if q +is a queue.
+ +Example:
+ +(message-queue? q)
+ +Will return true for q from the previous example.
+
(peek-message
+q [type])
+
Return true if there is a message (of given type, +or of any type if unspecified) in the queue q. +
+ +Example:
+ +(peek-message q) +
+ +Will return falsif the queue q is empty. +
+ +Note: types are compared using (equals?)
+.
+
(post-message
+q typ_msg)
+
Posts the message typ_msg +to the queue q.
+ +typ_msg must +be a cons (type . message).
+ +Example:
+ +(post-message q (cons
+'type-welcome 'hello))
+
(get-message [time-out]
+q [type])
+
Get message from queue q +, if time-out is defined +waits only time-out seconds, and
+ +optionally gets only messages from type type. +
+ +Example:
+ +(define msg (get-message +7 q 'type-welcome))
+ +The result will be (if the previous posting was +done) ('type-welcome . 'hello)
+ +Note: types are compared using (equals?)
+.
+
A window is the graphical board on which the turtles
+and the user draw. It is a bitmap of size 800x600.
+
+
(new-window [name])
+
+
Makes a new window, name +is a symbol or a string which will also be the window's title. The window's +color will be white and it's size 800x600.
+ +Example:
+ +(define w (new-window +'my-window))
+ +Will create a new window with the title my-window.
+
+
(rename-window!
+win [name])
+
Renames the window win. name +is a symbol or a string which will also be the window's title.
+ +Example:
+ +(rename-window! w 'foo) +
+ +Will make the title of w to be foo.
+
(set-background-color!
+R G B)
+
Set the background color of the window. All the +turtles in the window are notified on the new color (used in pen-erase) +
+ +The colors are defined in terms of Red +Green Blue +(where 0,0,0 is black and 255,255,255 is white).
+ +Example:
+ +(set-background-color! +w 255 255 0)
+ +Will turn the background color of w
+to yellow
+
(clear-window
+w)
+
Clears the screen from all the previous drawings, +leaving only the turtles images on it.
+ +Example:
+ +(clear-window w)
+
(load-bitmap w
+"filename" [x y])
+
Loads the bitmap "filename" +and makes it the background of w. x y are +the coordinates of the upper left corner of the picture. If x +y are not given then the picture is centered.
+ +Example:
+ +(load-bitmap w "c:\\windows\\forest.bmp")
+
+
This operation can also be done using the Board
+menu.
+
+
(save-bitmap w
+"filename")
+
Saves the window into a bitmap file called "filename". +
+ +Example:
+ +(save-bitmap w "my_draw.bmp")
+
+
This operation can also be done using the Board
+menu.
+
(window-alive?
+win)
+
True if win
+is alive, meaning it can get commands.
+
(window-name w) +
Returns the name of w. +
+ +Example:
+ +(window-name w) +
+ +Will return "foo" on our window.
+
A turtle is an object which is connected to a certain
+window. It has inner state variables:
+
- width: the width +of the pen.
+ +- heading: the direction +the turtle will go on command forward!. +The heading is in degrees where 0 is upwards and adding to the heading +means clock wise rotation.
+ +- visibility: if the +body of the turtle is visible on the board or not.
+ +- solid: if the turtle +is a "solid" turtle (its interior is also drawn) or "hollow" +one (only its circumference is drawn).
+ +- position: the location +of the turtle on the board, where 0,0 is the upper left corner. +
+ +- color: the color +of the turtle and it's pen, given in RGB format.
+ +- pen condition: the +turtle's pen can be in three states:
+ +- pen width: the width
+of the pen, the bigger the width the thicker the pen will be.
+
Turtles can also "see" the board or other
+turtles (only from the same board) and can handle user interrupts. A turtle
+is always connected to a certain view, which is the view it is drawing
+on. Turtles can move between views.
+
+
(make-turtle win
+[name])
+
Creates and return a new turtle, in window win, +optional name (where name can be anything). +
+ +The inner state of the new turtle will be: +
+ +Example:
+ +(define t (make-turtle
+'turty))
+
(turtle-alive?
+t)
+
A predicate that is true if t +is alive, meaning t can get commands. +
+ +Example:
+ +(turtle-alive? t)
+ +Will return true on our t.
+
(clone-turtle
+t [name])
+
Creates an identical turtle to t +(same inner state).
+ +Example:
+ +(define t2 (clone-turtle
+t))
+
(rename-turtle
+t [name])
+
Renames the turtle, name is a string or a symbol +
+ +Example:
+ +(rename-turtle t 'pongy)
+
+
(turtle-name t)
+
+
Returns the name of t. +
+ +Example:
+ +(turtle-name t) +
+ +Will return "pongy" on our t.
+
(forward! t d)
+
Makes t go +forward (in the heading of t) +d steps. +t will draw while going according to +the state of it's pen.
+ +Example:
+ +(forward! t 100) +
+ +Will cause t
+to go forward 100 steps. (In our case since t's
+heading hasn't changed it will go upwards)
+
(turtle-width! +t n)
Set the width of t's
+pen to be n. The bigger n
+is the wider the pen will be.
+
(backwards! t
+d)
+
Same as forward, just in the opposite direction. +
+ +Example:
+ +(backwards! t 100) +
+ +is the same as
+ +(forward! t -100)
+
(right! t d)
+
Will set a new heading to t. +The new heading is the old heading plus d, meaning +t will rotate clock-wise.
+ +Example:
+ +(right! t 90) +
+ +Will make t
+turn 90 degrees to the
+
(left! t d) +
Same as right, other direction
+
(set-heading!
+t val)
+
Sets the heading of t +to be val. 0 is upwards and 90 is to +the right.
+ +Example:
+ +(set-heading t 180) +
+ +Will cause t
+to point to the bottom of the screen.
+
(move-to! t x
+y)
+
Makes t move +to point x,y without painting. 0,0 +is the top-left corner of the window.
+ +Example:
+ +(move-to! T 100 100) +
+ +Will cause t
+to move to point 100,100.
+
(draw-to! t x
+y)
+
Moves t to +x,y possibly drawing or erasing according +to the state of t's pen.
+ +Example:
+ +(draw-to! t 0 0)
+
(move-turtle-to-window +t win)
Move t to the +window win
+ +Example:
+ +(move-turtle-to-window
+t w)
+
(pen-up! t)
+
The pen of t +is up, so he won't paint when moving.
+ +Example:
+ +(pen-up! t)
+
(pen-down! t)
+
Causes t's
+pen to be down, meaning he will draw as he is moving.
+
(pen-erase! t)
+
Causes t's
+pen to be in the same color as the background color of the window it is
+attached to.
+
(show-turtle!
+t)
+
Makes t visible. +Meaning he will be seen on the board.
+ +Example:
+ +(show-turtle! t)
+
(hide-turtle!
+t)
+
Makes t invisible. +Meaning he will not be seen on the board. (but all the drawing he does +will be seen)
+ +Example:
+ +(hide-turtle! t)
+
(make-turtle-solid!
+t)
+
Makes t a solid
+turtle.
+
(make-turtle-hollow!
+t)
+
Make t a "hollow"
+turtle.
+
(kill-turtle!
+t)
+
Kills t. Meaning +it will be erased from the board and will not accept further commands. +
+ +Note: This is the only way to get rid of a turtle. +
+ +Example:
+ +(kill-turtle! t) +
+ +Will cause when writing t +in the command line to the response
+ +#<dead turtle>
+
(set-color! t
+R G B) or (set-color! t (list R G B)
+
Sets t's color +(and it's pen), in RGB format.
+ +Example:
+ +(set-color! t 255 0 255) +
+ +Will cause t +to be pinkish.
+ +Same as:
+ +(define pinkish '(255 +0 255))
+ +(set-color! t pinkish)
+
(turtle-inner-state
+t)
+
Returns a list of 6 parameters: color, heading, +hidden-flag, pen width, solid flag, location (cons x y))
+ +Example:
+ +(define new-t (make-turtle +w))
+ +(turtle-inner-state new-t) +
+ +Will return the list
+ +((0 0 0) 0.0 #f 2 #t (400.0
+. 300.0))
+
Below are functions that returns only one of the
+parameters returned by turtle-inner-state:
+
+
(turtle-color t) +
+ +(turtle-heading t) +
+ +(turtle-visible t) +
+ +(turtle-width t) +
+ +(turtle-solid? t) +
+ +(turtle-position t)
+
A turtle can interact with the board. It can "see"
+colors or other turtles.
+
+
(look t distance
+angle '(R G B))
+
Will return true if there is a point in color (R +G B) in distance distance from +t and in the area bordered by the angle +2*angle.
+ +Example:
+ +(look t 50 20 '(0 0 0)) +
+ +Will cause t
+to search for the color black (RGB 0,0,0) in the area shown here in blue:
+
![]()
+
(look t distance
+angle [t1])
+
Same as if looking for color, just this time it +will be true is t1 is in the visible area.
+ +If no target turtle is defined then the function +will return true if any turtle from this window is in the visible area. +
+ +Example:
+ +(define new-t (clone-turtle +t))
+ +(forward! new-t 30) +
+ +(look t 50 20 new-t) +
+ +And
+ +(look t 50 20) +
+ +Will both return true.
+
+
A turtle can hold a list of interrupts (or notifications).
+When an interrupt is invoked it send a given message to the thread that
+sent the command. Every interrupt is defined by a "look" arguments.
+An interruptcan be of three kinds:
+
A "yes" interrupt - The interrupt will +happen (message sent) on every "first" time the look returns +yes.
+ +Meaning if a turtle is told to invoke an interrupt
+every time it sees blue on a certain region. Then the first time it sees
+blue it will invoke the interrupt. From now on if the blue is in view it
+will not invoke the interrupt. Then if it loses sight of the blue object,
+the next time it sees blue again it will invoke the interrupt, and so on.
+
A "no" interrupt - Same as the "yes"
+interrupt, just this time the interrupt is invoked when the sought object
+is not seen.
+
A "both" interrupt - First time the sought +object is viewed the "yes" message is sent, then the first time +the turtle loses sight of the object the "no" message is sent +and so on.
+ +A message can be any SCHEME object.
+
When the interpreter is installing interrupt to +a turtle it need to install a handler, which is a function that +takes only one argument and this argument is the messages that comes from +the interrupt.
+ +If no handler is installed, the messages will be +sent but will have no affect on the thread of execution.
+ +There can be only one handler per thread and a
+handler can not be a primitive procedure.
+
(turtle-notify +t msg1 msg2 distance angle TARGET)
Instructs a turtle to send msg1 and msg2 upon seeing +and not seeing, respectively, the target. The messages can be any Scheme +objects, which are sent to the thread as if by (tell-thread). The other +parameters - see (look)
+ +Example:
+ +(turtle-notify t 'yes +'no 50 10 new-t)
+ +This is a "both" kind interrupt.
+
(turtle-no-notify
+t distance angle TARGET)
+
Tells the turtle to stop notifying in the given
+case. Very like deleting the interrupt from the turtle.
+
(notify-when[-not]
+t1 msg dist ang TARGET)
+
Instructs a turtle to send msg upon [stopping] +seeing the target. This is a "yes" or "no" interrupt. +
+ +Example:
+ +(notify-when t 'gotcha +50 10 new-t)
+ +Will cause t
+to send the message "gotcha" every "first" time it
+sees new-t.
+
(stop-notifying
+t)
+
t will temporarily
+stop notifying on interrupts. Like "clear interrupts".
+
(continue-notifying
+t)
+
t will resume
+notifying on interrupts.
+
(no-notifications +t)
Deletes all t's
+interrupts.
+
(notify-on-click
+turtle msg)
+
Instructs turtle to send msg when right-clicked +with the mouse (distance of 5 pixels from the turtle location). There can +be only one interrupt of this kind per turtle.
+ +Example:
+ +(notify-on-click t 'ouch) +
+ +Will case t
+to send the message "ouch" when the user right-clicks next to
+it.
+
(notify-on-click
+window msg)
+
Instructs window to
+send msg when right-clicked with the
+mouse not close to any turtle.
+
(clear-notify-click
+t)
+
Clears the user right click interrupt
+
(install-handler
+func)
+
Installs a message handler. When a message arrives, +func is called with it as a sole argument. +
+ +There can be only one handler per thread. func +can not be a primitive procedure.
+ +Example:
+ +(define (print x) (write +x))
+ +(notify-on-click t 'click-on-t) +
+ +(install-handler print) +
+ +Will cause that the message "click-on-t"
+will be printed each time the user right clicked on t.
+
+
Galapagos supports multiple threads. Every thread
+is a complete Scheme interpreter, with its own base environment. Every
+thread has a Thread Object, which uniquely identifies it.
+
A console is a text window where the user
+can type commands (when the interpreter is idle) and see output. A thread
+may or may not be bound to a console. Information printed by a non-bound
+thread is lost; a non-bound thread waiting for input is stuck (unless provisions
+were made to allow a new console to be created by means of inter-thread
+communications.) If a non-bound thread has nothing to do, instead of waiting
+for input like a bound thread, it will terminate.
+
(this-thread)
+
Returns the thread-object of the current thread. +
+ +Example:
+ +(this-thread) +
+ +Will return something like
+ +#<thread 0x6d1e2c>
+
+
(is-first-thread?)
+
+
True if the current thread is the first SCM thread.
+
(thread? t) +
True if t is a thread
+ +Example:
+ +(thread? (this-thread)) +
+ +Will return true
+
(active-threads)
+
+
Returns the number of active threads
+
(new-thread form+) +
Creates a new thread that will calculate the form[s] +
+ +Example:
+ +(new-thread (define t +(make-turtle w)) (forward! t 200))
+ +Will make a new thread that will create a new turtle +and will move it forward 200 steps and then terminates.
+ +(new-thread (bind-to-console)) +
+ +Will make a new thread that's ready to accept commands
+form a newly-created window. The same can be achieved by selecting "Fork"
+from "Scheme" menu.
+
+
+
(break& form+)
+
+
Causes the current thread to stop and calculate
+the form[s]. The current computation is lost.
+
(bind-to-console)
+
+
The thread will get its commands from a console. +
+ +Example:
+ +(new-thread (bind-to-console)) +
+ +Will create a new thread that gets it.
+
(unbind-console) +
Close bound console.
+
(rename-console +name)
New name for the current console
+
(install-handler
+func)
+
Installs a message handler. When a message arrives, +func is called with it as a sole argument. +
+ +There can be only one handler per thread. func +can not be a primitive procedure.
+ +Example:
+ +(define (print x) (write +x))
+ +(notify-on-click t 'click-on-t) +
+ +(install-handler print) +
+ +Will cause that the message "click-on-t" +will be printed each time the user right clicked on t. +
+ +Note: (new -thread (install-handler
+f)) is a bad idea, because the fresh thread will terminate immediately.
+
+
(tell-thread th
+x)
+
Sends message X +to thread th. Returns true on success. +
+ +If th has no
+handler installed it will cause nothing.
+
(quit-thread)
+
Kills the current thread, does not work on the
+main thread.
+
(quit-program)
+
Quits the program.
+
+
+
These are primitives taken from SCM, which were +modifies to be multithread-safe: + +
+ + ++An arbiter +is a data object the canbe used as a +guard for critical sections. It can be either "locked" or "unlocked". It +is ideal when a busy/wait mechanism is required, since it is MT-safe. +
+ + +(sleep n) +
Causes the current thread to block for (approximately)
+n seconds. (sleep 0) is a way to instruct
+a thread to give up its remaining processor time.
+
(make-arbiter
+name)
+
Makes an arbiter called name. +
+ +Example:
+ +(define x-arb (make-arbiter
+'x-guard))
+
+
(try-arbiter arb)
+
+
Checks if the arbiter arb +is up. If the arbiter is up returns false, otherwise it sets +the arbiter to be "up" and returns true.
+ +Example:
+ +(try-arbiter x-arb) +
+ +Will return true and set x-arb
+to be "up". But trying it for the second time return false since
+x-arb is "up".
+
(release-arbiter
+arb)
+
Set the arb +to be "down". If the arbiter was "up" returns true +otherwise returns false.
+ +Example:
+ +(release-arbiter x-arb) +
+ +Will return true , but using this function again +will return false since x-arb is already +down.
+ + ++
+
+
+
+
++ +
+ +
+ +
+ +
+ +
+
+
+
+
+
+
+ ++
+ ++
+Welcome to
+
+
+

+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB) Welcome to
+
+
+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB)
+
+ In order to make Galapagos more fun to learn with, an interactive GUI
+(Graphical User Interface) is provided. Users can make changes on the board
+while a computation is in progress and effect its execution. Drawing tools
+enable the user to draw on the board while a program is being executed.
+If a line is drawn in front of a turtle which has a relevant interrupt,
+the interrupt will be invoked if needed. The user has a special user pen that can draw line, rectangles
+or free hand. These modes are available from the toolbar. The User's pen
+width and color can be modified using the User Pen menu or the toolbar. Color buttons are provided on the toolbar to give a known RGB color
+to the user pen. It is useful when the user draw an object on the board
+and wants a turtle to see this object. The colors are: White - (255 255 255) Black - (0 0 0) Blue - (0 0 255) Red - (255 0 0) Green - (0 255 0) Yellow - (255 255 0) Another option available is changing a turtle's heading and position,
+using the Move Turtle button: If this button is pressed then a turtle can be dragged to a new location
+simply by dragging it with the mouse. In order to change the turtle's heading,
+hold down a control key and move the move towards the desired location,
+the turtle will follow the movement of the mouse.
+
+
+ Galapagos was written using Microsoft Visual C++, and is designed to
+run under Windows 95. We chose Windows 95 because it seems to have the
+largest potential Galapagos users base. The following sections describe
+some implementation details of Galapagos. The SCM interpreter we used as a base is written in C. Most of the original
+code we added was written in C++. The parts we used from SCM are almost
+identical to the original. In fact, by changing the scmconfig.h file (which
+contain machine-specific configuration) and #defining THREAD to be null,
+the C files should become equivalent to the sources we used. We have implemented two MT-safe FIFO message queue classes. Both will
+block when trying to read from an empty queue. CMsgQx, the extended
+message queue, supports the same interface as the one provided in Scheme,
+plus an additional support for "Urgent Messages". These take
+precedence over all other messages. CMessageQueue is message queue
+with exactly the same interface as the Scheme level message queues, but
+which contain internal logic to handle "Urgent" messages used
+to deal with cases where synchronous respond is needed, such as I/O, Garbage
+collection, and Scheme-level inter-thread communications. Galapagos is based on SCM, which is a single-thread, read-evaluate-print-loop
+(repl) based Scheme interpreter. The most important issue in migrating
+SCM was how to maintain the interpreter's natural repl-based approach,
+yet allow for multiple threads to interact, and for Windows messages to
+be processed quickly. We used WIN32's multithreading capabilities to solve these problems.
+A single thread handles all aspects of the GUI - in a sense, "all
+that is Windows": graphic boards, turtles, consoles, menus and so
+on. Each interpreter runs in a thread of its own, interacting with the
+GUI using a message queue similar to the one provided at the Scheme level. The GUI thread manages both commands received from the OS and from the
+different interpreters running on their own threads. To ensure as fast
+responses as possible, priorities are used: OS messages (such as windows
+updates and input devices) gets highest priority; Console (text messages)
+come second, and graphics messages are last. This allows the interpreters
+to run interactively in a satisfactory manner. SCM interpreter threads each run in the old-fashion repl mode. When
+a computation is over, the interpreter blocks until new input comes from
+the GUI thread. All blocking functions were modified to allow synchronous
+messages (such as the one generated by tell-thread) to work. In
+addition, SCM's "poll routine" is used to force checking for
+such messages even during computations. An additional thread is used for Garbage Collection. It is described
+in detail in the section dealing with garbage collection. In this section we will briefly describe SCM's garbage collector, and
+then discuss the modifications done to adapt it to Galapagos's multithreading
+computations. It should be noted that the garbage collector used is a portable
+garbage collector taken from "SCHEME IN ONE DEFUN, BUT IN C THIS TIME",
+by George J Carrette <gjc@world.std.com>. SCM uses a conservative Mark & Sweep garbage collector (GC). All
+Scheme data objects share some common configuration (called "cells"):
+They are 8-byte aligned; they reside is specially-allocated memory segments
+(called hplims); they are the size of two pointers (so a scheme cons is
+exactly a cell); and they contain a special GC bit used by the garbage
+collector. This bit is 0 during actual computations. When a new cell is
+needed and all the hplims are used, garbage collection is initiated. If
+it does not free enough space to pass a certain threshold, a new hplim
+is allocated. The first stage in garbage collection is marking all cells which are
+not to be deleted. Some terminology might be helpful here: Obviously, all unreachable data is dead. Conservative garbage collectors
+treat all reachable data as alive. The Mark stage of the garbage collector scans the sys_protects[]
+array and the machine's stack and registers for anything that looks like
+a valid cell. All cell pointer have their 3 least significant bits zero,
+and are in one of few known ranges (the hplims). The garbage collector
+searches for anything matching a cell's bit pattern, and treats it as an
+immediately reachable cell pointer. In some cases, this may mean an integer,
+for example, happens to match the binary pattern and thus be interpreted
+as a cell pointer. However, this will only mean some cell or cells are
+marked as reachable though they are not such. Because of the uniform structure
+of the cell and its limited range of possible locations, such an accident
+is guarantied not to corrupt memory. Furthermore, if we accept the assumption
+that integers are usually relatively small, and memory addresses are relatively
+big, we conclude that such accidents are not very likely to happen often
+anyway. During mark stage, the garbage collector recursively finds (a superset
+of) all live cells, and marks them by setting their special GC bit to 1.
+The second stage is the Sweep stage, in which all the hplims are scanned
+linearly, and every cell which is not marked is recognized as dead, and
+as such is reclaimed as free. Marked cells get unmarked so they are ready
+for the next garbage collection. Mark & Sweep garbage collection has two main disadvantages: One,
+that it requires all computation to stop while garbage collection is in
+progress. In Galapagos, since all threads use a shared memory heap, it
+means all threads must synchronize and halt while garbage is collected.
+Second, Mark & Sweep is very likely to cause memory fragmentation.
+However, since cells are equally sized, fragmentation is only rarely a
+problem. We chose to stick with Mark & Sweep in Galapagos because of its
+two major advantages: Simplicity and efficiency. Mark & Sweep GC does
+not affect computation speed, because direct pointers are used. Most concurrent
+garbage collectors work by making all pointers indirect, which may slow
+computations down considerably. The need to halt all threads for GC is
+accepted. Since memory is shared, it would only be fair to stop all threads
+when GC is needed: Threads will probably halt anyway since cells are allocated
+continuously during computations. Two major issues are introduced when trying to multithread the garbage
+collector. One is the synchronization of the different threads, which run
+almost completely unaware one of the other; the second is the need to mark
+data from every thread's specific stack, registers, and sys_protects[].
+We solved these two issues by combining them to one. The intuitive approach might be to let each thread mark its own information,
+and then sweep centrally. However, since synchronization of threads is
+mandatory, letting every thread mark its own data will lead only to redundant
+marking and to excessive context switches, since each threads has to become
+active. Therefore we created the "Garbage Collection daemon"
+(GCd), which runs in a distinct thread and lasts for the whole Galapagos
+session. The GCd is not an interpreter, but a mechanism which keeps track
+of live threads and their need of GC. The GCd thread is always blocked,
+except when a thread notifies it on its birth or death, or when a thread
+indicates the need for garbage collection. Since the GC daemon is blocked
+whenever it is not needed, and then becomes the exclusive running thread
+during actual GC (with the exception of the GUI thread), its existence
+does not hurt performance. To explain how the GCd synchronizes all threads, let us examine the
+three-way protocol involved. freelist
+is a global pointer which holds a linked list of free cells - it can be
+either a cell pointer, a value indicating "busy" (thus implementing
+busy/wait protection over it) or "end of memory" which is found
+at the end of the linked list. MIB stands for Memory Information
+Block, which is a block of memory containing all of a thread's
+immediately reachable data. GCd scenario: GCd is blocked until a threads sends a GC
+request. Scenario 1: A thread needs to allocate a cell but can't.
+ Scenario 2: A thread receives a MIB request. This
+may happen within a computation or when considered otherwise blocked -
+waiting for input, for example. The important thing to note about this protocol is its indifference
+to the GC "initiator". Several threads can "initiate"
+GC, and each request is "satisfied", although of course only
+one GC takes place. The GCd itself is unaware of the initiating thread
+identity, and completely ignores any further GC requests. It treats all
+threads identically. This is important because it allows each thread meeting
+a low memory condition to initiate GC immediately. This is in fact the
+mechanism which saves us from explicitly checking for a third-party GC
+request during computation: If a thread runs out of memory, the freelist
+variable is kept at "out of memory" state, causing any other
+thread trying to allocate memory to initiate GC as well. This simplifies
+the GC protocol (technically, if not conceptually), and does it with almost
+no affect on computation speed. A board or a view as it called in MFC is the environment where a turtle
+moves and interact with. It hold two main data structures. The first is
+the bitmap of the drawing. It is a 800X600 bitmap. Every time a turtle
+draws on the board it makes its pen the active pen on the board and draws
+on it. Every time the picture needs refreshing (as signaled by the operating
+system) it is the board's duty to copy the relevant section from the bitmap
+to the screen. The second data object is the turtles list, an expandable
+array of turtles which holds pointers to all turtles on the specific board. The most important part in the board's work is to notify the turtles
+on any event that happened on the board such as drawing, changing background
+or moving of a turtle. If for example a user draws a line on the board,
+the board (after drawing the line) goes through the turtles list and tell
+each one that some event happened at a rectangle that contains the line.
+Each turtle will decide if this has any importance to it or not. Apart from that, the board handles all the user interface from the menus
+and the toolbar. The most obvious example is the move turtle button, which,
+when pressed, causes the board to find a turtle close enough to the click's
+location. Then, on every movement of the mouse it gives the turtle a command
+to move to this point. In order to support scrolling of the picture, we derived the CBoardView
+class from CScrollView. The interface with the interpreter threads
+is done via a message queue. The main function is ReadAndEval,
+which gets a message and then interprets its and act upon the result. In addition to a pointer to its current board, and to inner-state variable
+which affects its graphical aspects, every turtle holds an expandable array
+of interrupts. When a turtle gets from the window that a message signifying
+that some change has happened, it sends this change to each of its interrupts
+(only if the interrupt flag is on) and the interrupt is responsible to
+send an appropriate message if necessary. The turtle's location are stored
+as floating points on x,y axes, to allow for accuracy on the turtle's location
+and heading. The turtles interacts with the interpreter thread using a message queue.
+As with the board, the main function here is the ReadAndEval,
+which translates these messages to valid function calls. Every turtle holds a pointer to the bitmap it is drawing on. When it
+is "looking" for a color it calculates the minimal rectangle
+that holds the desired area. Then it iterates on all the pixels in this
+rectangle. First it checks if the pixel is in the vision area using the
+sign rule to determine if a point is clockwise or anti clockwise from a
+line, and then check for distance. If the point is in the relevant area
+the turtle gets its color from the bitmap and compares it with the sought
+color. When looking for a specific turtle, the turtle gets this turtle's position
+and calculates if this location is in the relevant area using the same
+algorithm. When looking for any turtle, the turtle passes the relevant
+arguments to the view, which then uses the same algorithm for each turtle
+on its turtles array. Each turtle holds an expandable array of interrupts. Each interrupts
+is an object that is much like a turtle vision. The interrupts has the
+view area argument and what it is looking for. It also has the message
+it needs to send and a pointer to the given queue. When the turtle notifies
+the interrupt that a change has happened, the interrupt first checks if
+the change is an area which is of interest to it. If so it calls the turtle
+look function with its location and the sought object. According to the
+turtle's answer and to the data stored inside the interrupt, the interrupt
+sends the needed message, if any. Message-passing mechanisms:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032310/~elad/GALAPAGOS/prev.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032310/~elad/GALAPAGOS/prev.gif
new file mode 100644
index 0000000..3c3db6d
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032310/~elad/GALAPAGOS/prev.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032317/~elad/GALAPAGOS/next.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032317/~elad/GALAPAGOS/next.gif
new file mode 100644
index 0000000..b8f05c3
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032317/~elad/GALAPAGOS/next.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032330/~elad/GALAPAGOS/toc.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032330/~elad/GALAPAGOS/toc.gif
new file mode 100644
index 0000000..786e4c7
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032330/~elad/GALAPAGOS/toc.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032339/~elad/GALAPAGOS/back.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032339/~elad/GALAPAGOS/back.gif
new file mode 100644
index 0000000..e0394b7
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032339/~elad/GALAPAGOS/back.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032348/~elad/GALAPAGOS/Envs.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032348/~elad/GALAPAGOS/Envs.gif
new file mode 100644
index 0000000..7be131a
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032348/~elad/GALAPAGOS/Envs.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032356/~elad/GALAPAGOS/Envs2.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032356/~elad/GALAPAGOS/Envs2.gif
new file mode 100644
index 0000000..64fa2f6
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032356/~elad/GALAPAGOS/Envs2.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032406/~elad/GALAPAGOS/img00001.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032406/~elad/GALAPAGOS/img00001.gif
new file mode 100644
index 0000000..3b44881
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032406/~elad/GALAPAGOS/img00001.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032416/~elad/GALAPAGOS/img00002.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032416/~elad/GALAPAGOS/img00002.gif
new file mode 100644
index 0000000..7d06417
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032416/~elad/GALAPAGOS/img00002.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032426/~elad/GALAPAGOS/img00003.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032426/~elad/GALAPAGOS/img00003.gif
new file mode 100644
index 0000000..66c1de1
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032426/~elad/GALAPAGOS/img00003.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032438/~elad/GALAPAGOS/vision.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032438/~elad/GALAPAGOS/vision.gif
new file mode 100644
index 0000000..bf50f22
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032438/~elad/GALAPAGOS/vision.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032447/~elad/GALAPAGOS/img00010.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032447/~elad/GALAPAGOS/img00010.gif
new file mode 100644
index 0000000..af5695d
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032447/~elad/GALAPAGOS/img00010.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032457/~elad/GALAPAGOS/img00011.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032457/~elad/GALAPAGOS/img00011.gif
new file mode 100644
index 0000000..0c838b6
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032457/~elad/GALAPAGOS/img00011.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032510/~elad/GALAPAGOS/img00012.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032510/~elad/GALAPAGOS/img00012.gif
new file mode 100644
index 0000000..ff7261a
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032510/~elad/GALAPAGOS/img00012.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032521/~elad/GALAPAGOS/img00013.gif b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032521/~elad/GALAPAGOS/img00013.gif
new file mode 100644
index 0000000..aaffee2
Binary files /dev/null and b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19970812032521/~elad/GALAPAGOS/img00013.gif differ
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19981205205433/~elad/GALAPAGOS/index.html b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19981205205433/~elad/GALAPAGOS/index.html
new file mode 100644
index 0000000..56faa74
--- /dev/null
+++ b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19981205205433/~elad/GALAPAGOS/index.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+Spring 1997
+Graduation project
+Department of Math & Computer Science,
+Ben-Gurion University of the Negev
+
+Written by Elad Eyal and Miki
+Tebeka.
+
+Supervisor: Dr. Michael Elhadad
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19990128140433/~elad/GALAPAGOS/gui.html b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19990128140433/~elad/GALAPAGOS/gui.html
new file mode 100644
index 0000000..a6c0244
--- /dev/null
+++ b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19990128140433/~elad/GALAPAGOS/gui.html
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+THE INTERACTIVE GUI
+
+
+
+
+![]()
+
+
+
+
+
+
+
+
+
+IMPLEMENTATION
+
+
+
+
+
+
+
+
+FITTING SCM INTO WINDOWS
+
+
+
+
+
+
+
+
+GARBAGE COLLECTION
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+BOARDS
+
+
+
+
+
+
+TURTLES
+
+
+
+
+VISION
+
+
+
+
+INTERRUPTS
+
+
+
+
+CLASS ORGANIZATION
+
+
+
+
+
+
+
+
+
+
+
+
+
+PROGRAMMER'S MANUAL:
+
+
+NONSTANDARD PRIMITIVES
+
+
+
Welcome to Galapagos Scheme. This chapter is intended
+as a quick reference to Galapagos's extensions over traditional Scheme.
+Knowledge of Scheme is assumed. Galapagos Scheme is compliant with both
+R4RS and IEEE standard P1178. If you've read the chapter titled
+"Scheme extensions", you can and should skip the short introduction
+in each section. This complete chapter appears as on-line help in Galapagos,
+just a F1 click away.
+
An environment is a list of frames, +with the global environment in its tail. A frame is a list +of bindings, which map variables to their values. (define...) +adds a binding to the frame at the top of the current environment. +(set!...) family of commands modify +an existing binding, in the frame where it was defined. When a variable +is referenced, the current environment is searched from head to tail, and +the first binding found dictates the value of the variable.
+ +The first interpreter, which pops up as Galapagos
+is started, runs at the global environment (the way traditional Scheme
+works). Additional interpreters (threads) run at distinct environments,
+which contain a single initially empty frame, and a pointer to the global
+environment.
+
+
(clone-environment
+env [depth])
+
Clone-environment will make an exact copy of the
+environment env, by copying its frames
+one by one. If depth is specified then the new environment will be the
+collection of frames which is up to depth
+frames from the current frame. And the last frame will point to the depth
++ 1 frames from the current one in env.
+
+
This means that if we are now in environment e1 +and done (define x 7). Then if we'll +write
+ +(define e2 (clone-environment +(current-environment))),
+ +the result of
+ +(eval@ e2 x) +
+ +will return 7.
+
But if we are not in a lower frame than the one +x was defined in and write
+ +(define e2 (clone-environment +(current-environment) 1))
+ +and write the value of x is undefined.
+ +(Unless it was defined in the global environment)
+
+
Note: Only the bindings are copied. The bound values +are not. Example:
+ +(define x (cons 1 2)) +
+ +(define e (clone-environment +(current-environment)))
+ +(eval@ e (set-cdr! X 6)) +
+ +will change the 2 into 6 at both environments. +However,
+ +(set! x 7) +
+ +will only affect one copy.
+
(pop-environment
+env)
+
Returns the current environment without the first +frame. This means the first frame on the list of frames is "popped" +out.
+ +If env was +made from f3->f2->f1->Global, the result will be f2->f1->Global. +
+ +(fx means frame number x)
+ +Example:
+ +(define e2 (pop-environment
+(current-environment)))
+
(extend-environment
+env)
+
Extends env with +a new empty frame (where nothing is defined yet).
+ +This means the if env +was f2->f1->Global the result will be f3->f2->f1->Global. +
+ +(fx means frame number x)
+ +Example:
+ +(define e2 (extend-environment
+(current-environment)))
+
(current-environment)
+
+
Returns the current environment.
+
(environment?
+env)
+
A predicate that is true if env +is an environment.
+ +Example:
+ +(environment? (current-environment)) +
+ +Will return true.
+
(parent-environment)
+
+
Returns the parent environment. This is the environment +where (new-thread) was called to create +this thread. The First thread returns the global environment.
+ +Example:
+ +(eval@ (parent-environment) +y)
+ +Will return the value of y in the parent environment.
+
(base-environment)
+
+
The environment where the interpreter runs.
+
(set-base-environment
+env)
+
Sets the base environment (where the interpreter +runs) to be env
+ +Example:
+ +(set-base-environment +(parent-environment))
+ +Will make this thread run in the same environment
+as its father)
+
(eval@ env forms...)
+
+
Evaluates forms in given environment.
+ +Example:
+ +(define x 7) +
+ +(define e2 (clone-environment +(current-environment)))
+ +(eval@ e2 x)
+
The result will be 7
+
(eval@p forms...)
+
+
Evaluates forms in parent environment.
+ +Example:
+ +Say we want to make our turtle walk 30 degrees +more than the father's turtle. Then we can write:
+ +(set-heading! T (+ 30
+(eval@p (turtle-heading t))))
+
Message queues are MT-safe mechanisms used to pass
+messages, possibly between threads. Messages accepted must be cons, its
+car being the message type and the cdr is the message body. Both can be
+any kind of Scheme object.
+
+
(make-queue) +
Creates a new message queue.
+ +Example:
+ +(define q (make-queue))
+
+
(message-queue? +q)
A predicate that is true if q +is a queue.
+ +Example:
+ +(message-queue? q)
+ +Will return true for q from the previous example.
+
(peek-message
+q [type])
+
Return true if there is a message (of given type, +or of any type if unspecified) in the queue q. +
+ +Example:
+ +(peek-message q) +
+ +Will return falsif the queue q is empty. +
+ +Note: types are compared using (equals?)
+.
+
(post-message
+q typ_msg)
+
Posts the message typ_msg +to the queue q.
+ +typ_msg must +be a cons (type . message).
+ +Example:
+ +(post-message q (cons
+'type-welcome 'hello))
+
(get-message [time-out]
+q [type])
+
Get message from queue q +, if time-out is defined +waits only time-out seconds, and
+ +optionally gets only messages from type type. +
+ +Example:
+ +(define msg (get-message +7 q 'type-welcome))
+ +The result will be (if the previous posting was +done) ('type-welcome . 'hello)
+ +Note: types are compared using (equals?)
+.
+
A window is the graphical board on which the turtles
+and the user draw. It is a bitmap of size 800x600.
+
+
(new-window [name])
+
+
Makes a new window, name +is a symbol or a string which will also be the window's title. The window's +color will be white and it's size 800x600.
+ +Example:
+ +(define w (new-window +'my-window))
+ +Will create a new window with the title my-window.
+
+
(rename-window!
+win [name])
+
Renames the window win. name +is a symbol or a string which will also be the window's title.
+ +Example:
+ +(rename-window! w 'foo) +
+ +Will make the title of w to be foo.
+
(set-background-color!
+R G B)
+
Set the background color of the window. All the +turtles in the window are notified on the new color (used in pen-erase) +
+ +The colors are defined in terms of Red +Green Blue +(where 0,0,0 is black and 255,255,255 is white).
+ +Example:
+ +(set-background-color! +w 255 255 0)
+ +Will turn the background color of w
+to yellow
+
(clear-window
+w)
+
Clears the screen from all the previous drawings, +leaving only the turtles images on it.
+ +Example:
+ +(clear-window w)
+
(load-bitmap w
+"filename" [x y])
+
Loads the bitmap "filename" +and makes it the background of w. x y are +the coordinates of the upper left corner of the picture. If x +y are not given then the picture is centered.
+ +Example:
+ +(load-bitmap w "c:\\windows\\forest.bmp")
+
+
This operation can also be done using the Board
+menu.
+
+
(save-bitmap w
+"filename")
+
Saves the window into a bitmap file called "filename". +
+ +Example:
+ +(save-bitmap w "my_draw.bmp")
+
+
This operation can also be done using the Board
+menu.
+
(window-alive?
+win)
+
True if win
+is alive, meaning it can get commands.
+
(window-name w) +
Returns the name of w. +
+ +Example:
+ +(window-name w) +
+ +Will return "foo" on our window.
+
A turtle is an object which is connected to a certain
+window. It has inner state variables:
+
- width: the width +of the pen.
+ +- heading: the direction +the turtle will go on command forward!. +The heading is in degrees where 0 is upwards and adding to the heading +means clock wise rotation.
+ +- visibility: if the +body of the turtle is visible on the board or not.
+ +- solid: if the turtle +is a "solid" turtle (its interior is also drawn) or "hollow" +one (only its circumference is drawn).
+ +- position: the location +of the turtle on the board, where 0,0 is the upper left corner. +
+ +- color: the color +of the turtle and it's pen, given in RGB format.
+ +- pen condition: the +turtle's pen can be in three states:
+ +- pen width: the width
+of the pen, the bigger the width the thicker the pen will be.
+
Turtles can also "see" the board or other
+turtles (only from the same board) and can handle user interrupts. A turtle
+is always connected to a certain view, which is the view it is drawing
+on. Turtles can move between views.
+
+
(make-turtle win
+[name])
+
Creates and return a new turtle, in window win, +optional name (where name can be anything). +
+ +The inner state of the new turtle will be: +
+ +Example:
+ +(define t (make-turtle
+'turty))
+
(turtle-alive?
+t)
+
A predicate that is true if t +is alive, meaning t can get commands. +
+ +Example:
+ +(turtle-alive? t)
+ +Will return true on our t.
+
(clone-turtle
+t [name])
+
Creates an identical turtle to t +(same inner state).
+ +Example:
+ +(define t2 (clone-turtle
+t))
+
(rename-turtle
+t [name])
+
Renames the turtle, name is a string or a symbol +
+ +Example:
+ +(rename-turtle t 'pongy)
+
+
(turtle-name t)
+
+
Returns the name of t. +
+ +Example:
+ +(turtle-name t) +
+ +Will return "pongy" on our t.
+
(forward! t d)
+
Makes t go +forward (in the heading of t) +d steps. +t will draw while going according to +the state of it's pen.
+ +Example:
+ +(forward! t 100) +
+ +Will cause t
+to go forward 100 steps. (In our case since t's
+heading hasn't changed it will go upwards)
+
(turtle-width! +t n)
Set the width of t's
+pen to be n. The bigger n
+is the wider the pen will be.
+
(backwards! t
+d)
+
Same as forward, just in the opposite direction. +
+ +Example:
+ +(backwards! t 100) +
+ +is the same as
+ +(forward! t -100)
+
(right! t d)
+
Will set a new heading to t. +The new heading is the old heading plus d, meaning +t will rotate clock-wise.
+ +Example:
+ +(right! t 90) +
+ +Will make t
+turn 90 degrees to the
+
(left! t d) +
Same as right, other direction
+
(set-heading!
+t val)
+
Sets the heading of t +to be val. 0 is upwards and 90 is to +the right.
+ +Example:
+ +(set-heading t 180) +
+ +Will cause t
+to point to the bottom of the screen.
+
(move-to! t x
+y)
+
Makes t move +to point x,y without painting. 0,0 +is the top-left corner of the window.
+ +Example:
+ +(move-to! T 100 100) +
+ +Will cause t
+to move to point 100,100.
+
(draw-to! t x
+y)
+
Moves t to +x,y possibly drawing or erasing according +to the state of t's pen.
+ +Example:
+ +(draw-to! t 0 0)
+
(move-turtle-to-window +t win)
Move t to the +window win
+ +Example:
+ +(move-turtle-to-window
+t w)
+
(pen-up! t)
+
The pen of t +is up, so he won't paint when moving.
+ +Example:
+ +(pen-up! t)
+
(pen-down! t)
+
Causes t's
+pen to be down, meaning he will draw as he is moving.
+
(pen-erase! t)
+
Causes t's
+pen to be in the same color as the background color of the window it is
+attached to.
+
(show-turtle!
+t)
+
Makes t visible. +Meaning he will be seen on the board.
+ +Example:
+ +(show-turtle! t)
+
(hide-turtle!
+t)
+
Makes t invisible. +Meaning he will not be seen on the board. (but all the drawing he does +will be seen)
+ +Example:
+ +(hide-turtle! t)
+
(make-turtle-solid!
+t)
+
Makes t a solid
+turtle.
+
(make-turtle-hollow!
+t)
+
Make t a "hollow"
+turtle.
+
(kill-turtle!
+t)
+
Kills t. Meaning +it will be erased from the board and will not accept further commands. +
+ +Note: This is the only way to get rid of a turtle. +
+ +Example:
+ +(kill-turtle! t) +
+ +Will cause when writing t +in the command line to the response
+ +#<dead turtle>
+
(set-color! t
+R G B) or (set-color! t (list R G B)
+
Sets t's color +(and it's pen), in RGB format.
+ +Example:
+ +(set-color! t 255 0 255) +
+ +Will cause t +to be pinkish.
+ +Same as:
+ +(define pinkish '(255 +0 255))
+ +(set-color! t pinkish)
+
(turtle-inner-state
+t)
+
Returns a list of 6 parameters: color, heading, +hidden-flag, pen width, solid flag, location (cons x y))
+ +Example:
+ +(define new-t (make-turtle +w))
+ +(turtle-inner-state new-t) +
+ +Will return the list
+ +((0 0 0) 0.0 #f 2 #t (400.0
+. 300.0))
+
Below are functions that returns only one of the
+parameters returned by turtle-inner-state:
+
+
(turtle-color t) +
+ +(turtle-heading t) +
+ +(turtle-visible t) +
+ +(turtle-width t) +
+ +(turtle-solid? t) +
+ +(turtle-position t)
+
A turtle can interact with the board. It can "see"
+colors or other turtles.
+
+
(look t distance
+angle '(R G B))
+
Will return true if there is a point in color (R +G B) in distance distance from +t and in the area bordered by the angle +2*angle.
+ +Example:
+ +(look t 50 20 '(0 0 0)) +
+ +Will cause t
+to search for the color black (RGB 0,0,0) in the area shown here in blue:
+
![]()
+
(look t distance
+angle [t1])
+
Same as if looking for color, just this time it +will be true is t1 is in the visible area.
+ +If no target turtle is defined then the function +will return true if any turtle from this window is in the visible area. +
+ +Example:
+ +(define new-t (clone-turtle +t))
+ +(forward! new-t 30) +
+ +(look t 50 20 new-t) +
+ +And
+ +(look t 50 20) +
+ +Will both return true.
+
+
A turtle can hold a list of interrupts (or notifications).
+When an interrupt is invoked it send a given message to the thread that
+sent the command. Every interrupt is defined by a "look" arguments.
+An interruptcan be of three kinds:
+
A "yes" interrupt - The interrupt will +happen (message sent) on every "first" time the look returns +yes.
+ +Meaning if a turtle is told to invoke an interrupt
+every time it sees blue on a certain region. Then the first time it sees
+blue it will invoke the interrupt. From now on if the blue is in view it
+will not invoke the interrupt. Then if it loses sight of the blue object,
+the next time it sees blue again it will invoke the interrupt, and so on.
+
A "no" interrupt - Same as the "yes"
+interrupt, just this time the interrupt is invoked when the sought object
+is not seen.
+
A "both" interrupt - First time the sought +object is viewed the "yes" message is sent, then the first time +the turtle loses sight of the object the "no" message is sent +and so on.
+ +A message can be any SCHEME object.
+
When the interpreter is installing interrupt to +a turtle it need to install a handler, which is a function that +takes only one argument and this argument is the messages that comes from +the interrupt.
+ +If no handler is installed, the messages will be +sent but will have no affect on the thread of execution.
+ +There can be only one handler per thread and a
+handler can not be a primitive procedure.
+
(turtle-notify +t msg1 msg2 distance angle TARGET)
Instructs a turtle to send msg1 and msg2 upon seeing +and not seeing, respectively, the target. The messages can be any Scheme +objects, which are sent to the thread as if by (tell-thread). The other +parameters - see (look)
+ +Example:
+ +(turtle-notify t 'yes +'no 50 10 new-t)
+ +This is a "both" kind interrupt.
+
(turtle-no-notify
+t distance angle TARGET)
+
Tells the turtle to stop notifying in the given
+case. Very like deleting the interrupt from the turtle.
+
(notify-when[-not]
+t1 msg dist ang TARGET)
+
Instructs a turtle to send msg upon [stopping] +seeing the target. This is a "yes" or "no" interrupt. +
+ +Example:
+ +(notify-when t 'gotcha +50 10 new-t)
+ +Will cause t
+to send the message "gotcha" every "first" time it
+sees new-t.
+
(stop-notifying
+t)
+
t will temporarily
+stop notifying on interrupts. Like "clear interrupts".
+
(continue-notifying
+t)
+
t will resume
+notifying on interrupts.
+
(no-notifications +t)
Deletes all t's
+interrupts.
+
(notify-on-click
+turtle msg)
+
Instructs turtle to send msg when right-clicked +with the mouse (distance of 5 pixels from the turtle location). There can +be only one interrupt of this kind per turtle.
+ +Example:
+ +(notify-on-click t 'ouch) +
+ +Will case t
+to send the message "ouch" when the user right-clicks next to
+it.
+
(notify-on-click
+window msg)
+
Instructs window to
+send msg when right-clicked with the
+mouse not close to any turtle.
+
(clear-notify-click
+t)
+
Clears the user right click interrupt
+
(install-handler
+func)
+
Installs a message handler. When a message arrives, +func is called with it as a sole argument. +
+ +There can be only one handler per thread. func +can not be a primitive procedure.
+ +Example:
+ +(define (print x) (write +x))
+ +(notify-on-click t 'click-on-t) +
+ +(install-handler print) +
+ +Will cause that the message "click-on-t"
+will be printed each time the user right clicked on t.
+
+
Galapagos supports multiple threads. Every thread
+is a complete Scheme interpreter, with its own base environment. Every
+thread has a Thread Object, which uniquely identifies it.
+
A console is a text window where the user
+can type commands (when the interpreter is idle) and see output. A thread
+may or may not be bound to a console. Information printed by a non-bound
+thread is lost; a non-bound thread waiting for input is stuck (unless provisions
+were made to allow a new console to be created by means of inter-thread
+communications.) If a non-bound thread has nothing to do, instead of waiting
+for input like a bound thread, it will terminate.
+
(this-thread)
+
Returns the thread-object of the current thread. +
+ +Example:
+ +(this-thread) +
+ +Will return something like
+ +#<thread 0x6d1e2c>
+
+
(is-first-thread?)
+
+
True if the current thread is the first SCM thread.
+
(thread? t) +
True if t is a thread
+ +Example:
+ +(thread? (this-thread)) +
+ +Will return true
+
(active-threads)
+
+
Returns the number of active threads
+
(new-thread form+) +
Creates a new thread that will calculate the form[s] +
+ +Example:
+ +(new-thread (define t +(make-turtle w)) (forward! t 200))
+ +Will make a new thread that will create a new turtle +and will move it forward 200 steps and then terminates.
+ +(new-thread (bind-to-console)) +
+ +Will make a new thread that's ready to accept commands
+form a newly-created window. The same can be achieved by selecting "Fork"
+from "Scheme" menu.
+
+
+
(break& form+)
+
+
Causes the current thread to stop and calculate
+the form[s]. The current computation is lost.
+
(bind-to-console)
+
+
The thread will get its commands from a console. +
+ +Example:
+ +(new-thread (bind-to-console)) +
+ +Will create a new thread that gets it.
+
(unbind-console) +
Close bound console.
+
(rename-console +name)
New name for the current console
+
(install-handler
+func)
+
Installs a message handler. When a message arrives, +func is called with it as a sole argument. +
+ +There can be only one handler per thread. func +can not be a primitive procedure.
+ +Example:
+ +(define (print x) (write +x))
+ +(notify-on-click t 'click-on-t) +
+ +(install-handler print) +
+ +Will cause that the message "click-on-t" +will be printed each time the user right clicked on t. +
+ +Note: (new -thread (install-handler
+f)) is a bad idea, because the fresh thread will terminate immediately.
+
+
(tell-thread th
+x)
+
Sends message X +to thread th. Returns true on success. +
+ +If th has no
+handler installed it will cause nothing.
+
(quit-thread)
+
Kills the current thread, does not work on the
+main thread.
+
(quit-program)
+
Quits the program.
+
+
+
These are primitives taken from SCM, which were +modifies to be multithread-safe: + +
+ + ++An arbiter +is a data object the canbe used as a +guard for critical sections. It can be either "locked" or "unlocked". It +is ideal when a busy/wait mechanism is required, since it is MT-safe. +
+ + +(sleep n) +
Causes the current thread to block for (approximately)
+n seconds. (sleep 0) is a way to instruct
+a thread to give up its remaining processor time.
+
(make-arbiter
+name)
+
Makes an arbiter called name. +
+ +Example:
+ +(define x-arb (make-arbiter
+'x-guard))
+
+
(try-arbiter arb)
+
+
Checks if the arbiter arb +is up. If the arbiter is up returns false, otherwise it sets +the arbiter to be "up" and returns true.
+ +Example:
+ +(try-arbiter x-arb) +
+ +Will return true and set x-arb
+to be "up". But trying it for the second time return false since
+x-arb is "up".
+
(release-arbiter
+arb)
+
Set the arb +to be "down". If the arbiter was "up" returns true +otherwise returns false.
+ +Example:
+ +(release-arbiter x-arb) +
+ +Will return true , but using this function again +will return false since x-arb is already +down.
+ + ++
+
+
+
+Welcome to
+
+
+

+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB)
+
+
+ We have extended Scheme in two main
+directions: Turtle graphics and multithreading: The turtle object lives on a board on which it can move and draw.
+A turtle can also communicate with the board and "see" colors
+or other turtles. Galapagos Scheme provides a set of primitives to create
+and manage such turtles and the boards they live on. A set of additional primitives enable the programmer to create multiple
+interpreters that run concurrently. The environment model was extended
+to support shared or thread-specific environments, and primitives to handle
+multiple environments were also added. A frame is a table which maps (or binds) names to values. An
+environment is a chained list of frames in which the interpreter works.
+ For example the command: (define x 7) creates a binding between x and the value 7. A typical environment looks like this:
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19990424140956/~elad/GALAPAGOS/extensions.html b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19990424140956/~elad/GALAPAGOS/extensions.html
new file mode 100644
index 0000000..67d97f1
--- /dev/null
+++ b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/19990424140956/~elad/GALAPAGOS/extensions.html
@@ -0,0 +1,493 @@
+
+
+
+
+
+
+SCHEME EXTENSIONS
+
+
+
+
+
+
+
+
+
+THE NEW ENVIRONMENT MODEL
+
+
+
+
When a variable is evaluated, the interpreter first tries to find it
+in the current frame. If a suitable binding can't be found, the interpreter
+moves to the next frame in the environment and searched for a binding there.
+
In our example if we write x in the command line we'll get 12
+as the answer because all such computations take place at the global environment.
+
+
A function application is always evaluated with respect to the environment +the in which it was defined. (A function "holds" its environment, +hence the name "closure") This means that if we write
+ +(define (f) x)
+ +and then
+ +(f)
+ +the result will be
+ +12.
+
+
+
+
+

Under Galapagos's environment model, every interpreter works on its
+branch of an "environments tree", but can also evaluate an expression
+in any other environment in the tree. If two interpreters have a shared
+node on the tree, then from that point up (towards the global environment)
+all the bindings are the same for the two interpreters. The global environment
+is shared by all interpreters. If an interpreter changes the value of some
+variable, the binding is changed in all other interpreters that have access
+to the frame where the variable was declared. Obviously, caution should
+be taken when writing to a shared variable.
+
As an example, if a user created two new threads, called A and B, and +then evaluated:
+ +First thread> (define +x 7)
+ +(define (f) ...)
+ +Thread A> (define (g) +x)
+ +Thread B> (define x 4) +
+ +this is how the environment model would look like:
+

+
Now consider what happens when the user evaluates this:
+ +Thread A> (set! f g) +
+ +
+
+
Now, evaluating (f) in thread B will call the function defined
+in thread A. It will return 12 which is the value of x in f's environment.
+If thread A defines a new x (using define), it will affect the result
+of subsequent calls to f.
+
Sharing environments and frames are Galapagos's way of allowing shared
+data. By default, however, most calculations are done at thread-specific
+frames. (More on this subject in the next section). Primitives are supplied
+to explicitly reference and manage environments: clone-environment
+can create a copy of an environment (so changing a binding in one copy
+does not alter the other); extend-environment and pop-environment
+can add and remove frames to and from environments. More environment functions
+are found in the next section of this document.
+
A thread is a SCHEME interpreter. The base environment of a thread
+is the thread's topmost environment. All forms entered at the thread's
+console or as arguments to new-thread are evaluated in the base
+environment. In traditional SCHEME there is only one thread of execution.
+It is a single thread and its base environment is the global environment.
+In Galapagos many interpreters can run concurrently, and each have its
+own environment (changing dynamically as computation progresses) and a
+base environment (which can be explicitly changed).
+
One thread is created by Galapagos upon startup. It is called the main
+thread, and it lasts for the whole Galapagos session. Its base environment
+is the global one - much like a traditional Scheme interpreter. Additional
+threads can be created using new-thread. These have their base environment
+set to a new environment, containing a single fresh frame pointing to the
+global environment. Any calculation done at the new thread's console takes
+place in this thread-local environment. However, if closure functions are
+used, then their evaluation may take place at the global environment or
+at some other thread's space, depending on where that function was defined.
+
+
When a thread finishes the execution of its commands it terminates. +There are two exceptions to this rule:
+ +Threads can communicate using the predicate tell-thread or by
+using the asynchronous message-queues system described later. In addition,
+SCM's arbiters were improved to be multithread safe. An arbiter
+object can serve as a guard on a critical section (where only one thread
+can work at a given time) of the program. The relevant primitves are make-arbiter,
+try-arbiter, and release-arbiter.
+
Note: Galapagos supports Scheme's notation of continuations. +However, two restrictions apply:
+ +A console is a text window where the user can type commands (when
+the interpreter is idle) and see output. A console has a name which can
+be changed dynamically, which appears on its title bar. A thread may or
+may not be bound to a console. Information printed by a non-bound thread
+is lost; a non-bound thread waiting for input is stuck (unless provisions
+were made to allow a new console to be created by means of inter-thread
+communications.) If a non-bound thread has nothing to do, instead of waiting
+for input like a bound thread, it will terminate.
+
The main thread is always bound to a console. To bind a thread to a
+console use the command bind-to-console from within the thread.
+
A board (window) is the graphical board on which the turtles and the
+user draw. It is a bitmap on which the user can draw interactively, by
+using the supplied GUI, or by creating turtles and instructing them to
+do the drawings.
+
The controls of the graphical user interface are located on the toolbar.
+The "shapes" of drawing are either a rectangle, a line or free
+hand drawing. The user pen can have three widths which are found under
+the User Pen menu. The numbers next to the sizes are the widths
+in pixels.
+
The colors of the user pen can be changes either from the User Pen
+menu or from the toolbar's color buttons. When choosing from a toolbar
+button, the user can know exactly what color (in RGB format) is used.
+
Each window has a name which is written on its title bar which can be
+changed using the rename-window! command. The board can be cleaned
+from all drawings using the clear-window command.
+
Since the board is a bitmap it can be saved to a BMP file using the
+save-bitmap command. A new background from a bitmap file can be
+loaded using the load-bitmap command.
+
A turtle is an object which is connected to a certain board. Each turtle
+has a pen with which it can draw on that board. The user can change the
+state of the turtle's pen including giving it the color of the board's
+background color (using the pen-erase! command). The pen will draw
+when it is "down" and will not draw when it is "up".
+Turtles can move between boards using the move-turtle-to-window
+command.
+
Each turtle holds its location as the a pair of coordinates where 0,0
+is the upper left corner of the board and 800,600 is the bottom-right corner
+of the board. The turtle's location can be changed by giving the turtle
+commands such as forward!, backwards!, move-to! or by using the
+move button from the toolbar.
+
A turtle also has a heading which is the direction it will move on the
+forward! command. The heading is in degrees, 0 meaning upwards and
+increasing clockwise, thus 90 means rightwards and so on. A turtle's heading
+can be changed by commands such as right!, left!, and set-heading!
+or interactively, by using the move button on the toolbar and pressing
+the control key.
+
A turtle can be visible on the board or be hidden. When it is visible
+the user can decide if it wants a "solid" or "hollow"
+turtle using the make-hollow! and make-solid! commands.
+
A turtle is always connected to a certain board, which is the board
+it is drawing on. To create a new turtle on a board use the make-turtle
+or the clone-turtle commands. A new turtle (created with the make-turtle
+command) will be black, solid, heading north and with it's pen down, in
+the center of the board. A cloned turtle will have exactly the same inner
+state as its parent.
+
A turtle can also look at the board and see other turtles or colors. +By using the command look the user can tell the turtle the area +in which to look and what to look in this area.
+ +Example:
+ +The command
+ +(look t 50 20 '(0 0 0))
+ +will cause the turtle t to look for black pixels in the area +in radius 50 from the turtle and 20 degrees to each side of the heading +line, shown here in blue:
+ +![]()
+
A turtle can have interrupts. Each interrupt is defined in terms of
+turtle's vision. Whenever a turtle starts or stops seeing a given target,
+a predefined message is sent to the thread which asked the interrupt. The
+user can determine if the interrupt will notify on every change (like a
+"can see"- "can't see" toggle) or only when one change
+happens (only "can see" or "can't see" toggle). A message
+can be any valid SCHEME object.
+
Example:
+ +The command
+ +(turtle-notify t "I-see" "I-don't-see" 50 20 +color-black)
+ +tells the turtle t that every time it sees the color black it +should send the message "I-see" and when it doesn't see +the color black any more it should send the message "I-don't-see". +
+ +Below is an example of what messages (or no message) t will send
+while it is moving forward, encountering two black lines on its way:
+
+
+
+
+If the interrupt was of kind "can see" (notify-when command)
+only the "I-see" messages were sent, and if it was a the
+"can't see" interrupt (notify-when-not command) only the
+"I-can't-see" style messages were sent.
+
A special "user interrupt" is invoked when the user right-clicks
+the turtle or a window. The notify-on-click command is used to enable
+this.
+
A thread can tell the turtle to delete a certain interrupt using the
+turtle-no-notify command. It can also tell the turtle to disable
+all interrupts using the stop-notifying command.
+
In order to process the messages sent from a turtle's interrupt (or
+from another thread, as presented later) the thread must install a message
+handler which is a one argument function. If no handler is installed
+the turtle's messages are lost. There can be only one handler per thread.
+If the handler is installed then every time an interrupt is invoked, the
+handler function in called with the message sent by the interrupt as its
+argument.
+
+
Example:
+ +We declare the function:
+ +(define (my-print x) (write x) (newline))
+ +and then install my-print as the current handler with:
+ +(install-handler my-print)
+ +from now on every message a turtle's interrupt sends will be printed
+on screen. If my-print was installed in the previous example then
+we would have seen:
+
"I-see"
+ +"I-don't-see"
+ +"I-see"
+
on the screen.
+
A good example to view the interrupts in action is to make a turtle
+turn each time it sees a color and then let it wander aimlessly. Then use
+the user pen to draw lines the turtle's way and watch it change direction.
+See the PINGPONG.SCM file for a demo program.
+
The message-handler concept can be used as a mean of synchronous inter-thread
+communications. The tell-thread functions sends a message to a thread,
+which will be treated as an interrupt-generated message: It will cause
+the thread's message handler function to be called with tell-thread's argument
+as its own. This allows one thread to initiate a computation in a different
+thread's environment and CPU space synchronously and without sharing environments.
+
+
In order to let threads communicate between themselves asynchronously
+a system of message queues was developed. A queue is an object which stores
+and relieves messages, stored in FIFO (First In First Out) style, meaning
+messages are read in the order of arrival to the queue. Supported messages
+are pairs of type and body, both of which can be any valid SCHEME object.
+Looking for messages of a certain type is also supported, allowing implementation
+of more flexible communication schemes than plain FIFO.
+
A thread can check if there are any messages in a given queue, if it
+does get-message without checking first if there are messages in
+the queue it will wait a given time-out or forever if no time-out is given.
+If by the end of the time-out no message were in the queue the result will
+be false.
+
Example:
+ +In this example a queue q is created then a message is posted
+into the queue and read from it.
+
(define q (make-queue))
+ +(post-message q (cons 'type-circus 'bozo-the-clown))
+ +(define msg (get-message q))
+
now the command
+ +(car msg)
+ +will give
+ +type-circus
+ +and the command
+ +(cdr msg)
+ +will yield
+ +bozo-the-clown.
+ + ++
+
+
+
++
+
+
++
Scheme is a dialect of Lisp that stresses conceptual elegance and simplicity.
+It is specified in R4RS and IEEE standard P1178. Scheme is much smaller
+than Common Lisp; the specification is about 50 pages, compared to Common
+Lisp's 1300 page draft standard. (See the Lisp FAQ for details on standards
+for Common Lisp.) Advocates of Scheme often find it amusing that the entire
+Scheme standard is shorter than the index to Guy Steele's "Common
+Lisp: the Language, 2nd Edition".
+
Scheme is often used in computer science curricula and programming language
+research, due to its ability to represent many programming abstractions
+with its simple primitives.
+
There are a lot of traditional SCHEME interpreter available such as
+Chez, ELK 2.1, GAMBIT, MITScheme, scheme->C, Scheme48, T3.1, VSCM and
+Scm4e. Many free Scheme implementations (as well as SCM) are available
+from swiss-ftp.ai.mit.edu [18.43.0.246].
+
Galapagos is built over the SCM interpreter version 4e4 written by Aubrey
+Jaffer <jaffer@ai.mit.edu>.
+
+
+
LOGO is a programming language designed for use by learners, including
+children. It is a dialect of LISP which has a more natural syntax, using
+infix arithmetics and (almost) no parentheses. LOGO features a "turtle"
+which can be instructed to move across the screen and draw shapes. This
+became known as "Turtle Graphics" or "Turtle Geometry"
+- a geometry that describes paths "from within" rather than "from
+outside" or "from above." For example, "turn right"
+means turn right relative to whatever direction you were heading before;
+by contrast, "turn east" specifies an apparently absolute direction.
+A Logo user or program manipulates the graphical turtle by telling it to
+move forward or back some number of steps, or by telling it to turn left
+or right some number of degrees.
+
Turtle geometry has two major advantages. One is that many paths are
+more simply described in relative than in absolute terms. For example,
+it's easy to indicate the absolute coordinates of the corners of a square
+with vertical and horizontal sides, but it's not so easy to find the corners
+of an inclined square. In turtle geometry the same commands (go forward,
+turn right 90 degrees, etc.) work for squares with any orientation.
+The second advantage is pedagogic rather than computational: turtle geometry
+is compatible with a learner's own experience of moving in the world -
+it's "body syntonic."
+
The two major goals behind Galapagos were:
+
First, we wanted to create an environment suitable for teaching programming,
+patterned after Logo's environment and its easy-to-understand, easy-to-use
+turtle geometry. We chose Scheme as the programming language because of
+its educational value, as noted before. We added Turtle Graphics because
+of its ability to visualize computations, and thus help understanding them
+better.
+
Second, we wanted to add parallel programming. The importance of multiprocessor
+machines and of multithreading is becoming more apparent every day, and
+so is the need for tools to help understanding parallel programming paradigms.
+By extending Scheme to be multithreaded, we wanted to create such a tool.
+
Galapagos was developed to run under Windows 95, and should work under
+Window NT as well. (It uses 32-bit specific code so Win32s is not enough
+to run Galapagos). Both binary and source are available at the
+homepage:
+
+
+
+
+
+
++ +
+ +
+ +
+ +
+ +
+
+
+
+
+
+
+ ++
+ ++
+Welcome to
+
+
+

+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB)
+
+ Scheme is a dialect of Lisp that stresses conceptual elegance and simplicity.
+It is specified in R4RS and IEEE standard P1178. Scheme is much smaller
+than Common Lisp; the specification is about 50 pages, compared to Common
+Lisp's 1300 page draft standard. (See the Lisp FAQ for details on standards
+for Common Lisp.) Advocates of Scheme often find it amusing that the entire
+Scheme standard is shorter than the index to Guy Steele's "Common
+Lisp: the Language, 2nd Edition". Scheme is often used in computer science curricula and programming language
+research, due to its ability to represent many programming abstractions
+with its simple primitives. There are a lot of traditional SCHEME interpreter available such as
+Chez, ELK 2.1, GAMBIT, MITScheme, scheme->C, Scheme48, T3.1, VSCM and
+Scm4e. Many free Scheme implementations (as well as SCM) are available
+from swiss-ftp.ai.mit.edu [18.43.0.246]. Galapagos is built over the SCM interpreter version 4e4 written by Aubrey
+Jaffer <jaffer@ai.mit.edu>. LOGO is a programming language designed for use by learners, including
+children. It is a dialect of LISP which has a more natural syntax, using
+infix arithmetics and (almost) no parentheses. LOGO features a "turtle"
+which can be instructed to move across the screen and draw shapes. This
+became known as "Turtle Graphics" or "Turtle Geometry"
+- a geometry that describes paths "from within" rather than "from
+outside" or "from above." For example, "turn right"
+means turn right relative to whatever direction you were heading before;
+by contrast, "turn east" specifies an apparently absolute direction.
+A Logo user or program manipulates the graphical turtle by telling it to
+move forward or back some number of steps, or by telling it to turn left
+or right some number of degrees. Turtle geometry has two major advantages. One is that many paths are
+more simply described in relative than in absolute terms. For example,
+it's easy to indicate the absolute coordinates of the corners of a square
+with vertical and horizontal sides, but it's not so easy to find the corners
+of an inclined square. In turtle geometry the same commands (go forward,
+turn right 90 degrees, etc.) work for squares with any orientation.
+The second advantage is pedagogic rather than computational: turtle geometry
+is compatible with a learner's own experience of moving in the world -
+it's "body syntonic." The two major goals behind Galapagos were: First, we wanted to create an environment suitable for teaching programming,
+patterned after Logo's environment and its easy-to-understand, easy-to-use
+turtle geometry. We chose Scheme as the programming language because of
+its educational value, as noted before. We added Turtle Graphics because
+of its ability to visualize computations, and thus help understanding them
+better. Second, we wanted to add parallel programming. The importance of multiprocessor
+machines and of multithreading is becoming more apparent every day, and
+so is the need for tools to help understanding parallel programming paradigms.
+By extending Scheme to be multithreaded, we wanted to create such a tool. Galapagos was developed to run under Windows 95, and should work under
+Window NT as well. (It uses 32-bit specific code so Win32s is not enough
+to run Galapagos). Both binary and source are available at the
+homepage:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ We have extended Scheme in two main
+directions: Turtle graphics and multithreading: The turtle object lives on a board on which it can move and draw.
+A turtle can also communicate with the board and "see" colors
+or other turtles. Galapagos Scheme provides a set of primitives to create
+and manage such turtles and the boards they live on. A set of additional primitives enable the programmer to create multiple
+interpreters that run concurrently. The environment model was extended
+to support shared or thread-specific environments, and primitives to handle
+multiple environments were also added. A frame is a table which maps (or binds) names to values. An
+environment is a chained list of frames in which the interpreter works.
+ For example the command: (define x 7) creates a binding between x and the value 7. A typical environment looks like this:
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20010608213604/~elad/GALAPAGOS/background.html b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20010608213604/~elad/GALAPAGOS/background.html
new file mode 100644
index 0000000..f606cb2
--- /dev/null
+++ b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20010608213604/~elad/GALAPAGOS/background.html
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+Background
+
+
+
+
+
+
+
+SCHEME
+
+
+
+
+
+
+
+LOGO AND TURTLE GEOMETRY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+BIBLIOGRAPHY
+
+
+
+
+
+
+http://www.cs.cmu.edu:8001/Web/Groups/AI/html/faqs/lang/scheme/top.html
+
+ftp://cher.media.mit.edu/pub/logo/FAQ
+
+ftp://ftp-swiss.ai.mit.edu/pub/scm/scm4e4.tar.gz
+
+
+
+
+
+
+
+
+
+
+
+
+SCHEME EXTENSIONS
+
+
+
+
+
+
+
+
+
+THE NEW ENVIRONMENT MODEL
+
+
+
+
When a variable is evaluated, the interpreter first tries to find it
+in the current frame. If a suitable binding can't be found, the interpreter
+moves to the next frame in the environment and searched for a binding there.
+
In our example if we write x in the command line we'll get 12
+as the answer because all such computations take place at the global environment.
+
+
A function application is always evaluated with respect to the environment +the in which it was defined. (A function "holds" its environment, +hence the name "closure") This means that if we write
+ +(define (f) x)
+ +and then
+ +(f)
+ +the result will be
+ +12.
+
+
+
+
+

Under Galapagos's environment model, every interpreter works on its
+branch of an "environments tree", but can also evaluate an expression
+in any other environment in the tree. If two interpreters have a shared
+node on the tree, then from that point up (towards the global environment)
+all the bindings are the same for the two interpreters. The global environment
+is shared by all interpreters. If an interpreter changes the value of some
+variable, the binding is changed in all other interpreters that have access
+to the frame where the variable was declared. Obviously, caution should
+be taken when writing to a shared variable.
+
As an example, if a user created two new threads, called A and B, and +then evaluated:
+ +First thread> (define +x 7)
+ +(define (f) ...)
+ +Thread A> (define (g) +x)
+ +Thread B> (define x 4) +
+ +this is how the environment model would look like:
+

+
Now consider what happens when the user evaluates this:
+ +Thread A> (set! f g) +
+ +
+
+
Now, evaluating (f) in thread B will call the function defined
+in thread A. It will return 12 which is the value of x in f's environment.
+If thread A defines a new x (using define), it will affect the result
+of subsequent calls to f.
+
Sharing environments and frames are Galapagos's way of allowing shared
+data. By default, however, most calculations are done at thread-specific
+frames. (More on this subject in the next section). Primitives are supplied
+to explicitly reference and manage environments: clone-environment
+can create a copy of an environment (so changing a binding in one copy
+does not alter the other); extend-environment and pop-environment
+can add and remove frames to and from environments. More environment functions
+are found in the next section of this document.
+
A thread is a SCHEME interpreter. The base environment of a thread
+is the thread's topmost environment. All forms entered at the thread's
+console or as arguments to new-thread are evaluated in the base
+environment. In traditional SCHEME there is only one thread of execution.
+It is a single thread and its base environment is the global environment.
+In Galapagos many interpreters can run concurrently, and each have its
+own environment (changing dynamically as computation progresses) and a
+base environment (which can be explicitly changed).
+
One thread is created by Galapagos upon startup. It is called the main
+thread, and it lasts for the whole Galapagos session. Its base environment
+is the global one - much like a traditional Scheme interpreter. Additional
+threads can be created using new-thread. These have their base environment
+set to a new environment, containing a single fresh frame pointing to the
+global environment. Any calculation done at the new thread's console takes
+place in this thread-local environment. However, if closure functions are
+used, then their evaluation may take place at the global environment or
+at some other thread's space, depending on where that function was defined.
+
+
When a thread finishes the execution of its commands it terminates. +There are two exceptions to this rule:
+ +Threads can communicate using the predicate tell-thread or by
+using the asynchronous message-queues system described later. In addition,
+SCM's arbiters were improved to be multithread safe. An arbiter
+object can serve as a guard on a critical section (where only one thread
+can work at a given time) of the program. The relevant primitves are make-arbiter,
+try-arbiter, and release-arbiter.
+
Note: Galapagos supports Scheme's notation of continuations. +However, two restrictions apply:
+ +A console is a text window where the user can type commands (when
+the interpreter is idle) and see output. A console has a name which can
+be changed dynamically, which appears on its title bar. A thread may or
+may not be bound to a console. Information printed by a non-bound thread
+is lost; a non-bound thread waiting for input is stuck (unless provisions
+were made to allow a new console to be created by means of inter-thread
+communications.) If a non-bound thread has nothing to do, instead of waiting
+for input like a bound thread, it will terminate.
+
The main thread is always bound to a console. To bind a thread to a
+console use the command bind-to-console from within the thread.
+
A board (window) is the graphical board on which the turtles and the
+user draw. It is a bitmap on which the user can draw interactively, by
+using the supplied GUI, or by creating turtles and instructing them to
+do the drawings.
+
The controls of the graphical user interface are located on the toolbar.
+The "shapes" of drawing are either a rectangle, a line or free
+hand drawing. The user pen can have three widths which are found under
+the User Pen menu. The numbers next to the sizes are the widths
+in pixels.
+
The colors of the user pen can be changes either from the User Pen
+menu or from the toolbar's color buttons. When choosing from a toolbar
+button, the user can know exactly what color (in RGB format) is used.
+
Each window has a name which is written on its title bar which can be
+changed using the rename-window! command. The board can be cleaned
+from all drawings using the clear-window command.
+
Since the board is a bitmap it can be saved to a BMP file using the
+save-bitmap command. A new background from a bitmap file can be
+loaded using the load-bitmap command.
+
A turtle is an object which is connected to a certain board. Each turtle
+has a pen with which it can draw on that board. The user can change the
+state of the turtle's pen including giving it the color of the board's
+background color (using the pen-erase! command). The pen will draw
+when it is "down" and will not draw when it is "up".
+Turtles can move between boards using the move-turtle-to-window
+command.
+
Each turtle holds its location as the a pair of coordinates where 0,0
+is the upper left corner of the board and 800,600 is the bottom-right corner
+of the board. The turtle's location can be changed by giving the turtle
+commands such as forward!, backwards!, move-to! or by using the
+move button from the toolbar.
+
A turtle also has a heading which is the direction it will move on the
+forward! command. The heading is in degrees, 0 meaning upwards and
+increasing clockwise, thus 90 means rightwards and so on. A turtle's heading
+can be changed by commands such as right!, left!, and set-heading!
+or interactively, by using the move button on the toolbar and pressing
+the control key.
+
A turtle can be visible on the board or be hidden. When it is visible
+the user can decide if it wants a "solid" or "hollow"
+turtle using the make-hollow! and make-solid! commands.
+
A turtle is always connected to a certain board, which is the board
+it is drawing on. To create a new turtle on a board use the make-turtle
+or the clone-turtle commands. A new turtle (created with the make-turtle
+command) will be black, solid, heading north and with it's pen down, in
+the center of the board. A cloned turtle will have exactly the same inner
+state as its parent.
+
A turtle can also look at the board and see other turtles or colors. +By using the command look the user can tell the turtle the area +in which to look and what to look in this area.
+ +Example:
+ +The command
+ +(look t 50 20 '(0 0 0))
+ +will cause the turtle t to look for black pixels in the area +in radius 50 from the turtle and 20 degrees to each side of the heading +line, shown here in blue:
+ +![]()
+
A turtle can have interrupts. Each interrupt is defined in terms of
+turtle's vision. Whenever a turtle starts or stops seeing a given target,
+a predefined message is sent to the thread which asked the interrupt. The
+user can determine if the interrupt will notify on every change (like a
+"can see"- "can't see" toggle) or only when one change
+happens (only "can see" or "can't see" toggle). A message
+can be any valid SCHEME object.
+
Example:
+ +The command
+ +(turtle-notify t "I-see" "I-don't-see" 50 20 +color-black)
+ +tells the turtle t that every time it sees the color black it +should send the message "I-see" and when it doesn't see +the color black any more it should send the message "I-don't-see". +
+ +Below is an example of what messages (or no message) t will send
+while it is moving forward, encountering two black lines on its way:
+
+
+
+
+If the interrupt was of kind "can see" (notify-when command)
+only the "I-see" messages were sent, and if it was a the
+"can't see" interrupt (notify-when-not command) only the
+"I-can't-see" style messages were sent.
+
A special "user interrupt" is invoked when the user right-clicks
+the turtle or a window. The notify-on-click command is used to enable
+this.
+
A thread can tell the turtle to delete a certain interrupt using the
+turtle-no-notify command. It can also tell the turtle to disable
+all interrupts using the stop-notifying command.
+
In order to process the messages sent from a turtle's interrupt (or
+from another thread, as presented later) the thread must install a message
+handler which is a one argument function. If no handler is installed
+the turtle's messages are lost. There can be only one handler per thread.
+If the handler is installed then every time an interrupt is invoked, the
+handler function in called with the message sent by the interrupt as its
+argument.
+
+
Example:
+ +We declare the function:
+ +(define (my-print x) (write x) (newline))
+ +and then install my-print as the current handler with:
+ +(install-handler my-print)
+ +from now on every message a turtle's interrupt sends will be printed
+on screen. If my-print was installed in the previous example then
+we would have seen:
+
"I-see"
+ +"I-don't-see"
+ +"I-see"
+
on the screen.
+
A good example to view the interrupts in action is to make a turtle
+turn each time it sees a color and then let it wander aimlessly. Then use
+the user pen to draw lines the turtle's way and watch it change direction.
+See the PINGPONG.SCM file for a demo program.
+
The message-handler concept can be used as a mean of synchronous inter-thread
+communications. The tell-thread functions sends a message to a thread,
+which will be treated as an interrupt-generated message: It will cause
+the thread's message handler function to be called with tell-thread's argument
+as its own. This allows one thread to initiate a computation in a different
+thread's environment and CPU space synchronously and without sharing environments.
+
+
In order to let threads communicate between themselves asynchronously
+a system of message queues was developed. A queue is an object which stores
+and relieves messages, stored in FIFO (First In First Out) style, meaning
+messages are read in the order of arrival to the queue. Supported messages
+are pairs of type and body, both of which can be any valid SCHEME object.
+Looking for messages of a certain type is also supported, allowing implementation
+of more flexible communication schemes than plain FIFO.
+
A thread can check if there are any messages in a given queue, if it
+does get-message without checking first if there are messages in
+the queue it will wait a given time-out or forever if no time-out is given.
+If by the end of the time-out no message were in the queue the result will
+be false.
+
Example:
+ +In this example a queue q is created then a message is posted
+into the queue and read from it.
+
(define q (make-queue))
+ +(post-message q (cons 'type-circus 'bozo-the-clown))
+ +(define msg (get-message q))
+
now the command
+ +(car msg)
+ +will give
+ +type-circus
+ +and the command
+ +(cdr msg)
+ +will yield
+ +bozo-the-clown.
+ + ++
+
+
+
+
+
+
++ +
In order to make Galapagos more fun to learn with, an interactive GUI
+(Graphical User Interface) is provided. Users can make changes on the board
+while a computation is in progress and effect its execution. Drawing tools
+enable the user to draw on the board while a program is being executed.
+If a line is drawn in front of a turtle which has a relevant interrupt,
+the interrupt will be invoked if needed.
+
The user has a special user pen that can draw line, rectangles
+or free hand. These modes are available from the toolbar. The User's pen
+width and color can be modified using the User Pen menu or the toolbar.
+
Color buttons are provided on the toolbar to give a known RGB color +to the user pen. It is useful when the user draw an object on the board +and wants a turtle to see this object. The colors are:
+ +White - (255 255 255)
+ +Black - (0 0 0)
+ +Blue - (0 0 255)
+ +Red - (255 0 0)
+ +Green - (0 255 0)
+ +Yellow - (255 255 0)
+
Another option available is changing a turtle's heading and position, +using the Move Turtle button:
+ +![]()
+
If this button is pressed then a turtle can be dragged to a new location +simply by dragging it with the mouse. In order to change the turtle's heading, +hold down a control key and move the move towards the desired location, +the turtle will follow the movement of the mouse.
+ ++
+
+
+
+
+
+
++ +
Galapagos was written using Microsoft Visual C++, and is designed to
+run under Windows 95. We chose Windows 95 because it seems to have the
+largest potential Galapagos users base. The following sections describe
+some implementation details of Galapagos.
+
The SCM interpreter we used as a base is written in C. Most of the original
+code we added was written in C++. The parts we used from SCM are almost
+identical to the original. In fact, by changing the scmconfig.h file (which
+contain machine-specific configuration) and #defining THREAD to be null,
+the C files should become equivalent to the sources we used.
+
We have implemented two MT-safe FIFO message queue classes. Both will
+block when trying to read from an empty queue. CMsgQx, the extended
+message queue, supports the same interface as the one provided in Scheme,
+plus an additional support for "Urgent Messages". These take
+precedence over all other messages. CMessageQueue is message queue
+with exactly the same interface as the Scheme level message queues, but
+which contain internal logic to handle "Urgent" messages used
+to deal with cases where synchronous respond is needed, such as I/O, Garbage
+collection, and Scheme-level inter-thread communications.
+
Galapagos is based on SCM, which is a single-thread, read-evaluate-print-loop
+(repl) based Scheme interpreter. The most important issue in migrating
+SCM was how to maintain the interpreter's natural repl-based approach,
+yet allow for multiple threads to interact, and for Windows messages to
+be processed quickly.
+
We used WIN32's multithreading capabilities to solve these problems.
+A single thread handles all aspects of the GUI - in a sense, "all
+that is Windows": graphic boards, turtles, consoles, menus and so
+on. Each interpreter runs in a thread of its own, interacting with the
+GUI using a message queue similar to the one provided at the Scheme level.
+

+
The GUI thread manages both commands received from the OS and from the
+different interpreters running on their own threads. To ensure as fast
+responses as possible, priorities are used: OS messages (such as windows
+updates and input devices) gets highest priority; Console (text messages)
+come second, and graphics messages are last. This allows the interpreters
+to run interactively in a satisfactory manner.
+
SCM interpreter threads each run in the old-fashion repl mode. When
+a computation is over, the interpreter blocks until new input comes from
+the GUI thread. All blocking functions were modified to allow synchronous
+messages (such as the one generated by tell-thread) to work. In
+addition, SCM's "poll routine" is used to force checking for
+such messages even during computations.
+
An additional thread is used for Garbage Collection. It is described
+in detail in the section dealing with garbage collection.
+
In this section we will briefly describe SCM's garbage collector, and
+then discuss the modifications done to adapt it to Galapagos's multithreading
+computations. It should be noted that the garbage collector used is a portable
+garbage collector taken from "SCHEME IN ONE DEFUN, BUT IN C THIS TIME",
+by George J Carrette <gjc@world.std.com>.
+
SCM uses a conservative Mark & Sweep garbage collector (GC). All
+Scheme data objects share some common configuration (called "cells"):
+They are 8-byte aligned; they reside is specially-allocated memory segments
+(called hplims); they are the size of two pointers (so a scheme cons is
+exactly a cell); and they contain a special GC bit used by the garbage
+collector. This bit is 0 during actual computations. When a new cell is
+needed and all the hplims are used, garbage collection is initiated. If
+it does not free enough space to pass a certain threshold, a new hplim
+is allocated.
+
The first stage in garbage collection is marking all cells which are
+not to be deleted. Some terminology might be helpful here:
+
Obviously, all unreachable data is dead. Conservative garbage collectors
+treat all reachable data as alive.
+
The Mark stage of the garbage collector scans the sys_protects[]
+array and the machine's stack and registers for anything that looks like
+a valid cell. All cell pointer have their 3 least significant bits zero,
+and are in one of few known ranges (the hplims). The garbage collector
+searches for anything matching a cell's bit pattern, and treats it as an
+immediately reachable cell pointer. In some cases, this may mean an integer,
+for example, happens to match the binary pattern and thus be interpreted
+as a cell pointer. However, this will only mean some cell or cells are
+marked as reachable though they are not such. Because of the uniform structure
+of the cell and its limited range of possible locations, such an accident
+is guarantied not to corrupt memory. Furthermore, if we accept the assumption
+that integers are usually relatively small, and memory addresses are relatively
+big, we conclude that such accidents are not very likely to happen often
+anyway.
+
During mark stage, the garbage collector recursively finds (a superset
+of) all live cells, and marks them by setting their special GC bit to 1.
+The second stage is the Sweep stage, in which all the hplims are scanned
+linearly, and every cell which is not marked is recognized as dead, and
+as such is reclaimed as free. Marked cells get unmarked so they are ready
+for the next garbage collection.
+
Mark & Sweep garbage collection has two main disadvantages: One,
+that it requires all computation to stop while garbage collection is in
+progress. In Galapagos, since all threads use a shared memory heap, it
+means all threads must synchronize and halt while garbage is collected.
+Second, Mark & Sweep is very likely to cause memory fragmentation.
+However, since cells are equally sized, fragmentation is only rarely a
+problem.
+
We chose to stick with Mark & Sweep in Galapagos because of its
+two major advantages: Simplicity and efficiency. Mark & Sweep GC does
+not affect computation speed, because direct pointers are used. Most concurrent
+garbage collectors work by making all pointers indirect, which may slow
+computations down considerably. The need to halt all threads for GC is
+accepted. Since memory is shared, it would only be fair to stop all threads
+when GC is needed: Threads will probably halt anyway since cells are allocated
+continuously during computations.
+
Two major issues are introduced when trying to multithread the garbage
+collector. One is the synchronization of the different threads, which run
+almost completely unaware one of the other; the second is the need to mark
+data from every thread's specific stack, registers, and sys_protects[].
+We solved these two issues by combining them to one.
+
The intuitive approach might be to let each thread mark its own information,
+and then sweep centrally. However, since synchronization of threads is
+mandatory, letting every thread mark its own data will lead only to redundant
+marking and to excessive context switches, since each threads has to become
+active. Therefore we created the "Garbage Collection daemon"
+(GCd), which runs in a distinct thread and lasts for the whole Galapagos
+session. The GCd is not an interpreter, but a mechanism which keeps track
+of live threads and their need of GC. The GCd thread is always blocked,
+except when a thread notifies it on its birth or death, or when a thread
+indicates the need for garbage collection. Since the GC daemon is blocked
+whenever it is not needed, and then becomes the exclusive running thread
+during actual GC (with the exception of the GUI thread), its existence
+does not hurt performance.
+
To explain how the GCd synchronizes all threads, let us examine the
+three-way protocol involved. freelist
+is a global pointer which holds a linked list of free cells - it can be
+either a cell pointer, a value indicating "busy" (thus implementing
+busy/wait protection over it) or "end of memory" which is found
+at the end of the linked list. MIB stands for Memory Information
+Block, which is a block of memory containing all of a thread's
+immediately reachable data.
+
GCd scenario: GCd is blocked until a threads sends a GC +request.
+ +Scenario 1: A thread needs to allocate a cell but can't. +
+ +Scenario 2: A thread receives a MIB request. This +may happen within a computation or when considered otherwise blocked - +waiting for input, for example.
+ +The important thing to note about this protocol is its indifference
+to the GC "initiator". Several threads can "initiate"
+GC, and each request is "satisfied", although of course only
+one GC takes place. The GCd itself is unaware of the initiating thread
+identity, and completely ignores any further GC requests. It treats all
+threads identically. This is important because it allows each thread meeting
+a low memory condition to initiate GC immediately. This is in fact the
+mechanism which saves us from explicitly checking for a third-party GC
+request during computation: If a thread runs out of memory, the freelist
+variable is kept at "out of memory" state, causing any other
+thread trying to allocate memory to initiate GC as well. This simplifies
+the GC protocol (technically, if not conceptually), and does it with almost
+no affect on computation speed.
+
A board or a view as it called in MFC is the environment where a turtle
+moves and interact with. It hold two main data structures. The first is
+the bitmap of the drawing. It is a 800X600 bitmap. Every time a turtle
+draws on the board it makes its pen the active pen on the board and draws
+on it. Every time the picture needs refreshing (as signaled by the operating
+system) it is the board's duty to copy the relevant section from the bitmap
+to the screen. The second data object is the turtles list, an expandable
+array of turtles which holds pointers to all turtles on the specific board.
+
The most important part in the board's work is to notify the turtles
+on any event that happened on the board such as drawing, changing background
+or moving of a turtle. If for example a user draws a line on the board,
+the board (after drawing the line) goes through the turtles list and tell
+each one that some event happened at a rectangle that contains the line.
+Each turtle will decide if this has any importance to it or not.
+
Apart from that, the board handles all the user interface from the menus
+and the toolbar. The most obvious example is the move turtle button, which,
+when pressed, causes the board to find a turtle close enough to the click's
+location. Then, on every movement of the mouse it gives the turtle a command
+to move to this point.
+
In order to support scrolling of the picture, we derived the CBoardView
+class from CScrollView. The interface with the interpreter threads
+is done via a message queue. The main function is ReadAndEval,
+which gets a message and then interprets its and act upon the result.
+
In addition to a pointer to its current board, and to inner-state variable
+which affects its graphical aspects, every turtle holds an expandable array
+of interrupts. When a turtle gets from the window that a message signifying
+that some change has happened, it sends this change to each of its interrupts
+(only if the interrupt flag is on) and the interrupt is responsible to
+send an appropriate message if necessary. The turtle's location are stored
+as floating points on x,y axes, to allow for accuracy on the turtle's location
+and heading.
+
The turtles interacts with the interpreter thread using a message queue.
+As with the board, the main function here is the ReadAndEval,
+which translates these messages to valid function calls.
+
Every turtle holds a pointer to the bitmap it is drawing on. When it
+is "looking" for a color it calculates the minimal rectangle
+that holds the desired area. Then it iterates on all the pixels in this
+rectangle. First it checks if the pixel is in the vision area using the
+sign rule to determine if a point is clockwise or anti clockwise from a
+line, and then check for distance. If the point is in the relevant area
+the turtle gets its color from the bitmap and compares it with the sought
+color.
+
When looking for a specific turtle, the turtle gets this turtle's position
+and calculates if this location is in the relevant area using the same
+algorithm. When looking for any turtle, the turtle passes the relevant
+arguments to the view, which then uses the same algorithm for each turtle
+on its turtles array.
+
Each turtle holds an expandable array of interrupts. Each interrupts
+is an object that is much like a turtle vision. The interrupts has the
+view area argument and what it is looking for. It also has the message
+it needs to send and a pointer to the given queue. When the turtle notifies
+the interrupt that a change has happened, the interrupt first checks if
+the change is an area which is of interest to it. If so it calls the turtle
+look function with its location and the sought object. According to the
+turtle's answer and to the data stored inside the interrupt, the interrupt
+sends the needed message, if any.
+
+

Message-passing mechanisms:
+
+
+
+
+
+
+
+
+
++ +
+
Welcome to Galapagos Scheme. This chapter is intended
+as a quick reference to Galapagos's extensions over traditional Scheme.
+Knowledge of Scheme is assumed. Galapagos Scheme is compliant with both
+R4RS and IEEE standard P1178. If you've read the chapter titled
+"Scheme extensions", you can and should skip the short introduction
+in each section. This complete chapter appears as on-line help in Galapagos,
+just a F1 click away.
+
An environment is a list of frames, +with the global environment in its tail. A frame is a list +of bindings, which map variables to their values. (define...) +adds a binding to the frame at the top of the current environment. +(set!...) family of commands modify +an existing binding, in the frame where it was defined. When a variable +is referenced, the current environment is searched from head to tail, and +the first binding found dictates the value of the variable.
+ +The first interpreter, which pops up as Galapagos
+is started, runs at the global environment (the way traditional Scheme
+works). Additional interpreters (threads) run at distinct environments,
+which contain a single initially empty frame, and a pointer to the global
+environment.
+
+
(clone-environment
+env [depth])
+
Clone-environment will make an exact copy of the
+environment env, by copying its frames
+one by one. If depth is specified then the new environment will be the
+collection of frames which is up to depth
+frames from the current frame. And the last frame will point to the depth
++ 1 frames from the current one in env.
+
+
This means that if we are now in environment e1 +and done (define x 7). Then if we'll +write
+ +(define e2 (clone-environment +(current-environment))),
+ +the result of
+ +(eval@ e2 x) +
+ +will return 7.
+
But if we are not in a lower frame than the one +x was defined in and write
+ +(define e2 (clone-environment +(current-environment) 1))
+ +and write the value of x is undefined.
+ +(Unless it was defined in the global environment)
+
+
Note: Only the bindings are copied. The bound values +are not. Example:
+ +(define x (cons 1 2)) +
+ +(define e (clone-environment +(current-environment)))
+ +(eval@ e (set-cdr! X 6)) +
+ +will change the 2 into 6 at both environments. +However,
+ +(set! x 7) +
+ +will only affect one copy.
+
(pop-environment
+env)
+
Returns the current environment without the first +frame. This means the first frame on the list of frames is "popped" +out.
+ +If env was +made from f3->f2->f1->Global, the result will be f2->f1->Global. +
+ +(fx means frame number x)
+ +Example:
+ +(define e2 (pop-environment
+(current-environment)))
+
(extend-environment
+env)
+
Extends env with +a new empty frame (where nothing is defined yet).
+ +This means the if env +was f2->f1->Global the result will be f3->f2->f1->Global. +
+ +(fx means frame number x)
+ +Example:
+ +(define e2 (extend-environment
+(current-environment)))
+
(current-environment)
+
+
Returns the current environment.
+
(environment?
+env)
+
A predicate that is true if env +is an environment.
+ +Example:
+ +(environment? (current-environment)) +
+ +Will return true.
+
(parent-environment)
+
+
Returns the parent environment. This is the environment +where (new-thread) was called to create +this thread. The First thread returns the global environment.
+ +Example:
+ +(eval@ (parent-environment) +y)
+ +Will return the value of y in the parent environment.
+
(base-environment)
+
+
The environment where the interpreter runs.
+
(set-base-environment
+env)
+
Sets the base environment (where the interpreter +runs) to be env
+ +Example:
+ +(set-base-environment +(parent-environment))
+ +Will make this thread run in the same environment
+as its father)
+
(eval@ env forms...)
+
+
Evaluates forms in given environment.
+ +Example:
+ +(define x 7) +
+ +(define e2 (clone-environment +(current-environment)))
+ +(eval@ e2 x)
+
The result will be 7
+
(eval@p forms...)
+
+
Evaluates forms in parent environment.
+ +Example:
+ +Say we want to make our turtle walk 30 degrees +more than the father's turtle. Then we can write:
+ +(set-heading! T (+ 30
+(eval@p (turtle-heading t))))
+
Message queues are MT-safe mechanisms used to pass
+messages, possibly between threads. Messages accepted must be cons, its
+car being the message type and the cdr is the message body. Both can be
+any kind of Scheme object.
+
+
(make-queue) +
Creates a new message queue.
+ +Example:
+ +(define q (make-queue))
+
+
(message-queue? +q)
A predicate that is true if q +is a queue.
+ +Example:
+ +(message-queue? q)
+ +Will return true for q from the previous example.
+
(peek-message
+q [type])
+
Return true if there is a message (of given type, +or of any type if unspecified) in the queue q. +
+ +Example:
+ +(peek-message q) +
+ +Will return falsif the queue q is empty. +
+ +Note: types are compared using (equals?)
+.
+
(post-message
+q typ_msg)
+
Posts the message typ_msg +to the queue q.
+ +typ_msg must +be a cons (type . message).
+ +Example:
+ +(post-message q (cons
+'type-welcome 'hello))
+
(get-message [time-out]
+q [type])
+
Get message from queue q +, if time-out is defined +waits only time-out seconds, and
+ +optionally gets only messages from type type. +
+ +Example:
+ +(define msg (get-message +7 q 'type-welcome))
+ +The result will be (if the previous posting was +done) ('type-welcome . 'hello)
+ +Note: types are compared using (equals?)
+.
+
A window is the graphical board on which the turtles
+and the user draw. It is a bitmap of size 800x600.
+
+
(new-window [name])
+
+
Makes a new window, name +is a symbol or a string which will also be the window's title. The window's +color will be white and it's size 800x600.
+ +Example:
+ +(define w (new-window +'my-window))
+ +Will create a new window with the title my-window.
+
+
(rename-window!
+win [name])
+
Renames the window win. name +is a symbol or a string which will also be the window's title.
+ +Example:
+ +(rename-window! w 'foo) +
+ +Will make the title of w to be foo.
+
(set-background-color!
+R G B)
+
Set the background color of the window. All the +turtles in the window are notified on the new color (used in pen-erase) +
+ +The colors are defined in terms of Red +Green Blue +(where 0,0,0 is black and 255,255,255 is white).
+ +Example:
+ +(set-background-color! +w 255 255 0)
+ +Will turn the background color of w
+to yellow
+
(clear-window
+w)
+
Clears the screen from all the previous drawings, +leaving only the turtles images on it.
+ +Example:
+ +(clear-window w)
+
(load-bitmap w
+"filename" [x y])
+
Loads the bitmap "filename" +and makes it the background of w. x y are +the coordinates of the upper left corner of the picture. If x +y are not given then the picture is centered.
+ +Example:
+ +(load-bitmap w "c:\\windows\\forest.bmp")
+
+
This operation can also be done using the Board
+menu.
+
+
(save-bitmap w
+"filename")
+
Saves the window into a bitmap file called "filename". +
+ +Example:
+ +(save-bitmap w "my_draw.bmp")
+
+
This operation can also be done using the Board
+menu.
+
(window-alive?
+win)
+
True if win
+is alive, meaning it can get commands.
+
(window-name w) +
Returns the name of w. +
+ +Example:
+ +(window-name w) +
+ +Will return "foo" on our window.
+
A turtle is an object which is connected to a certain
+window. It has inner state variables:
+
- width: the width +of the pen.
+ +- heading: the direction +the turtle will go on command forward!. +The heading is in degrees where 0 is upwards and adding to the heading +means clock wise rotation.
+ +- visibility: if the +body of the turtle is visible on the board or not.
+ +- solid: if the turtle +is a "solid" turtle (its interior is also drawn) or "hollow" +one (only its circumference is drawn).
+ +- position: the location +of the turtle on the board, where 0,0 is the upper left corner. +
+ +- color: the color +of the turtle and it's pen, given in RGB format.
+ +- pen condition: the +turtle's pen can be in three states:
+ +- pen width: the width
+of the pen, the bigger the width the thicker the pen will be.
+
Turtles can also "see" the board or other
+turtles (only from the same board) and can handle user interrupts. A turtle
+is always connected to a certain view, which is the view it is drawing
+on. Turtles can move between views.
+
+
(make-turtle win
+[name])
+
Creates and return a new turtle, in window win, +optional name (where name can be anything). +
+ +The inner state of the new turtle will be: +
+ +Example:
+ +(define t (make-turtle
+'turty))
+
(turtle-alive?
+t)
+
A predicate that is true if t +is alive, meaning t can get commands. +
+ +Example:
+ +(turtle-alive? t)
+ +Will return true on our t.
+
(clone-turtle
+t [name])
+
Creates an identical turtle to t +(same inner state).
+ +Example:
+ +(define t2 (clone-turtle
+t))
+
(rename-turtle
+t [name])
+
Renames the turtle, name is a string or a symbol +
+ +Example:
+ +(rename-turtle t 'pongy)
+
+
(turtle-name t)
+
+
Returns the name of t. +
+ +Example:
+ +(turtle-name t) +
+ +Will return "pongy" on our t.
+
(forward! t d)
+
Makes t go +forward (in the heading of t) +d steps. +t will draw while going according to +the state of it's pen.
+ +Example:
+ +(forward! t 100) +
+ +Will cause t
+to go forward 100 steps. (In our case since t's
+heading hasn't changed it will go upwards)
+
(turtle-width! +t n)
Set the width of t's
+pen to be n. The bigger n
+is the wider the pen will be.
+
(backwards! t
+d)
+
Same as forward, just in the opposite direction. +
+ +Example:
+ +(backwards! t 100) +
+ +is the same as
+ +(forward! t -100)
+
(right! t d)
+
Will set a new heading to t. +The new heading is the old heading plus d, meaning +t will rotate clock-wise.
+ +Example:
+ +(right! t 90) +
+ +Will make t
+turn 90 degrees to the
+
(left! t d) +
Same as right, other direction
+
(set-heading!
+t val)
+
Sets the heading of t +to be val. 0 is upwards and 90 is to +the right.
+ +Example:
+ +(set-heading t 180) +
+ +Will cause t
+to point to the bottom of the screen.
+
(move-to! t x
+y)
+
Makes t move +to point x,y without painting. 0,0 +is the top-left corner of the window.
+ +Example:
+ +(move-to! T 100 100) +
+ +Will cause t
+to move to point 100,100.
+
(draw-to! t x
+y)
+
Moves t to +x,y possibly drawing or erasing according +to the state of t's pen.
+ +Example:
+ +(draw-to! t 0 0)
+
(move-turtle-to-window +t win)
Move t to the +window win
+ +Example:
+ +(move-turtle-to-window
+t w)
+
(pen-up! t)
+
The pen of t +is up, so he won't paint when moving.
+ +Example:
+ +(pen-up! t)
+
(pen-down! t)
+
Causes t's
+pen to be down, meaning he will draw as he is moving.
+
(pen-erase! t)
+
Causes t's
+pen to be in the same color as the background color of the window it is
+attached to.
+
(show-turtle!
+t)
+
Makes t visible. +Meaning he will be seen on the board.
+ +Example:
+ +(show-turtle! t)
+
(hide-turtle!
+t)
+
Makes t invisible. +Meaning he will not be seen on the board. (but all the drawing he does +will be seen)
+ +Example:
+ +(hide-turtle! t)
+
(make-turtle-solid!
+t)
+
Makes t a solid
+turtle.
+
(make-turtle-hollow!
+t)
+
Make t a "hollow"
+turtle.
+
(kill-turtle!
+t)
+
Kills t. Meaning +it will be erased from the board and will not accept further commands. +
+ +Note: This is the only way to get rid of a turtle. +
+ +Example:
+ +(kill-turtle! t) +
+ +Will cause when writing t +in the command line to the response
+ +#<dead turtle>
+
(set-color! t
+R G B) or (set-color! t (list R G B)
+
Sets t's color +(and it's pen), in RGB format.
+ +Example:
+ +(set-color! t 255 0 255) +
+ +Will cause t +to be pinkish.
+ +Same as:
+ +(define pinkish '(255 +0 255))
+ +(set-color! t pinkish)
+
(turtle-inner-state
+t)
+
Returns a list of 6 parameters: color, heading, +hidden-flag, pen width, solid flag, location (cons x y))
+ +Example:
+ +(define new-t (make-turtle +w))
+ +(turtle-inner-state new-t) +
+ +Will return the list
+ +((0 0 0) 0.0 #f 2 #t (400.0
+. 300.0))
+
Below are functions that returns only one of the
+parameters returned by turtle-inner-state:
+
+
(turtle-color t) +
+ +(turtle-heading t) +
+ +(turtle-visible t) +
+ +(turtle-width t) +
+ +(turtle-solid? t) +
+ +(turtle-position t)
+
A turtle can interact with the board. It can "see"
+colors or other turtles.
+
+
(look t distance
+angle '(R G B))
+
Will return true if there is a point in color (R +G B) in distance distance from +t and in the area bordered by the angle +2*angle.
+ +Example:
+ +(look t 50 20 '(0 0 0)) +
+ +Will cause t
+to search for the color black (RGB 0,0,0) in the area shown here in blue:
+
![]()
+
(look t distance
+angle [t1])
+
Same as if looking for color, just this time it +will be true is t1 is in the visible area.
+ +If no target turtle is defined then the function +will return true if any turtle from this window is in the visible area. +
+ +Example:
+ +(define new-t (clone-turtle +t))
+ +(forward! new-t 30) +
+ +(look t 50 20 new-t) +
+ +And
+ +(look t 50 20) +
+ +Will both return true.
+
+
A turtle can hold a list of interrupts (or notifications).
+When an interrupt is invoked it send a given message to the thread that
+sent the command. Every interrupt is defined by a "look" arguments.
+An interruptcan be of three kinds:
+
A "yes" interrupt - The interrupt will +happen (message sent) on every "first" time the look returns +yes.
+ +Meaning if a turtle is told to invoke an interrupt
+every time it sees blue on a certain region. Then the first time it sees
+blue it will invoke the interrupt. From now on if the blue is in view it
+will not invoke the interrupt. Then if it loses sight of the blue object,
+the next time it sees blue again it will invoke the interrupt, and so on.
+
A "no" interrupt - Same as the "yes"
+interrupt, just this time the interrupt is invoked when the sought object
+is not seen.
+
A "both" interrupt - First time the sought +object is viewed the "yes" message is sent, then the first time +the turtle loses sight of the object the "no" message is sent +and so on.
+ +A message can be any SCHEME object.
+
When the interpreter is installing interrupt to +a turtle it need to install a handler, which is a function that +takes only one argument and this argument is the messages that comes from +the interrupt.
+ +If no handler is installed, the messages will be +sent but will have no affect on the thread of execution.
+ +There can be only one handler per thread and a
+handler can not be a primitive procedure.
+
(turtle-notify +t msg1 msg2 distance angle TARGET)
Instructs a turtle to send msg1 and msg2 upon seeing +and not seeing, respectively, the target. The messages can be any Scheme +objects, which are sent to the thread as if by (tell-thread). The other +parameters - see (look)
+ +Example:
+ +(turtle-notify t 'yes +'no 50 10 new-t)
+ +This is a "both" kind interrupt.
+
(turtle-no-notify
+t distance angle TARGET)
+
Tells the turtle to stop notifying in the given
+case. Very like deleting the interrupt from the turtle.
+
(notify-when[-not]
+t1 msg dist ang TARGET)
+
Instructs a turtle to send msg upon [stopping] +seeing the target. This is a "yes" or "no" interrupt. +
+ +Example:
+ +(notify-when t 'gotcha +50 10 new-t)
+ +Will cause t
+to send the message "gotcha" every "first" time it
+sees new-t.
+
(stop-notifying
+t)
+
t will temporarily
+stop notifying on interrupts. Like "clear interrupts".
+
(continue-notifying
+t)
+
t will resume
+notifying on interrupts.
+
(no-notifications +t)
Deletes all t's
+interrupts.
+
(notify-on-click
+turtle msg)
+
Instructs turtle to send msg when right-clicked +with the mouse (distance of 5 pixels from the turtle location). There can +be only one interrupt of this kind per turtle.
+ +Example:
+ +(notify-on-click t 'ouch) +
+ +Will case t
+to send the message "ouch" when the user right-clicks next to
+it.
+
(notify-on-click
+window msg)
+
Instructs window to
+send msg when right-clicked with the
+mouse not close to any turtle.
+
(clear-notify-click
+t)
+
Clears the user right click interrupt
+
(install-handler
+func)
+
Installs a message handler. When a message arrives, +func is called with it as a sole argument. +
+ +There can be only one handler per thread. func +can not be a primitive procedure.
+ +Example:
+ +(define (print x) (write +x))
+ +(notify-on-click t 'click-on-t) +
+ +(install-handler print) +
+ +Will cause that the message "click-on-t"
+will be printed each time the user right clicked on t.
+
+
Galapagos supports multiple threads. Every thread
+is a complete Scheme interpreter, with its own base environment. Every
+thread has a Thread Object, which uniquely identifies it.
+
A console is a text window where the user
+can type commands (when the interpreter is idle) and see output. A thread
+may or may not be bound to a console. Information printed by a non-bound
+thread is lost; a non-bound thread waiting for input is stuck (unless provisions
+were made to allow a new console to be created by means of inter-thread
+communications.) If a non-bound thread has nothing to do, instead of waiting
+for input like a bound thread, it will terminate.
+
(this-thread)
+
Returns the thread-object of the current thread. +
+ +Example:
+ +(this-thread) +
+ +Will return something like
+ +#<thread 0x6d1e2c>
+
+
(is-first-thread?)
+
+
True if the current thread is the first SCM thread.
+
(thread? t) +
True if t is a thread
+ +Example:
+ +(thread? (this-thread)) +
+ +Will return true
+
(active-threads)
+
+
Returns the number of active threads
+
(new-thread form+) +
Creates a new thread that will calculate the form[s] +
+ +Example:
+ +(new-thread (define t +(make-turtle w)) (forward! t 200))
+ +Will make a new thread that will create a new turtle +and will move it forward 200 steps and then terminates.
+ +(new-thread (bind-to-console)) +
+ +Will make a new thread that's ready to accept commands
+form a newly-created window. The same can be achieved by selecting "Fork"
+from "Scheme" menu.
+
+
+
(break& form+)
+
+
Causes the current thread to stop and calculate
+the form[s]. The current computation is lost.
+
(bind-to-console)
+
+
The thread will get its commands from a console. +
+ +Example:
+ +(new-thread (bind-to-console)) +
+ +Will create a new thread that gets it.
+
(unbind-console) +
Close bound console.
+
(rename-console +name)
New name for the current console
+
(install-handler
+func)
+
Installs a message handler. When a message arrives, +func is called with it as a sole argument. +
+ +There can be only one handler per thread. func +can not be a primitive procedure.
+ +Example:
+ +(define (print x) (write +x))
+ +(notify-on-click t 'click-on-t) +
+ +(install-handler print) +
+ +Will cause that the message "click-on-t" +will be printed each time the user right clicked on t. +
+ +Note: (new -thread (install-handler
+f)) is a bad idea, because the fresh thread will terminate immediately.
+
+
(tell-thread th
+x)
+
Sends message X +to thread th. Returns true on success. +
+ +If th has no
+handler installed it will cause nothing.
+
(quit-thread)
+
Kills the current thread, does not work on the
+main thread.
+
(quit-program)
+
Quits the program.
+
+
+
These are primitives taken from SCM, which were +modifies to be multithread-safe: + +
+ + ++An arbiter +is a data object the canbe used as a +guard for critical sections. It can be either "locked" or "unlocked". It +is ideal when a busy/wait mechanism is required, since it is MT-safe. +
+ + +(sleep n) +
Causes the current thread to block for (approximately)
+n seconds. (sleep 0) is a way to instruct
+a thread to give up its remaining processor time.
+
(make-arbiter
+name)
+
Makes an arbiter called name. +
+ +Example:
+ +(define x-arb (make-arbiter
+'x-guard))
+
+
(try-arbiter arb)
+
+
Checks if the arbiter arb +is up. If the arbiter is up returns false, otherwise it sets +the arbiter to be "up" and returns true.
+ +Example:
+ +(try-arbiter x-arb) +
+ +Will return true and set x-arb
+to be "up". But trying it for the second time return false since
+x-arb is "up".
+
(release-arbiter
+arb)
+
Set the arb +to be "down". If the arbiter was "up" returns true +otherwise returns false.
+ +Example:
+ +(release-arbiter x-arb) +
+ +Will return true , but using this function again +will return false since x-arb is already +down.
+ + ++
+
+
+
+Welcome to
+
+
+

+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB) Welcome to
+
+
+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB) Welcome to
+
+
+
+
+
+ TABLE OF CONTENTS
+
+ DOWNLOAD CENTER
+
+
+500K gps10bin.zip - Executable and required Scheme libraries (SLIB)
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20220312053305/~elad/GALAPAGOS/index.html b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20220312053305/~elad/GALAPAGOS/index.html
new file mode 100644
index 0000000..56faa74
--- /dev/null
+++ b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20220312053305/~elad/GALAPAGOS/index.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+Spring 1997
+Graduation project
+Department of Math & Computer Science,
+Ben-Gurion University of the Negev
+
+Written by Elad Eyal and Miki
+Tebeka.
+
+Supervisor: Dr. Michael Elhadad
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+
diff --git a/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20220312053307/~elad/GALAPAGOS/index.html b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20220312053307/~elad/GALAPAGOS/index.html
new file mode 100644
index 0000000..56faa74
--- /dev/null
+++ b/websites/www.cs.bgu.ac.il/~elad/GALAPAGOS/20220312053307/~elad/GALAPAGOS/index.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+Spring 1997
+Graduation project
+Department of Math & Computer Science,
+Ben-Gurion University of the Negev
+
+Written by Elad Eyal and Miki
+Tebeka.
+
+Supervisor: Dr. Michael Elhadad
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+700K gps10src.zip - Same with all source code
+400K mfc40dll.zip - You might need this MFC40.DLL if you
+don't have it already.
+
+