 }
 
 void gc (object *form, object *env) {
-#if defined(debug1)
+  #if defined(debug1)
   int start = freespace;
-#endif
-  markobject(bra); markobject(ket); markobject(quo);
-  markobject(tee); markobject(dot);
+  #endif
+  markobject(tee); 
   markobject(GlobalEnv);
   markobject(GCStack);
   markobject(form);
   markobject(env);
   sweep();
-#if defined(debug1)
+  #if defined(debug1)
   Serial.print('{');
   Serial.print(freespace - start);
   Serial.println('}');
-#endif
-}
-
+  #endif
+}
+
+// Save-image and load-image
+
+typedef struct {
+  unsigned int eval;
+  unsigned int datasize;
+  unsigned int globalenv;
+  unsigned int tee;
+  char data[];
+} struct_image;
+
+struct_image EEMEM image;
+
+void movepointer (object *from, object *to) {
+  for (int i=0; i<workspacesize; i++) {
+    object *obj = &workspace[i];
+    int type = (obj->type) & 0x7FFF;
+    if (marked(obj) && type != SYMBOL && type != NUMBER) {
+      if (car(obj) == (object *)((unsigned int)from | 0x8000)) 
+        car(obj) = (object *)((unsigned int)to | 0x8000);
+      if (cdr(obj) == from) cdr(obj) = to;
+    }
+  }
+}
+  
+int compactimage (object **arg) {
+  markobject(tee);
+  markobject(GlobalEnv);
+  markobject(GCStack);
+  object *firstfree = workspace;
+  while (marked(firstfree)) firstfree++;
+
+  for (int i=0; i<workspacesize; i++) {
+    object *obj = &workspace[i];
+    if (marked(obj) && firstfree < obj) {
+      car(firstfree) = car(obj);
+      cdr(firstfree) = cdr(obj);
+      unmark(obj);
+      movepointer(obj, firstfree);
+      if (GlobalEnv == obj) GlobalEnv = firstfree;
+      if (GCStack == obj) GCStack = firstfree;
+      if (tee == obj) tee = firstfree;
+      if (*arg == obj) *arg = firstfree;
+      while (marked(firstfree)) firstfree++;
+    }
+  }
+  sweep();
+  return firstfree - workspace;
+}
+  
+int saveimage (object *arg) {
+  unsigned int imagesize = compactimage(&arg);
+  // Save to EEPROM
+  if ((imagesize*4+8) > EEPROMsize) {
+    Serial.print(F("Error: Image size too large: "));
+    Serial.println(imagesize+2);
+    GCStack = NULL;
+    longjmp(exception, 1);
+  }
+  eeprom_write_word(&image.datasize, imagesize);
+  eeprom_write_word(&image.eval, (unsigned int)arg);
+  eeprom_write_word(&image.globalenv, (unsigned int)GlobalEnv);
+  eeprom_write_word(&image.tee, (unsigned int)tee);
+  eeprom_write_block(workspace, image.data, imagesize*4);
+  return imagesize+2;
+}
+
+int loadimage () {
+  unsigned int imagesize = eeprom_read_word(&image.datasize);
+  if (imagesize == 0 || imagesize == 0xFFFF) error(F("No saved image"));
+  GlobalEnv = (object *)eeprom_read_word(&image.globalenv);
+  tee = (object *)eeprom_read_word(&image.tee) ;
+  eeprom_read_block(workspace, image.data, imagesize*4);
+  gc(NULL, NULL);
+  return imagesize+2;
+}
 
 // Error handling
+
 void error (const __FlashStringHelper *string) {
   Serial.print(F("Error: "));
   Serial.println(string);

  Serial.print(micros() - start);
  Serial.println(F(" uS"));
  return nil;
}

// Arduino procedures

object *fn_mapc (object *args, object *env) {
  object *function = first(args);
  object *list1 = second(args);
  object *result = list1;
  if (!listp(list1)) error(F("'mapc' second argument is not a list"));
  object *list2 = third(args);
  if (!listp(list2)) error(F("'mapc' third argument is not a list"));
