[Avida-SVN] r2022 - in branches/energy: Avida.xcodeproj source source/cpu source/main source/script source/tools source/utils/process_map

beckma24 at myxo.css.msu.edu beckma24 at myxo.css.msu.edu
Tue Aug 28 11:53:27 PDT 2007


Author: beckma24
Date: 2007-08-28 14:53:26 -0400 (Tue, 28 Aug 2007)
New Revision: 2022

Added:
   branches/energy/source/main/cOrgMessage.h
   branches/energy/source/main/cOrgMessagePredicate.h
   branches/energy/source/utils/process_map/mypcolor.m
   branches/energy/source/utils/process_map/pcolor_all.m
Modified:
   branches/energy/Avida.xcodeproj/project.pbxproj
   branches/energy/source/cpu/cHardwareCPU.cc
   branches/energy/source/cpu/cHardwareCPU.h
   branches/energy/source/cpu/cInstSet.cc
   branches/energy/source/cpu/cInstSet.h
   branches/energy/source/cpu/cTestCPUInterface.h
   branches/energy/source/defs.h
   branches/energy/source/main/cAvidaConfig.h
   branches/energy/source/main/cOrgInterface.h
   branches/energy/source/main/cOrganism.cc
   branches/energy/source/main/cOrganism.h
   branches/energy/source/main/cPhenotype.cc
   branches/energy/source/main/cPhenotype.h
   branches/energy/source/main/cPopulationInterface.cc
   branches/energy/source/main/cPopulationInterface.h
   branches/energy/source/main/cStats.cc
   branches/energy/source/main/cStats.h
   branches/energy/source/main/cTaskContext.h
   branches/energy/source/script/ASTree.cc
   branches/energy/source/script/ASTree.h
   branches/energy/source/script/AvidaScript.h
   branches/energy/source/script/cASTDumpVisitor.cc
   branches/energy/source/script/cASTDumpVisitor.h
   branches/energy/source/script/cASTVisitor.h
   branches/energy/source/script/cLexer.l
   branches/energy/source/script/cParser.cc
   branches/energy/source/script/cParser.h
   branches/energy/source/tools/cRandom.cc
   branches/energy/source/tools/cRandom.h
   branches/energy/source/tools/tArray.h
   branches/energy/source/tools/tAutoRelease.h
   branches/energy/source/tools/tList.h
   branches/energy/source/utils/process_map/Makefile
   branches/energy/source/utils/process_map/process_map.cc
Log:
Merged development into energy branch (1980-2021)

Modified: branches/energy/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/energy/Avida.xcodeproj/project.pbxproj	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/Avida.xcodeproj/project.pbxproj	2007-08-28 18:53:26 UTC (rev 2022)
@@ -210,23 +210,6 @@
 		};
 /* End PBXBuildRule section */
 
-/* Begin PBXBuildStyle section */
-		B5029AA90C6B83D600D10480 /* Development */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-			};
-			name = Development;
-		};
-		B5029AAA0C6B83D600D10480 /* Deployment */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-			};
-			name = Deployment;
-		};
-/* End PBXBuildStyle section */
-
 /* Begin PBXContainerItemProxy section */
 		56F555DA0C3B36FC00E2E929 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
@@ -368,9 +351,11 @@
 		1097463D0AE9606E00929ED6 /* cDeme.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cDeme.cc; sourceTree = "<group>"; };
 		1097463E0AE9606E00929ED6 /* cDeme.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cDeme.h; sourceTree = "<group>"; };
 		4201F39A0BE187F6006279B9 /* cTopology.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cTopology.h; sourceTree = "<group>"; };
+		422B64520C8305C40012C545 /* cOrgMessagePredicate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cOrgMessagePredicate.h; sourceTree = "<group>"; };
 		423335880BC067E3000DF681 /* cHardwareGX.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cHardwareGX.cc; sourceTree = "<group>"; };
 		423335890BC067E3000DF681 /* cHardwareGX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cHardwareGX.h; sourceTree = "<group>"; };
 		42490EFE0BE2472800318058 /* cGermline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cGermline.h; sourceTree = "<group>"; };
+		42777E5B0C7F123600AFA4ED /* cOrgMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cOrgMessage.h; sourceTree = "<group>"; };
 		5629D80D0C3EE13500C5F152 /* cTextWindow.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cTextWindow.cc; sourceTree = "<group>"; };
 		5629D80E0C3EE13500C5F152 /* cTextWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cTextWindow.h; sourceTree = "<group>"; };
 		5629D80F0C3EE13500C5F152 /* ncurses-defs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "ncurses-defs.h"; sourceTree = "<group>"; };
@@ -1414,6 +1399,8 @@
 				70B0864F08F4972600FC65FE /* cMxCodeArray.h */,
 				70B0868708F49EA800FC65FE /* cOrganism.cc */,
 				70B0868308F49E9700FC65FE /* cOrganism.h */,
+				42777E5B0C7F123600AFA4ED /* cOrgMessage.h */,
+				422B64520C8305C40012C545 /* cOrgMessagePredicate.h */,
 				70B0869C08F49F4800FC65FE /* cPhenotype.cc */,
 				70B0869B08F49F3900FC65FE /* cPhenotype.h */,
 				70B0868908F49EA800FC65FE /* cPopulation.cc */,
@@ -1782,12 +1769,6 @@
 		DCC30C4D0762532C008F7A48 /* Project object */ = {
 			isa = PBXProject;
 			buildConfigurationList = 702442D70859E0B00059BD9B /* Build configuration list for PBXProject "Avida" */;
-			buildSettings = {
-			};
-			buildStyles = (
-				B5029AA90C6B83D600D10480 /* Development */,
-				B5029AAA0C6B83D600D10480 /* Deployment */,
-			);
 			hasScannedForEncodings = 0;
 			mainGroup = DCC30C490762532C008F7A48;
 			productRefGroup = DCC3164E07626CF3008F7A48 /* Products */;

Modified: branches/energy/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/cpu/cHardwareCPU.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -38,6 +38,7 @@
 #include "cMutationLib.h"
 #include "nMutation.h"
 #include "cOrganism.h"
+#include "cOrgMessage.h"
 #include "cPhenotype.h"
 #include "cPopulation.h"
 #include "cPopulationCell.h"
@@ -353,21 +354,18 @@
     tInstLibEntry<tMethod>("sleep4", &cHardwareCPU::Inst_Sleep),
     tInstLibEntry<tMethod>("time", &cHardwareCPU::Inst_GetUpdate),
     
-
     // Promoter Model
-    tInstLibEntry<tMethod>("up-reg-*", &cHardwareCPU::Inst_UpRegulatePromoter),
-    tInstLibEntry<tMethod>("down-reg-*", &cHardwareCPU::Inst_DownRegulatePromoter),
-    tInstLibEntry<tMethod>("up-reg", &cHardwareCPU::Inst_UpRegulatePromoterNop),
-    tInstLibEntry<tMethod>("down-reg", &cHardwareCPU::Inst_DownRegulatePromoterNop),
-    tInstLibEntry<tMethod>("up-reg>0", &cHardwareCPU::Inst_UpRegulatePromoterNopIfGT0),
-    tInstLibEntry<tMethod>("down-reg>0", &cHardwareCPU::Inst_DownRegulatePromoterNopIfGT0),
     tInstLibEntry<tMethod>("terminate", &cHardwareCPU::Inst_Terminate),
     tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
-    tInstLibEntry<tMethod>("decay-reg", &cHardwareCPU::Inst_DecayRegulation),
+    tInstLibEntry<tMethod>("regulate", &cHardwareCPU::Inst_Regulate),
     
     // Energy usage
     tInstLibEntry<tMethod>("double-energy-usage", &cHardwareCPU::Inst_DoubleEnergyUsage),
     tInstLibEntry<tMethod>("half-energy-usage", &cHardwareCPU::Inst_HalfEnergyUsage),
+
+    // Messaging
+    tInstLibEntry<tMethod>("send-msg", &cHardwareCPU::Inst_SendMessage),
+    tInstLibEntry<tMethod>("retrieve-msg", &cHardwareCPU::Inst_RetrieveMessage),
     
     // Placebo instructions
     tInstLibEntry<tMethod>("skip", &cHardwareCPU::Inst_Skip),
@@ -553,9 +551,6 @@
     // Print the status of this CPU at each step...
     if (m_tracer != NULL) m_tracer->TraceHardware(*this);
     
-    // For tracing when termination occurs...
-    if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) organism->GetPhenotype().SetTerminated(false);
-
     // Find the instruction to be executed
     const cInstruction& cur_inst = IP().GetInst();
     
@@ -4269,188 +4264,12 @@
 
 //// Promoter Model ////
 
-// Starting at the current position reads a promoter pattern
-void cHardwareCPU::GetPromoterPattern(tArray<int>& promoter)
+bool cHardwareCPU::Inst_Promoter(cAvidaContext& ctx)
 {
-  // For now a constant that defines behavior
-  const int max_size = 6;
-  int count = 0;
-  
-  cHeadCPU& inst_ptr = IP();
-    
-  while ( (inst_ptr.GetNextInst().GetOp() != m_inst_set->GetNumNops() - 1) &&
-         (count < max_size) ) {
-    count++;
-    inst_ptr++;
-    promoter.Push(inst_ptr.GetInst().GetOp());
-  }
+  // Promoters don't do anything themselves
+  return true;
 }
 
-
-// Adjust the weight at promoter positions that match the downstream pattern
-// allowing wildcards and matching of instructions
-void cHardwareCPU::RegulatePromoter(cAvidaContext& ctx, bool up)
-{
-  static cInstruction promoter_inst = GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
-
-  // Save the initial site so we don't match our own pattern
-  cHeadCPU inst_ptr(IP());
-
-  tArray<int> promoter;
-  GetPromoterPattern(promoter);
-  if (promoter.GetSize() == 0) return;
-
-  // nop-A is a wildcard of length 1
-  // nop-B is a wildcard of length 1
-  // nop-C (the final nop) terminates the matching pattern, and is not included
-  
-  cHeadCPU search_head(IP());  
-  while (search_head.GetPosition() != inst_ptr.GetPosition()) 
-  {
-    cHeadCPU match_head(search_head);
-    int matched_pos = 0;
-    while (matched_pos < promoter.GetSize())
-    {
-      // Unless the promoter pattern has a nop, we must match the instruction exactly
-      if ( (promoter[matched_pos] > m_inst_set->GetNumNops())
-        && (promoter[matched_pos] != match_head.GetInst().GetOp()) )
-      {
-        break;
-      }
-      matched_pos++;
-      match_head++;
-    }
-    
-    // Successfully matched, change this promoter position weight
-    if (matched_pos == promoter.GetSize())
-    {
-      cHeadCPU change_head(search_head);
-      for (int j=0; j < 5; j++)
-      {
-        change_head++;
-        if (change_head.GetInst() == promoter_inst) {
-          organism->GetPhenotype().RegulatePromoter(change_head.GetPosition(), up);
-        }
-      }
-    }
-    search_head++;
-  }
-}
-
-// Adjust the weight at promoter positions that match the downstream nop pattern
-void cHardwareCPU::RegulatePromoterNop(cAvidaContext& ctx, bool up)
-{
-  const int max_distance_to_promoter = 3;
-  
-  // Look for the label directly (no complement)
-  // Save the position before the label, so we don't count it as a regulatory site
-  int start_pos = IP().GetPosition(); 
-  ReadLabel();
-  
-  // Don't allow zero-length label matches.
-  if (GetLabel().GetSize() == 0) return;
-  
-  cHeadCPU search_head(IP());
-  do {
-    //Find the next nop
-    search_head++;
-    
-    cHeadCPU match_head(search_head);
-
-    // See whether a matching label is here (Note: we count sub-labels as valid matches)
-    int i;
-    for (i=0; i < GetLabel().GetSize(); i++)
-    {
-      match_head++;
-      if ( !m_inst_set->IsNop(match_head.GetInst() ) 
-        || (GetLabel()[i] != m_inst_set->GetNopMod( match_head.GetInst())) ) break;
-    }
-  
-    // Matching label found (next inst must not be a nop)
-    if (i == GetLabel().GetSize())
-    {
-      //Check each promoter
-      int start_pos = match_head.GetPosition();
-      int end_pos = start_pos + max_distance_to_promoter;
-      int circle_end = end_pos % GetMemory().GetSize(); //annoying circular genomes
-
-      for (int j=0; j<promoter_pos.GetSize(); j++)
-      {
-        if ( (promoter_pos[j] >= start_pos) && (promoter_pos[j] < end_pos) ) promoter_active[j] = up;
-        if ( (circle_end != end_pos) &&  (promoter_pos[j] >= 0) && (promoter_pos[j] < circle_end) ) promoter_active[j] = up;
-
-      }
-    }
-  } while ( start_pos != search_head.GetPosition() );
-}
-
-
-/* Alternate version, cleanup later @JEB
-// Adjust the weight at promoter positions that match the downstream nop pattern
-void cHardwareCPU::RegulatePromoterNop(cAvidaContext& ctx, bool up)
-{
-  static cInstruction promoter_inst = GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
-  const int max_distance_to_promoter = 10;
-  
-  // Look for the label directly (no complement)
-  // Save the position before the label, so we don't count it as a regulatory site
-  int start_pos = IP().GetPosition(); 
-  ReadLabel();
-  
-  // Don't allow zero-length label matches. These are too powerful.
-  if (GetLabel().GetSize() == 0) return;
- 
-  cHeadCPU search_head(IP());
-  do {
-    search_head++;
-    cHeadCPU match_head(search_head);
-
-    // See whether a matching label is here
-    int i;
-    for (i=0; i < GetLabel().GetSize(); i++)
-    {
-      match_head++;
-      if ( !m_inst_set->IsNop(match_head.GetInst() ) 
-        || (GetLabel()[i] != m_inst_set->GetNopMod( match_head.GetInst())) ) break;
-    }
-  
-    // Matching label found
-    if (i == GetLabel().GetSize())
-    {
-      cHeadCPU change_head(match_head);
-      for (int j=0; j < max_distance_to_promoter; j++)
-      {
-        change_head++;
-        if (change_head.GetInst() == promoter_inst) {
-         
-          if (change_head.GetPosition() < organism->GetPhenotype().GetCurPromoterWeights().GetSize())
-          {
-            organism->GetPhenotype().RegulatePromoter(change_head.GetPosition(), up);
-          }
-          else
-          {
-            // I can't seem to get resizing promoter arrays on memory allocation to work.
-            // Promoter weights still get unsynched from the genome size somewhere. @JEB
-            //cout << change_head.GetPosition() << endl;
-            //cout << organism->GetPhenotype().GetCurPromoterWeights().GetSize() << endl;
-            //cout << GetMemory().GetSize() << endl;
-            //cout << GetMemory().AsString() << endl;
-          }
-        }
-      }
-    }
-  } while ( start_pos != search_head.GetPosition() );
-}
-*/
-
-// Adjust the weight at promoter positions that match the downstream nop pattern
-void cHardwareCPU::RegulatePromoterNopIfGT0(cAvidaContext& ctx, bool up)
-{
-  // whether we do regulation is related to BX
-  double reg = (double) GetRegister(REG_BX);
-  if (reg > 0) RegulatePromoterNop(ctx, up);
-}
-
 // Move execution to a new promoter
 bool cHardwareCPU::Inst_Terminate(cAvidaContext& ctx)
 {
@@ -4464,7 +4283,6 @@
   // We want to execute the promoter that we land on.
   promoter_inst_executed = 0;
   m_advance_ip = false;
-  organism->GetPhenotype().SetTerminated(true);
   
   //Setting this makes it harder to do things. You have to be modular.
   organism->GetOrgInterface().ResetInputs(ctx);   // Re-randomize the inputs this organism sees
@@ -4495,67 +4313,46 @@
   return true;
 }
 
-/* Older version... @JEB
-// Move execution to a new promoter
-bool cHardwareCPU::Inst_Terminate(cAvidaContext& ctx)
+// To be implemented...
+bool cHardwareCPU::Inst_Regulate(cAvidaContext& ctx)
 {
-  // Reset the CPU, clearing everything except R/W head positions.
-  const int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
-  const int read_head_pos = GetHead(nHardware::HEAD_READ).GetPosition();
-  m_threads[m_cur_thread].Reset(this, m_threads[m_cur_thread].GetID());
-  GetHead(nHardware::HEAD_WRITE).Set(write_head_pos);
-  GetHead(nHardware::HEAD_READ).Set(read_head_pos);
-
-  // We want to execute the promoter that we land on.
-  m_advance_ip = false;
-  organism->GetPhenotype().SetTerminated(true);
-  
-  //organism->ClearInput();
-  
-  // Get the promoter weight list
-  double total_weight = 0;
-  tArray<double> w = organism->GetPhenotype().GetCurPromoterWeights();
-  for (int i = 0; i < w.GetSize(); i++) {
-    total_weight += w[i];
-  }
-   
-  // If there is no weight (for example if there are no promoters)
-  // then randomly choose a starting position
-  if (total_weight==0)
-  {
-    // Or we could kill the organism...
-    //organism->Die();
-    //return true;
-    
-    int i = m_world->GetRandom().GetInt(w.GetSize());
-    IP().Set(i);
-    return true;
-  }
-  
-  // Add together all of the promoter weights
-  double promoter_choice = (double) m_world->GetRandom().GetDouble(total_weight);
-  double test_total = 0;
-  for (int i = 0; i < w.GetSize(); i++) {
-    test_total += w[i];
-    if (promoter_choice < test_total) {
-      IP().Set(i);
-      break;
-    }
-  }  
   return true;
 }
-*/
 
-bool cHardwareCPU::Inst_Promoter(cAvidaContext& ctx)
+
+/*! Send a message to the organism that is currently faced by this cell,
+where the label field of sent message is from register ?BX?, and the data field
+is from register ~?BX?.
+*/
+bool cHardwareCPU::Inst_SendMessage(cAvidaContext& ctx)
 {
-  // Promoters don't do anything themselves
-  return true;
+  const int label_reg = FindModifiedRegister(REG_BX);
+  const int data_reg = FindNextRegister(label_reg);
+  
+  cOrgMessage msg = cOrgMessage(organism);
+  msg.SetLabel(GetRegister(label_reg));
+  msg.SetData(GetRegister(data_reg));
+  return organism->SendMessage(ctx, msg);
 }
 
 
-bool cHardwareCPU::Inst_DecayRegulation(cAvidaContext& ctx)
+/*! This method /attempts/ to retrieve a message -- It may not be possible, as in
+the case of an empty receive buffer.
+
+If a message is available, ?BX? is set to the message's label, and ~?BX? is set
+to its data.
+*/
+bool cHardwareCPU::Inst_RetrieveMessage(cAvidaContext& ctx) 
 {
-  organism->GetPhenotype().DecayAllPromoterRegulation();
+  const cOrgMessage* msg = organism->RetrieveMessage();
+  if(msg == 0)
+    return false;
+  
+  const int label_reg = FindModifiedRegister(REG_BX);
+  const int data_reg = FindNextRegister(label_reg);
+  
+  GetRegister(label_reg) = msg->GetLabel();
+  GetRegister(data_reg) = msg->GetData();
   return true;
 }
 
@@ -4566,4 +4363,3 @@
   IP().Advance();
   return true;
 }
-

Modified: branches/energy/source/cpu/cHardwareCPU.h
===================================================================
--- branches/energy/source/cpu/cHardwareCPU.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/cpu/cHardwareCPU.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -532,20 +532,13 @@
   bool Inst_GetUpdate(cAvidaContext& ctx);
 
   //// Promoter Model ////
-  
-  void GetPromoterPattern(tArray<int>& promoter);
-  void RegulatePromoter(cAvidaContext& ctx, bool up);
-  bool Inst_UpRegulatePromoter(cAvidaContext& ctx) { RegulatePromoter(ctx, true); return true; }
-  bool Inst_DownRegulatePromoter(cAvidaContext& ctx) { RegulatePromoter(ctx, false); return true; }
-  void RegulatePromoterNop(cAvidaContext& ctx, bool up);
-  bool Inst_UpRegulatePromoterNop(cAvidaContext& ctx) { RegulatePromoterNop(ctx, true); return true; }
-  bool Inst_DownRegulatePromoterNop(cAvidaContext& ctx) { RegulatePromoterNop(ctx, false); return true; }
-  void RegulatePromoterNopIfGT0(cAvidaContext& ctx, bool up); 
-  bool Inst_UpRegulatePromoterNopIfGT0(cAvidaContext& ctx) { RegulatePromoterNopIfGT0(ctx, true); return true; }
-  bool Inst_DownRegulatePromoterNopIfGT0(cAvidaContext& ctx) { RegulatePromoterNopIfGT0(ctx, false); return true; } 
-  bool Inst_Terminate(cAvidaContext& ctx);
   bool Inst_Promoter(cAvidaContext& ctx);
-  bool Inst_DecayRegulation(cAvidaContext& ctx);
+  bool Inst_Terminate(cAvidaContext& ctx);
+  bool Inst_Regulate(cAvidaContext& ctx);
+
+  //// Messaging ////
+  bool Inst_SendMessage(cAvidaContext& ctx);
+  bool Inst_RetrieveMessage(cAvidaContext& ctx);
   
   //// Placebo ////
   bool Inst_Skip(cAvidaContext& ctx);

Modified: branches/energy/source/cpu/cInstSet.cc
===================================================================
--- branches/energy/source/cpu/cInstSet.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/cpu/cInstSet.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -158,7 +158,15 @@
   // Double
   schema.AddEntry("prob_fail", 0, 0.0);
   
+  // String  
+  schema.AddEntry("inst_code", 0, "");
   
+  
+  // Ensure that the instruction code length is in the range of bits supported by the int type
+  int inst_code_len = m_world->GetConfig().INST_CODE_LENGTH.Get();
+  if ((unsigned)inst_code_len > (sizeof(int) * 8)) inst_code_len = sizeof(int) * 8;
+  else if (inst_code_len <= 0) inst_code_len = 1;
+  
   tList<cString> errors;
   bool success = true;
   for (int line_id = 0; line_id < sl.GetSize(); line_id++) {
@@ -194,7 +202,6 @@
       continue;
     }
     
-    
     int redundancy = args->GetInt(0);
     if (redundancy < 0) {
       m_world->GetDriver().NotifyWarning(cString("Instruction '") + inst_name + "' has negative redundancy, ignoring.");
@@ -225,6 +232,37 @@
     m_lib_name_map[inst_id].prob_fail = args->GetDouble(0);
     m_lib_name_map[inst_id].addl_time_cost = args->GetInt(4);
     
+    
+    // Parse the instruction code
+    cString inst_code = args->GetString(0);
+    if (inst_code == "") {
+      switch (m_world->GetConfig().INST_CODE_DEFAULT_TYPE.Get()) {
+        case INST_CODE_ZEROS:
+          m_lib_name_map[inst_id].inst_code = 0;
+          break;
+        case INST_CODE_INSTNUM:
+          m_lib_name_map[inst_id].inst_code = ((~0) >> ((sizeof(int) * 8) - inst_code_len)) & inst_id;
+          break;
+        default:
+          errors.PushRear(new cString("Invalid default instruction code type."));
+          success = false;
+          break;
+      }
+    } else {
+      int inst_code_val = 0;
+      for (int i = 0; i < inst_code_len && i < inst_code.GetSize(); i++) {
+        inst_code_val <<= 1;
+        if (inst_code[i] == '1') inst_code_val |= 1;
+        else if (inst_code[i] != '0') {
+          errors.PushRear(new cString("Invalid character in instruction code, must be 0 or 1."));
+          success = false;
+          break;
+        }
+      }
+      
+      m_lib_name_map[inst_id].inst_code = inst_code_val;
+    }
+    
 
     // If this is a nop, add it to the proper mappings
     if ((*m_inst_lib)[fun_id].IsNop()) {
@@ -322,6 +360,7 @@
     m_lib_name_map[inst_id].energy_cost = energy_cost;
     m_lib_name_map[inst_id].prob_fail = prob_fail;
     m_lib_name_map[inst_id].addl_time_cost = addl_time_cost;
+    m_lib_name_map[inst_id].inst_code = 0;
     
     const int total_redundancy = m_mutation_chart.GetSize();
     m_mutation_chart.Resize(total_redundancy + redundancy);

Modified: branches/energy/source/cpu/cInstSet.h
===================================================================
--- branches/energy/source/cpu/cInstSet.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/cpu/cInstSet.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -72,6 +72,7 @@
     int energy_cost;          // energy required to execute.
     double prob_fail;         // probability of failing to execute inst
     int addl_time_cost;       // additional time added to age for executing instruction
+    int inst_code;            // instruction binary code
   };
   tSmartArray<sInstEntry> m_lib_name_map;
   
@@ -95,12 +96,15 @@
   // Accessors
   const cString& GetName(int id) const { return m_inst_lib->GetName(m_lib_name_map[id].lib_fun_id); }
   const cString& GetName(const cInstruction& inst) const { return GetName(inst.GetOp()); }
+  
+  int GetRedundancy(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].redundancy; }
   int GetCost(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].cost; }
   int GetFTCost(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].ft_cost; }
   int GetEnergyCost(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].energy_cost; }
+  double GetProbFail(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].prob_fail; }
   int GetAddlTimeCost(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].addl_time_cost; }
-  double GetProbFail(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].prob_fail; }
-  int GetRedundancy(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].redundancy; }
+  int GetInstructionCode(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].inst_code; }
+  
   int GetLibFunctionIndex(const cInstruction& inst) const { return m_lib_name_map[inst.GetOp()].lib_fun_id; }
 
   int GetNopMod(const cInstruction& inst) const

Modified: branches/energy/source/cpu/cTestCPUInterface.h
===================================================================
--- branches/energy/source/cpu/cTestCPUInterface.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/cpu/cTestCPUInterface.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -74,6 +74,7 @@
   bool UpdateMerit(double new_merit);
   bool TestOnDivide() { return false; }
   int GetFacing() { return 0; }
+  bool SendMessage(cOrgMessage& msg) { return false; }
 };
 
 

Modified: branches/energy/source/defs.h
===================================================================
--- branches/energy/source/defs.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/defs.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -158,6 +158,12 @@
   BASE_MERIT_NUM_BONUS_INST
 };
 
+enum eINST_CODE_DEFAULT
+{
+  INST_CODE_ZEROS = 0,
+  INST_CODE_INSTNUM
+};
+
 enum eVerbosity {
   VERBOSE_SILENT = 0,   // No output at all
   VERBOSE_NORMAL,       // Notification at start of commands.

Modified: branches/energy/source/main/cAvidaConfig.h
===================================================================
--- branches/energy/source/main/cAvidaConfig.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cAvidaConfig.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -471,6 +471,8 @@
   CONFIG_ADD_VAR(PROMOTER_BG_STRENGTH, double, 0, "Probability of positions that are not promoter\ninstructions initiating execution (promoters are 1).");
   CONFIG_ADD_VAR(REGULATION_STRENGTH, double, 1, "Strength added or subtracted to a promoter by regulation.");
   CONFIG_ADD_VAR(REGULATION_DECAY_FRAC, double, 0.1, "Fraction of regulation that decays away. \nMax regulation = 2^(REGULATION_STRENGTH/REGULATION_DECAY_FRAC)");
+  CONFIG_ADD_VAR(INST_CODE_LENGTH, int, 4, "Instruction binary code length (number of bits)");
+  CONFIG_ADD_VAR(INST_CODE_DEFAULT_TYPE, int, 0, "Default value of instruction binary code value.\n0 = All zeros\n1 = Based of the instruction number");
 
   CONFIG_ADD_GROUP(COLORS_GROUP, "Output colors for when data files are printed in HTML mode.\nThere are two sets of these; the first are for lineages,\nand the second are for mutation tests.");
   CONFIG_ADD_VAR(COLOR_DIFF, cString, "CCCCFF", "Color to flag stat that has changed since parent.");

Modified: branches/energy/source/main/cOrgInterface.h
===================================================================
--- branches/energy/source/main/cOrgInterface.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cOrgInterface.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -38,6 +38,7 @@
 class cCodeLabel;
 class cGenome;
 class cOrganism;
+class cOrgMessage;
 class cOrgSinkMessage;
 template <class T> class tArray;
 
@@ -82,6 +83,7 @@
   virtual bool InjectParasite(cOrganism* parent, const cCodeLabel& label, const cGenome& injected_code) = 0;
   virtual bool UpdateMerit(double new_merit) = 0;
   virtual bool TestOnDivide() = 0;
+  virtual bool SendMessage(cOrgMessage& msg) = 0;
 };
 
 #endif

Copied: branches/energy/source/main/cOrgMessage.h (from rev 2021, development/source/main/cOrgMessage.h)
===================================================================
--- branches/energy/source/main/cOrgMessage.h	                        (rev 0)
+++ branches/energy/source/main/cOrgMessage.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -0,0 +1,70 @@
+/*
+ *  cOrgMessage.h
+ *  Avida
+ *
+ *  Called "org_message.hh" prior to 12/5/05.
+ *  Copyright 2005-2006 Michigan State University. All rights reserved.
+ *  Copyright 1993-2003 California Institute of Technology.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; version 2
+ *  of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+#ifndef cOrgMessage_h
+#define cOrgMessage_h
+
+class cOrganism;
+
+
+/*! This class encapsulates two unsigned integers that are sent as a "message"
+between connected organisms within an Avida population.  The label and data fields
+are these two integers, while the sending and receiving organisms are represented by
+pointers.
+
+\todo Extend to support a varying number of bytes.
+*/
+class cOrgMessage
+{
+public:
+  //! Constructor that takes a pointer to the sending organism.
+  cOrgMessage(cOrganism* sender) : m_pSender(sender), m_pReceiver(0), m_data(0), m_label(0) 
+  {
+    assert(m_pSender);
+  }
+  
+  cOrganism* GetSender() const { return m_pSender; }
+  cOrganism* GetReceiver() const { return m_pReceiver; }
+  void SetReceiver(cOrganism* recvr) { m_pReceiver = recvr; }
+  
+  unsigned int GetData() const { return m_data; }
+  unsigned int GetLabel() const { return m_label; }
+  
+  void SetData(unsigned int data) { m_data = data; }
+  void SetLabel(unsigned int label) { m_label = label; }
+
+private:
+  //! Default constructor is only used internally, to support message predicates.
+  cOrgMessage() : m_pSender(0), m_pReceiver(0), m_data(0), m_label(0)
+  {
+  }
+  
+  cOrganism* m_pSender;
+  cOrganism* m_pReceiver;
+  unsigned int m_data;
+  unsigned int m_label;
+};
+
+
+#endif

Copied: branches/energy/source/main/cOrgMessagePredicate.h (from rev 2021, development/source/main/cOrgMessagePredicate.h)
===================================================================
--- branches/energy/source/main/cOrgMessagePredicate.h	                        (rev 0)
+++ branches/energy/source/main/cOrgMessagePredicate.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -0,0 +1,130 @@
+/*
+ *  cOrgMessagePredicate.h
+ *  Avida
+ *
+ *  Copyright 2005-2006 Michigan State University. All rights reserved.
+ *  Copyright 1993-2003 California Institute of Technology.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; version 2
+ *  of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+#ifndef cOrgMessagePredicate_h
+#define cOrgMessagePredicate_h
+
+#include <iostream>
+#include <functional>
+#include <set>
+
+#include "cOrgMessage.h"
+#include "cOrganism.h"
+
+
+/*! \brief An STL-compatible predicate on cOrgMessages.  The intent here is to
+provide a straightforward way to track arbitrary messages *wherever* they appear
+in the population.  The most utility can be had from message predicates if they're
+installed into cStats (since every message goes through cStats). */
+struct cOrgMessagePredicate : public std::unary_function<cOrgMessage, bool> 
+{
+  virtual ~cOrgMessagePredicate() { }
+  virtual bool operator()(const cOrgMessage& msg) = 0;
+  virtual void Print(std::ostream& out) { }
+  virtual void Reset() { }
+};
+
+
+/*! A predicate that returns true and tracks the sending cell_id for messages
+that contain the same data field as this predicate was constructed with.
+*/
+struct cOrgMessagePred_DataEQU : public cOrgMessagePredicate 
+{
+  cOrgMessagePred_DataEQU(unsigned int data) : m_data(data) { }
+  
+  virtual bool operator()(const cOrgMessage& msg) {
+    if(m_data==msg.GetData()) {
+      m_cell_ids.insert(msg.GetSender()->GetCellID());
+    }
+    return true;
+  }
+  
+  virtual void Print(std::ostream& out) { 
+    out << "data==" << m_data << ":{";
+    for(std::set<int>::iterator i=m_cell_ids.begin(); i!=m_cell_ids.end(); ++i) {
+      out << *i << ",";
+    }
+    out << "}";
+  }
+  
+  virtual void Reset() { 
+    m_cell_ids.clear();
+  }
+  
+  unsigned int m_data;
+  std::set<int> m_cell_ids;
+};
+
+
+/*! A predicate that returns true and tracks the label and data field for messages
+that contain a sink as the receiver.
+*/
+struct cOrgMessagePred_SinkReceiverEQU : public cOrgMessagePredicate {
+  cOrgMessagePred_SinkReceiverEQU(unsigned int data) : m_data(data) { }
+  
+  virtual bool operator()(const cOrgMessage& msg) {
+    if(m_data==(unsigned int)msg.GetReceiver()->GetCellID()) {
+      m_cell_ids.insert(msg.GetData());
+//      cWorld* w = msg.GetSender()->getWorld();
+      /*      int i = w->GetPopulation().GetCell(289).GetRandomCellID();
+      if(msg.GetData() == i) {
+        std::cout<<"289 = "<< i<<endl;
+      }*/
+    }
+    return true;
+  }
+  
+  virtual void print(std::ostream& out) { 
+//    cPopulationCell::t_id_map& ids = cPopulationCell::GetRandomCellIDMap();
+//    int badMSGs = 0;
+//    
+//    out << "data==" << m_data << ":{";
+//    for(std::set<int>::iterator i=m_cell_ids.begin(); i!=m_cell_ids.end(); ++i) {
+//      int x,y;
+//      //check if # is ID and log cell location and count bad messages
+//      if(cPopulationCell::IsRandomCellID(*i)) {
+//        cPopulationCell* cell = ids.find(*i)->second;
+//        cell->GetPosition(x, y);
+//        out << x <<" "<< y << ",";
+//        m_cell_ids_total_good.insert(cell->GetRandomCellID());
+//      } else {
+//        badMSGs++;
+//        //        out << *i << ",";
+//      }
+//    }
+//    //write # bad messages in last slot
+//    out << badMSGs;
+//    out << "} "<<m_cell_ids_total_good.size();
+  }
+  
+  virtual void reset() { 
+    m_cell_ids.clear();
+  }
+  
+  unsigned int m_data;
+  std::set<int> m_cell_ids;
+  std::set<int> m_cell_ids_total_good;
+};
+
+
+#endif

Modified: branches/energy/source/main/cOrganism.cc
===================================================================
--- branches/energy/source/main/cOrganism.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cOrganism.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -70,6 +70,7 @@
   , m_is_running(false)
   , m_is_sleeping(false)
   , m_net(NULL)
+  , m_msg(0)
 {
   // Initialization of structures...
   m_hardware = m_world->GetHardwareManager().Create(this);
@@ -99,6 +100,7 @@
   delete m_hardware;
   delete m_interface;
   if (m_net != NULL) delete m_net;
+  if(!m_msg) delete m_msg;
 }
 
 cOrganism::cNetSupport::~cNetSupport()
@@ -168,18 +170,31 @@
 }
 
 
+void cOrganism::DoOutput(cAvidaContext& ctx, const bool on_divide)
+{
+  DoOutput(ctx, m_input_buf, m_output_buf, on_divide, false);
+}
 
-void cOrganism::DoOutput(cAvidaContext& ctx, const int value, const bool on_divide)
+
+void cOrganism::DoOutput(cAvidaContext& ctx, const int value)
 {
-  DoOutput(ctx, m_input_buf, m_output_buf, value, on_divide);
+  m_output_buf.Add(value);
+  DoOutput(ctx, m_input_buf, m_output_buf, false, NetValidate(ctx, value));
 }
 
 
+void cOrganism::DoOutput(cAvidaContext& ctx, tBuffer<int>& input_buffer, tBuffer<int>& output_buffer, const int value)
+{
+  output_buffer.Add(value);
+  DoOutput(ctx, input_buffer, output_buffer, false, NetValidate(ctx, value));
+}
+
+
 void cOrganism::DoOutput(cAvidaContext& ctx, 
                          tBuffer<int>& input_buffer, 
                          tBuffer<int>& output_buffer,
-                         const int value,
-                         const bool on_divide)
+                         const bool on_divide,
+                         const bool net_valid)
 {
   const int deme_id = m_interface->GetDemeID();
   const tArray<double> & global_resource_count = m_interface->GetResources();
@@ -212,14 +227,8 @@
     }
   }
   
-  bool net_valid = false;
-  if (m_net) net_valid = NetValidate(ctx, value);
-  
   // Do the testing of tasks performed...
   
-  // if on IO add value to m_output_buf, if on divide don't need to
-  if(!on_divide) output_buffer.Add(value);
-  
   tArray<double> global_res_change(global_resource_count.GetSize());
   tArray<double> deme_res_change(deme_resource_count.GetSize());
   tArray<int> insts_triggered;
@@ -228,7 +237,7 @@
   if (!m_world->GetConfig().SAVE_RECEIVED.Get()) received_messages_point = NULL;
   
   cTaskContext taskctx(m_interface, input_buffer, output_buffer, other_input_list, 
-                       other_output_list, net_valid, 0, on_divide, received_messages_point);
+                       other_output_list, net_valid, 0, on_divide, received_messages_point, this);
                        
   //combine global and deme resource counts
   const tArray<double> globalAndDeme_resource_count = global_resource_count + deme_resource_count;
@@ -340,6 +349,8 @@
 
 bool cOrganism::NetValidate(cAvidaContext& ctx, int value)
 {
+  if(!m_net) return false;
+
   assert(m_net);
   
   if (0xFFFF0000 & value) return false;
@@ -569,7 +580,7 @@
   assert(m_interface);
   // Test tasks one last time before actually dividing, pass true so 
   // know that should only test "divide" tasks here
-  DoOutput(ctx, 0, true);
+  DoOutput(ctx, true);
 
   // Activate the child!  (Keep Last: may kill this organism!)
   return m_interface->Divide(ctx, this, m_child_genome);
@@ -609,3 +620,46 @@
   m_input_buf.Clear();
   m_output_buf.Clear();
 }
+
+
+bool cOrganism::SendMessage(cAvidaContext& ctx, cOrgMessage& msg)
+{
+  assert(m_interface);
+  InitMessaging();
+
+  // If we're able to succesfully send the message...
+  if(m_interface->SendMessage(msg)) {
+    // save it...
+    m_msg->sent.push_back(msg);
+    // stat-tracking...
+    m_world->GetStats().SentMessage(msg);
+    // check to see if we've performed any tasks...
+    DoOutput(ctx);
+    // and set the receiver-pointer of this message to NULL.  We don't want to
+    // walk this list later thinking that the receivers are still around.
+    m_msg->sent.back().SetReceiver(0);
+    return true;
+  }
+  
+  return false;
+}
+
+
+void cOrganism::ReceiveMessage(cOrgMessage& msg)
+{
+  InitMessaging();
+  msg.SetReceiver(this);    
+  m_msg->received.push_back(msg);
+}
+
+
+const cOrgMessage* cOrganism::RetrieveMessage()
+{
+  InitMessaging();
+
+  if(m_msg->retrieve_index < m_msg->received.size()) {
+    return &m_msg->received.at(m_msg->retrieve_index++);
+  }
+  
+  return 0;
+}

Modified: branches/energy/source/main/cOrganism.h
===================================================================
--- branches/energy/source/main/cOrganism.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cOrganism.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -27,6 +27,7 @@
 #define cOrganism_h
 
 #include <iostream>
+#include <vector>
 
 #ifndef cCPUMemory_h
 #include "cCPUMemory.h"
@@ -55,6 +56,9 @@
 #ifndef cOrgSourceMessage_h
 #include "cOrgSourceMessage.h"
 #endif
+#ifndef cOrgMessage_h
+#include "cOrgMessage.h"
+#endif
 #ifndef tArray_h
 #include "tArray.h"
 #endif
@@ -80,6 +84,7 @@
 class cSaleItem;
 
 
+
 class cOrganism
 {
 protected:
@@ -130,8 +135,7 @@
     ~cNetSupport();
   };
   cNetSupport* m_net;
-
-
+  
   cOrganism(); // @not_implemented
   cOrganism(const cOrganism&); // @not_implemented
   cOrganism& operator=(const cOrganism&); // @not_implemented
@@ -209,9 +213,22 @@
   // --------  Input and Output Methods  --------
   void DoInput(const int value);
   void DoInput(tBuffer<int>& input_buffer, tBuffer<int>& output_buffer, const int value);
-  void DoOutput(cAvidaContext& ctx, const int value, const bool on_divide = false);
+
+  /* These different flavors of DoOutput are "frontends" to the main DoOutput
+  that follows - One DoOutput to rule them all, etc., etc. */
+  //! Check tasks based on the current state of this organism's IO & message buffers.
+  void DoOutput(cAvidaContext& ctx, const bool on_divide=false);
+  //! Add the passed-in value to this organism's output buffer, and check tasks (on_divide=false).
+  void DoOutput(cAvidaContext& ctx, const int value);
+  //! Check tasks based on the passed-in IO buffers and value (on_divide=false).
+  void DoOutput(cAvidaContext& ctx, tBuffer<int>& input_buffer, tBuffer<int>& output_buffer, const int value);  
+
+protected:
+  /*! The main DoOutput function.  The DoOutputs above all forward to this function. */
   void DoOutput(cAvidaContext& ctx, tBuffer<int>& input_buffer, 
-                tBuffer<int>& output_buffer, const int value, const bool on_divide=false);
+                tBuffer<int>& output_buffer, const bool on_divide, const bool net_valid);
+
+public:
   void ClearInput() { m_input_buf.Clear(); }
   void AddOutput(int val) { m_output_buf.Add(val); }
 
@@ -238,7 +255,7 @@
   cInjectGenotype& GetParasite(int x) { return *m_parasites[x]; }
   int GetNumParasites() const { return m_parasites.GetSize(); }
   void ClearParasites();
-		      
+  
 
   // --------  Support Methods  --------
   double GetTestFitness(cAvidaContext& ctx);
@@ -291,6 +308,41 @@
   bool GetSterilizePos() const;
   double GetNeutralMin() const;
   double GetNeutralMax() const;
+
+  // -------- Messaging support --------
+public:
+  typedef std::vector<cOrgMessage> message_list_type; //!< Container-type for cOrgMessages.
+  
+  //! Called when this organism attempts to send a message.
+  bool SendMessage(cAvidaContext& ctx, cOrgMessage& msg);
+  //! Called when this organism has been sent a message.
+  void ReceiveMessage(cOrgMessage& msg);
+  //! Called when this organism attempts to move a received message into its CPU.
+  const cOrgMessage* RetrieveMessage();
+  //! Returns the list of all messsages received by this organism.
+  const message_list_type& GetReceivedMessages() { InitMessaging(); return m_msg->received; }
+  //! Returns the list of all messages sent by this organism.
+  const message_list_type& GetSentMessages() { InitMessaging(); return m_msg->sent; }
+  
+protected:
+  /*! Contains all the different data structures needed to support messaging within
+  cOrganism.  Inspired by cNetSupport (above), the idea is to minimize impact on
+  organisms that DON'T use messaging. */
+  struct cMessagingSupport
+  {
+    cMessagingSupport() : retrieve_index(0) { }
+    message_list_type sent; //!< List of all messages sent by this organism.
+    message_list_type received; //!< List of all messages received by this organism.
+    message_list_type::size_type retrieve_index; //!< Index of next message that can be retrieved.
+  };
+  
+  /*! This member variable is lazily initialized whenever any of the messaging
+  methods are used.  (My kingdom for boost::shared_ptr.) */
+  cMessagingSupport* m_msg;
+  
+  //! Called to check for (and initialize) messaging support within this organism.
+  inline void InitMessaging() { if(!m_msg) m_msg = new cMessagingSupport(); }
+  // -------- End of messaging support --------
 };
 
 

Modified: branches/energy/source/main/cPhenotype.cc
===================================================================
--- branches/energy/source/main/cPhenotype.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cPhenotype.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -52,7 +52,6 @@
   , cur_sense_count(m_world->GetStats().GetSenseSize())
   , sensed_resources(m_world->GetEnvironment().GetResourceLib().GetSize())
   , cur_task_time(m_world->GetEnvironment().GetNumTasks())   // Added for tracking time; WRE 03-18-07
-  , promoter_last_inst_terminated(false) 
   , last_task_count(m_world->GetEnvironment().GetNumTasks())
   , last_task_quality(m_world->GetEnvironment().GetNumTasks())
   , last_task_value(m_world->GetEnvironment().GetNumTasks())
@@ -115,12 +114,6 @@
   cur_sense_count          = in_phen.cur_sense_count;                 
   sensed_resources         = in_phen.sensed_resources;            
   cur_task_time            = in_phen.cur_task_time;   
-  active_transposons       = in_phen.active_transposons;   
-  base_promoter_weights    = in_phen.base_promoter_weights;      
-  cur_promoter_weights     = in_phen.cur_promoter_weights;        
-  promoter_activation      = in_phen.promoter_activation;         
-  promoter_repression      = in_phen.promoter_repression;        
-  promoter_last_inst_terminated = in_phen.promoter_last_inst_terminated;        
   
   // Dynamically allocated m_task_states requires special handling
   tList<cTaskState*> hash_values;
@@ -830,10 +823,6 @@
   gestation_start = 0;
   fitness         = clone_phenotype.fitness;
   div_type        = clone_phenotype.div_type;
-  cur_promoter_weights = clone_phenotype.cur_promoter_weights; // @JEB Not correct if clone is not of fresh phenotype 
-  base_promoter_weights = clone_phenotype.base_promoter_weights; // @JEB Not correct if clone is not of fresh phenotype 
-  promoter_repression = clone_phenotype.promoter_repression; // @JEB Not correct if clone is not of fresh phenotype 
-  promoter_activation = clone_phenotype.promoter_activation; // @JEB Not correct if clone is not of fresh phenotype 
 
   assert(genome_length > 0);
   assert(copied_size > 0);
@@ -1270,26 +1259,6 @@
   for (int i = 0; i < cur_task_count.GetSize(); i++)
     fp << " " << cur_task_count[i] << " (" << cur_task_quality[i] << ")";
   fp << endl;
-  
-  if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1)
-  {
-    fp << "Promoters:     ";
-    for (int i=0; i<cur_promoter_weights.GetSize(); i++)
-    {
-      if (cur_promoter_weights[i] != m_world->GetConfig().PROMOTER_BG_STRENGTH.Get()) fp << i << " (" << cur_promoter_weights[i] << ") ";
-    }
-    fp << endl;
-    
-    if (promoter_last_inst_terminated)
-    {
-      fp << "Terminated!" << endl;
-    }
-    else
-    {
-      fp << "No termination..." << endl;
-    }
-  }
-
 }
 
 int cPhenotype::CalcSizeMerit() const
@@ -1443,64 +1412,6 @@
   return child_energy;
 }
 
-void cPhenotype::SetupPromoterWeights(const cGenome & _genome, const bool clear)
-{
-  if (!m_world->GetConfig().PROMOTERS_ENABLED.Get()) return;
-
-  // Ideally, this wouldn't be hard-coded
-  static cInstruction promoter_inst = m_world->GetHardwareManager().GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
-
-  int old_size = base_promoter_weights.GetSize();
-  cur_promoter_weights.Resize(_genome.GetSize());
-  base_promoter_weights.Resize(_genome.GetSize());
-  promoter_repression.Resize(_genome.GetSize());
-  promoter_activation.Resize(_genome.GetSize());
-
-  // Only change new regions of the genome (that might have been allocated since this was last called)
-  for ( int i = (clear ? 0 : old_size); i<_genome.GetSize(); i++)
-  {
-    base_promoter_weights[i] = 1;
-    promoter_repression[i] = 0;
-    promoter_activation[i] = 0;
-
-    // Now change the weights at instructions that are not promoters if called for
-    if ( _genome[i] != promoter_inst)
-    {
-      base_promoter_weights[i] *= m_world->GetConfig().PROMOTER_BG_STRENGTH.Get(); 
-    }
-    cur_promoter_weights[i] = base_promoter_weights[i];
-  }
-}
-
-
-void cPhenotype::DecayAllPromoterRegulation()
-{
-  for ( int i=0; i<cur_promoter_weights.GetSize(); i++)
-  {
-    promoter_activation[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
-    promoter_repression[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
-    cur_promoter_weights[i] = base_promoter_weights[i] * exp((1+promoter_activation[i])*log(2.0)) / exp((1+promoter_repression[i])*log(2.0));
-
-  }
-}
-
-void cPhenotype::RegulatePromoter(const int i, const bool up )
-{
-  // Make sure we were initialized
-  assert ( (promoter_activation.GetSize() > 0) && (promoter_activation.GetSize() > 0) );
-  
-  if (up) {
-    promoter_activation[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
-    promoter_activation[i] += m_world->GetConfig().REGULATION_STRENGTH.Get(); 
-  }
-  else {
-    promoter_repression[i] *= (1 - m_world->GetConfig().REGULATION_DECAY_FRAC.Get());
-    promoter_repression[i] += m_world->GetConfig().REGULATION_STRENGTH.Get(); 
-  }
-  
-  cur_promoter_weights[i] = base_promoter_weights[i] * exp((1+promoter_activation[i])*log(2.0)) / exp((1+promoter_repression[i])*log(2.0));
-}
-
 // Save the current fitness and reset relevant parts of the phenotype
 void cPhenotype::NewTrial()
 { 

Modified: branches/energy/source/main/cPhenotype.h
===================================================================
--- branches/energy/source/main/cPhenotype.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cPhenotype.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -121,12 +121,6 @@
   tArray<int> cur_sense_count;                // Total times resource combinations have been sensed; @JEB 
   tArray<double> sensed_resources;            // Resources which the organism has sensed; @JEB 
   tArray<double> cur_task_time;    // Time at which each task was last performed; WRE 03-18-07
-  tArray<cCodeLabel> active_transposons;      // Transposons that are active; @JEB
-  tArray<double> base_promoter_weights;       // Baseline chance of starting execution from each position; @JEB 
-  tArray<double> cur_promoter_weights;        // Current of starting execution from each position, adjusted for regulation; @JEB 
-  tArray<double> promoter_activation;         // Amount of positive regulation in play at each site; @JEB 
-  tArray<double> promoter_repression;         // Amount of negative regulation in play at each site; @JEB 
-  bool promoter_last_inst_terminated;         // Did termination occur when executing the last instruction; @JEB
   tHashTable<void*, cTaskState*> m_task_states;
   tArray<double> cur_trial_fitnesses;         // Fitnesses of various trials.; @JEB
   tArray<double> cur_trial_bonuses;           // Bonuses of various trials.; @JEB
@@ -306,8 +300,6 @@
   const tArray<int>& GetCurInstCount() const { assert(initialized == true); return cur_inst_count; }
   const tArray<int>& GetCurSenseCount() const { assert(initialized == true); return cur_sense_count; }
   double GetSensedResource(int _in) { assert(initialized == true); return sensed_resources[_in]; }
-  const tArray<cCodeLabel>& GetActiveTransposons() { assert(initialized == true); return active_transposons; }
-  const tArray<double>& GetCurPromoterWeights() { assert(initialized == true); return cur_promoter_weights; }
   
   void  NewTrial(); //Save the current fitness, and reset the bonus. @JEB
   void  TrialDivideReset(const cGenome & _genome); //Subset of resets specific to division not done by NewTrial. @JEB
@@ -435,12 +427,6 @@
   void IncCurInstCount(int _inst_num)  { assert(initialized == true); cur_inst_count[_inst_num]++; } 
   void DecCurInstCount(int _inst_num)  { assert(initialized == true); cur_inst_count[_inst_num]--; } 
   
-  void ActivateTransposon(cCodeLabel & in_label) { assert(initialized == true); active_transposons.Push(in_label); }
-  void SetupPromoterWeights(const cGenome & _genome, const bool clear = false);
-  void DecayAllPromoterRegulation();
-  void RegulatePromoter(const int i, const bool up );
-  void SetTerminated(bool _in) { promoter_last_inst_terminated = _in; }
-
   void IncNumThreshGbDonations() { assert(initialized == true); num_thresh_gb_donations++; }
   void IncNumQuantaThreshGbDonations() { assert(initialized == true); num_quanta_thresh_gb_donations++; }
 

Modified: branches/energy/source/main/cPopulationInterface.cc
===================================================================
--- branches/energy/source/main/cPopulationInterface.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cPopulationInterface.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -29,6 +29,7 @@
 #include "cHardwareManager.h"
 #include "cOrganism.h"
 #include "cOrgSinkMessage.h"
+#include "cOrgMessage.h"
 #include "cPopulation.h"
 #include "cPopulationCell.h"
 #include "cStats.h"
@@ -233,3 +234,21 @@
 {
   return m_world->GetTestOnDivide();
 }
+
+
+/*! Send a message to the faced organism, failing if this cell does not have 
+neighbors or if the cell currently faced is not occupied. */
+bool cPopulationInterface::SendMessage(cOrgMessage& msg) {
+  cPopulationCell& cell = m_world->GetPopulation().GetCell(m_cell_id);
+  assert(cell.IsOccupied()); // This organism; sanity.
+  cPopulationCell* rcell = cell.ConnectionList().GetFirst();
+  assert(rcell != NULL); // Cells should never be null.
+
+  // Fail if the cell we're facing is not occupied.
+  if(!rcell->IsOccupied())
+    return false;
+  cOrganism* recvr = rcell->GetOrganism();
+  assert(recvr != NULL);
+  recvr->ReceiveMessage(msg);
+  return true;
+}

Modified: branches/energy/source/main/cPopulationInterface.h
===================================================================
--- branches/energy/source/main/cPopulationInterface.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cPopulationInterface.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -37,6 +37,7 @@
 #endif
 
 class cPopulation;
+class cOrgMessage;
 
 
 class cPopulationInterface : public cOrgInterface
@@ -84,6 +85,8 @@
   bool InjectParasite(cOrganism* parent, const cCodeLabel& label, const cGenome& injected_code);
   bool UpdateMerit(double new_merit);
   bool TestOnDivide();
+  //! Send a message to the faced organism.
+  bool SendMessage(cOrgMessage& msg);
 };
 
 

Modified: branches/energy/source/main/cStats.cc
===================================================================
--- branches/energy/source/main/cStats.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cStats.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -34,6 +34,8 @@
 #include "cWorld.h"
 #include "cWorldDriver.h"
 #include "tDataEntry.h"
+#include "cOrgMessage.h"
+#include "cOrgMessagePredicate.h"
 
 #include "functions.h"
 
@@ -1026,3 +1028,55 @@
   }
   df.Endl();
 }
+
+
+/*! This method is called whenever an organism successfully sends a message.  Success,
+in this case, means that the message has been delivered to the receive buffer of
+the organism that this message was sent to. */
+void cStats::SentMessage(const cOrgMessage& msg)
+{
+  // Check to see if this message matches any of our predicates.
+  for(message_pred_ptr_list::iterator i=m_message_predicates.begin(); 
+      i!=m_message_predicates.end(); ++i) {
+    (**i)(msg); // Predicate is responsible for tracking info about messages.
+  }  
+}
+
+
+/*! This method adds a message predicate to the list of all predicates.  Each predicate
+in the list is evaluated for every sent message.
+
+NOTE: cStats does NOT own the predicate pointer!  (It DOES NOT delete them!)
+*/
+void cStats::AddMessagePredicate(cOrgMessagePredicate* predicate)
+{
+  m_message_predicates.push_back(predicate);
+}
+
+
+/*! This method prints information contained within all active message predicates.
+
+about  specific messages that are being tracked.
+The messages that are being tracked are setup by the AddTrackedMessage method below.
+
+The format of this log file is:
+<update> \
+<predicate>:{<cell_id>,...}...
+*/
+void cStats::PrintPredicatedMessages(const cString& filename)
+{
+  cDataFile& df = m_world->GetDataFile(filename);
+  df.WriteColumnDesc("update [update]");
+  df.WriteColumnDesc("predicate:{p_info,...}...");
+  df.FlushComments();
+  
+  df.WriteAnonymous(m_update);
+  std::ofstream& out = df.GetOFStream();
+  for(message_pred_ptr_list::iterator i=m_message_predicates.begin();
+      i!=m_message_predicates.end(); ++i) {
+    (*i)->Print(out);
+    (*i)->Reset();
+    out << " ";
+  }
+  df.Endl();  
+}

Modified: branches/energy/source/main/cStats.h
===================================================================
--- branches/energy/source/main/cStats.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cStats.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -29,6 +29,7 @@
 #include <cassert>
 #include <fstream>
 #include <iostream>
+#include <vector>
 
 #ifndef defs_h
 #include "defs.h"
@@ -65,6 +66,8 @@
 class cGenotype;
 class cInjectGenotype;
 class cWorld;
+class cOrgMessage;
+class cOrgMessagePredicate;
 
 class cStats
 {
@@ -612,6 +615,26 @@
   void PrintSenseData(const cString& filename);
   void PrintSenseExeData(const cString& filename);
   void PrintSleepData(const cString& filename);
+  
+  // -------- Messaging support --------
+public:
+  //! Type for a list of pointers to message predicates.
+  typedef std::vector<cOrgMessagePredicate*> message_pred_ptr_list;
+  
+  //! Called for every message successfully sent anywhere in the population.
+  void SentMessage(const cOrgMessage& msg);
+  //! Adds a predicate that will be evaluated for each message.
+  void AddMessagePredicate(cOrgMessagePredicate* predicate);
+  //! Prints information regarding messages that "passed" their predicate.
+  void PrintPredicatedMessages(const cString& filename);
+
+protected:
+  /*! List of all active message predicates.  The idea here is that the predicates,
+  rather than cStats / cOrgMessage / etc., do the tracking of particular messages
+  of interest. */
+  message_pred_ptr_list m_message_predicates;
+  // -------- End messaging support --------
+  
 };
 
 

Modified: branches/energy/source/main/cTaskContext.h
===================================================================
--- branches/energy/source/main/cTaskContext.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/main/cTaskContext.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -37,6 +37,9 @@
 #ifndef tHashTable_h
 #include "tHashTable.h"
 #endif
+#ifndef cOrganism_h
+#include "cOrganism.h"
+#endif
 
 class cTaskEntry;
 class cTaskState;
@@ -63,11 +66,13 @@
   cTaskEntry* m_task_entry;
   tHashTable<void*, cTaskState*>* m_task_states;
 
+  cOrganism* m_organism;
+  
 public:
   cTaskContext(cOrgInterface* interface, const tBuffer<int>& inputs, const tBuffer<int>& outputs,
                const tList<tBuffer<int> >& other_inputs, const tList<tBuffer<int> >& other_outputs,
                bool in_net_valid, int in_net_completed, bool in_on_divide = false,
-               tBuffer<int>* in_received_messages = NULL)
+               tBuffer<int>* in_received_messages = NULL, cOrganism* org=0)
     : m_interface(interface)
     , m_input_buffer(inputs)
     , m_output_buffer(outputs)
@@ -80,6 +85,7 @@
     , m_on_divide(in_on_divide)
     , m_task_entry(NULL)
     , m_task_states(NULL)
+    , m_organism(org)
   {
 	  m_task_value = 0;
   }
@@ -102,6 +108,8 @@
   inline cTaskEntry* GetTaskEntry() { return m_task_entry; }
   
   inline void SetTaskStates(tHashTable<void*, cTaskState*>* states) { m_task_states = states; }
+
+  inline cOrganism* GetOrganism() { return m_organism; }
   
   inline cTaskState* GetTaskState()
   {

Modified: branches/energy/source/script/ASTree.cc
===================================================================
--- branches/energy/source/script/ASTree.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/ASTree.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -38,14 +38,17 @@
 
 void cASTFunctionDefinition::Accept(cASTVisitor& visitor) { visitor.visitFunctionDefinition(*this); }
 void cASTVariableDefinition::Accept(cASTVisitor& visitor) { visitor.visitVariableDefinition(*this); }
+void cASTVariableDefinitionList::Accept(cASTVisitor& visitor) { visitor.visitVariableDefinitionList(*this); }
 
 void cASTExpressionBinary::Accept(cASTVisitor& visitor) { visitor.visitExpressionBinary(*this); }
 void cASTExpressionUnary::Accept(cASTVisitor& visitor) { visitor.visitExpressionUnary(*this); }
 
+void cASTArgumentList::Accept(cASTVisitor& visitor) { visitor.visitArgumentList(*this); }
 void cASTFunctionCall::Accept(cASTVisitor& visitor) { visitor.visitFunctionCall(*this); }
 void cASTLiteral::Accept(cASTVisitor& visitor) { visitor.visitLiteral(*this); }
 void cASTLiteralArray::Accept(cASTVisitor& visitor) { visitor.visitLiteralArray(*this); }
 void cASTVariableReference::Accept(cASTVisitor& visitor) { visitor.visitVariableReference(*this); }
+void cASTUnpackTarget::Accept(cASTVisitor& visitor) { visitor.visitUnpackTarget(*this); }
 
 
 cASTStatementList::~cASTStatementList()

Modified: branches/energy/source/script/ASTree.h
===================================================================
--- branches/energy/source/script/ASTree.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/ASTree.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -37,6 +37,9 @@
 #ifndef tList_h
 #include "tList.h"
 #endif
+#ifndef tManagedPointerArray_h
+#include "tManagedPointerArray.h"
+#endif
 
 
 class cASTVisitor;
@@ -68,6 +71,7 @@
 // ---------------------------------------------------------------------------------------------------------------------
 
 class cASTAssignment;
+class cASTArgumentList;
 
 class cASTReturnStatement;
 class cASTStatementList;
@@ -78,6 +82,7 @@
 
 class cASTFunctionDefinition;
 class cASTVariableDefinition;
+class cASTVariableDefinitionList;
 
 class cASTExpressionBinary;
 class cASTExpressionUnary;
@@ -86,6 +91,7 @@
 class cASTLiteral;
 class cASTLiteralArray;
 class cASTVariableReference;
+class cASTUnpackTarget;
 
 
 
@@ -110,7 +116,24 @@
 };
 
 
+class cASTArgumentList : public cASTNode
+{
+private:
+  tList<cASTNode> m_nodes;
+  
+public:
+  cASTArgumentList() { ; }
+  ~cASTArgumentList() { ; }
+  
+  inline void AddNode(cASTNode* n) { m_nodes.PushRear(n); }
+  inline tListIterator<cASTNode> Iterator() { return tListIterator<cASTNode>(m_nodes); }
+  
+  void Accept(cASTVisitor& visitor);
+};
 
+
+
+
 // --------  Block Nodes  --------
 
 class cASTReturnStatement : public cASTNode
@@ -168,20 +191,48 @@
 
 class cASTIfBlock : public cASTNode
 {
+public:
+  class cElseIf
+  {
+    friend class cASTIfBlock;
+  private:
+    cASTNode* m_expr;
+    cASTNode* m_code;
+    
+    cElseIf(cASTNode* expr, cASTNode* code) : m_expr(expr), m_code(code) { ; }
+    
+  public:
+      cASTNode* GetCondition() { return m_expr; }
+    cASTNode* GetCode() { return m_code; }
+  };
+  
 private:
   cASTNode* m_expr;
   cASTNode* m_code;
   cASTNode* m_else;
   
+  tList<cElseIf> m_elifs;
+  
 public:
   cASTIfBlock(cASTNode* expr, cASTNode* code) : m_expr(expr), m_code(code), m_else(NULL) { ; }
-  ~cASTIfBlock() { delete m_expr; delete m_code; delete m_else; }
+  ~cASTIfBlock()
+  {
+    delete m_expr;
+    delete m_code;
+    delete m_else;
+    cElseIf* elif = NULL;
+    while ((elif = m_elifs.Pop())) delete elif;
+  }
+
   
   inline cASTNode* GetCondition() { return m_expr; }
   inline cASTNode* GetCode() { return m_code; }
+  inline void AddElseIf(cASTNode* expr, cASTNode* code) { m_elifs.PushRear(new cElseIf(expr, code)); }
+  inline tListIterator<cElseIf> ElseIfIterator() { return tListIterator<cElseIf>(m_elifs); }
   inline void SetElseCode(cASTNode* code) { m_else = code; }
   inline cASTNode* GetElseCode() { return m_else; }
   
+  inline bool HasElseIfs() const { return (m_elifs.GetSize()); }
   inline bool HasElse() const { return (m_else); }
   
   void Accept(cASTVisitor& visitor);
@@ -214,16 +265,16 @@
 private:
   ASType_t m_type;
   cString m_name;
-  cASTNode* m_args;
+  cASTVariableDefinitionList* m_args;
   cASTNode* m_code;
   
 public:
-  cASTFunctionDefinition(ASType_t type, const cString& name, cASTNode* args)
+  cASTFunctionDefinition(ASType_t type, const cString& name, cASTVariableDefinitionList* args)
     : m_type(type), m_name(name), m_args(args), m_code(NULL) { ; }
   
   inline ASType_t GetType() { return m_type; }
   inline const cString& GetName() { return m_name; }
-  inline cASTNode* GetArguments() { return m_args; }
+  inline cASTVariableDefinitionList* GetArguments() { return m_args; }
   
   inline void SetCode(cASTNode* code) { m_code = code; }
   inline cASTNode* GetCode() { return m_code; }
@@ -240,22 +291,44 @@
   ASType_t m_type;
   cString m_var;
   cASTNode* m_assign;
+  cASTArgumentList* m_dims;
   
 public:
-  cASTVariableDefinition(ASType_t type, const cString& var) : m_type(type), m_var(var), m_assign(NULL) { ; }
-  ~cASTVariableDefinition() { delete m_assign; }
+  cASTVariableDefinition(ASType_t type, const cString& var) : m_type(type), m_var(var), m_assign(NULL), m_dims(NULL) { ; }
+  ~cASTVariableDefinition() { delete m_assign; delete m_dims; }
   
   inline ASType_t GetType() { return m_type; }
   inline const cString& GetVariable() { return m_var; }
   inline void SetAssignmentExpression(cASTNode* assign) { delete m_assign; m_assign = assign; }
   inline cASTNode* GetAssignmentExpression() { return m_assign; }
+  inline void SetDimensions(cASTArgumentList* dims) { delete m_dims; m_dims = dims; }
+  inline cASTArgumentList* GetDimensions() { return m_dims; }
   
   void Accept(cASTVisitor& visitor);
 };
 
 
+class cASTVariableDefinitionList : public cASTNode
+{
+private:
+  tList<cASTVariableDefinition> m_nodes;
+  
+public:
+  cASTVariableDefinitionList() { ; }
+  ~cASTVariableDefinitionList() { ; }
+  
+  inline void AddNode(cASTVariableDefinition* n) { m_nodes.PushRear(n); }
+  inline tListIterator<cASTVariableDefinition> Iterator() { return tListIterator<cASTVariableDefinition>(m_nodes); }
+  
+  inline int GetSize() const { return m_nodes.GetSize(); }
+  
+  void Accept(cASTVisitor& visitor);
+};
 
 
+
+
+
 // --------  Expression Operation Nodes  --------
 
 class cASTExpressionBinary : public cASTNode
@@ -303,10 +376,19 @@
 class cASTFunctionCall : public cASTNode
 {
 private:
+  cASTNode* m_target;
+  cASTArgumentList* m_args;
   
 public:
-  cASTFunctionCall() { ; }
+  cASTFunctionCall(cASTNode* target) : m_target(target), m_args(NULL) { ; }
+  ~cASTFunctionCall() { delete m_args; }
   
+  cASTNode* GetTarget() { return m_target; }
+  void SetArguments(cASTArgumentList* args) { delete m_args; m_args = args; }
+  cASTArgumentList* GetArguments() { return m_args; }
+  
+  bool HasArguments() const { return (m_args); }
+  
   void Accept(cASTVisitor& visitor);
 };
 
@@ -330,16 +412,15 @@
 class cASTLiteralArray : public cASTNode
 {
 private:
-  ASType_t m_type;
   cASTNode* m_value;
+  bool m_is_matrix;
   
 public:
-  cASTLiteralArray(ASType_t t, cASTNode* v) : m_type(t), m_value(v) { ; }
-  ~cASTLiteralArray() { delete m_value; }
+  cASTLiteralArray(cASTNode* v, bool is_mat) : m_value(v), m_is_matrix(is_mat) { ; }
+  ~cASTLiteralArray() { delete m_value; }  
   
-  
-  inline ASType_t GetType() { return m_type; }
   inline cASTNode* GetValue() { return m_value; }
+  inline bool IsMatrix() const { return m_is_matrix; }
   
   void Accept(cASTVisitor& visitor);
 };
@@ -359,4 +440,27 @@
 };
 
 
+class cASTUnpackTarget : public cASTNode
+{
+private:
+  tManagedPointerArray<cString> m_nodes;
+  bool m_last_wild;
+  bool m_last_named;
+  
+public:
+  cASTUnpackTarget() : m_last_wild(false), m_last_named(false) { ; }
+  ~cASTUnpackTarget() { ; }
+  
+  inline void AddVar(const cString& name) { m_nodes.Push(name); }
+  inline int GetSize() const { return m_nodes.GetSize(); }
+  inline const cString& GetVar(int idx) const { return m_nodes[idx]; }
+  
+  inline void SetLastNamed() { m_last_wild = true; m_last_named = true; }
+  inline void SetLastWild() { m_last_wild = true; m_last_named = false; }
+  
+  
+  void Accept(cASTVisitor& visitor);
+};
+
+
 #endif

Modified: branches/energy/source/script/AvidaScript.h
===================================================================
--- branches/energy/source/script/AvidaScript.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/AvidaScript.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -79,27 +79,21 @@
   
   AS_TOKEN_CMD_IF, // 41
   AS_TOKEN_CMD_ELSE,
-  AS_TOKEN_CMD_ENDIF,
+  AS_TOKEN_CMD_ELSEIF,
+  AS_TOKEN_CMD_WHILE,
+  AS_TOKEN_CMD_FOREACH,
+  AS_TOKEN_CMD_FUNCTION,
   
-  AS_TOKEN_CMD_WHILE, // 44
-  AS_TOKEN_CMD_ENDWHILE,
+  AS_TOKEN_CMD_RETURN, // 47
   
-  AS_TOKEN_CMD_FOREACH, // 46
-  AS_TOKEN_CMD_ENDFOREACH,
+  AS_TOKEN_ID, // 48
   
-  AS_TOKEN_CMD_FUNCTION, // 48
-  AS_TOKEN_CMD_ENDFUNCTION,
-  
-  AS_TOKEN_CMD_RETURN, // 50
-  
-  AS_TOKEN_ID, // 51
-  
-  AS_TOKEN_FLOAT, // 52
+  AS_TOKEN_FLOAT, // 49
   AS_TOKEN_INT,
   AS_TOKEN_STRING,
   AS_TOKEN_CHAR,
   
-  AS_TOKEN_UNKNOWN, // 56
+  AS_TOKEN_UNKNOWN, // 53
   AS_TOKEN_INVALID
 } ASToken_t;
 

Modified: branches/energy/source/script/cASTDumpVisitor.cc
===================================================================
--- branches/energy/source/script/cASTDumpVisitor.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/cASTDumpVisitor.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -54,6 +54,7 @@
     case AS_TOKEN_OP_MUL:       cout << '*';  break;
     case AS_TOKEN_OP_DIV:       cout << '/';  break;
     case AS_TOKEN_OP_MOD:       cout << '%';  break;
+    case AS_TOKEN_DOT:          cout << '.';  break;
     case AS_TOKEN_OP_EQ:        cout << "=="; break;
     case AS_TOKEN_OP_LE:        cout << "<="; break;
     case AS_TOKEN_OP_GE:        cout << ">="; break;
@@ -62,6 +63,7 @@
     case AS_TOKEN_OP_NEQ:       cout << "!="; break;
     case AS_TOKEN_ARR_RANGE:    cout << ':';  break;
     case AS_TOKEN_ARR_EXPAN:    cout << '^';  break;
+    case AS_TOKEN_IDX_OPEN:     cout << "[]"; break;
     default:                    cout << '?';  break;
   }
 }
@@ -114,7 +116,7 @@
 
 void cASTDumpVisitor::visitStatementList(cASTStatementList& node)
 {
-  tListIterator<cASTNode> it(node.Iterator());
+  tListIterator<cASTNode> it = node.Iterator();
   
   cASTNode* stmt = NULL;
   while ((stmt = it.Next())) {
@@ -169,6 +171,32 @@
   node.GetCode()->Accept(*this);
   m_depth--;
   
+  if (node.HasElseIfs()) {
+    tListIterator<cASTIfBlock::cElseIf> it = node.ElseIfIterator();
+    cASTIfBlock::cElseIf* elif = NULL;
+    while ((elif = it.Next())) {
+      indent();
+      cout << "elseif:" << endl;
+
+      m_depth++;
+      indent();
+      cout << "condition:" << endl;
+      
+      m_depth++;
+      elif->GetCondition()->Accept(*this);
+      m_depth--;
+      
+      indent();
+      cout << "do:" << endl;
+      
+      m_depth++;
+      elif->GetCode()->Accept(*this);
+      m_depth--;
+      
+      m_depth--;
+    }
+  }
+  
   if (node.HasElse()) {
     indent();
     cout << "else:" << endl;
@@ -212,13 +240,24 @@
 {
   indent();
   cout << (node.IsDefinition() ? "":"@") << "function: " << mapType(node.GetType()) << " " << node.GetName() << "(";
+  if (node.GetArguments()->GetSize()) { 
+    cout << endl;
+    node.GetArguments()->Accept(*this);
+    indent();
+  }
+  cout << ")" << endl;
   
-  cout << ")" << endl;
+  indent();
+  cout << "{" << endl;
+  
   if (node.IsDefinition()) {
     m_depth++;
     node.GetCode()->Accept(*this);
     m_depth--;
   }
+
+  indent();
+  cout << "}" << endl;
 }
 
 
@@ -240,7 +279,19 @@
 }
 
 
+void cASTDumpVisitor::visitVariableDefinitionList(cASTVariableDefinitionList& node)
+{
+  m_depth++;
+  
+  tListIterator<cASTVariableDefinition> it = node.Iterator();
+  cASTNode* val = NULL;
+  while ((val = it.Next())) val->Accept(*this);
+  
+  m_depth--;
+}
 
+
+
 void cASTDumpVisitor::visitExpressionBinary(cASTExpressionBinary& node)
 {
   m_depth++;
@@ -269,10 +320,40 @@
 }
 
 
+void cASTDumpVisitor::visitArgumentList(cASTArgumentList& node)
+{
+  m_depth++;
+  
+  tListIterator<cASTNode> it = node.Iterator();
+  cASTNode* val = NULL;
+  while ((val = it.Next())) val->Accept(*this);
+  
+  m_depth--;
+}
 
 void cASTDumpVisitor::visitFunctionCall(cASTFunctionCall& node)
 {
+  indent();
+  cout << "call:" << endl;
+  m_depth++;
   
+  indent();
+  cout << "target:" << endl;
+  
+  m_depth++;
+  node.GetTarget()->Accept(*this);
+  m_depth--;
+  
+  if (node.HasArguments()) {
+    indent();
+    cout << "with:" << endl;
+    
+    m_depth++;
+    node.GetArguments()->Accept(*this);
+    m_depth--;
+  }
+  
+  m_depth--;
 }
 
 
@@ -285,7 +366,16 @@
 
 void cASTDumpVisitor::visitLiteralArray(cASTLiteralArray& node)
 {
-
+  indent();
+  if (node.IsMatrix()) cout << "$";
+  cout << "{" << endl;
+  m_depth++;
+  
+  node.GetValue()->Accept(*this);
+  
+  m_depth--;
+  indent();
+  cout << "}" << endl;
 }
 
 
@@ -294,3 +384,9 @@
   indent();
   cout << node.GetName() << endl;
 }
+
+
+void cASTDumpVisitor::visitUnpackTarget(cASTUnpackTarget& node)
+{
+  // @todo
+}

Modified: branches/energy/source/script/cASTDumpVisitor.h
===================================================================
--- branches/energy/source/script/cASTDumpVisitor.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/cASTDumpVisitor.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -49,14 +49,17 @@
   
   void visitFunctionDefinition(cASTFunctionDefinition&);
   void visitVariableDefinition(cASTVariableDefinition&);
+  void visitVariableDefinitionList(cASTVariableDefinitionList&);
   
   void visitExpressionBinary(cASTExpressionBinary&);
   void visitExpressionUnary(cASTExpressionUnary&);
   
+  void visitArgumentList(cASTArgumentList&);
   void visitFunctionCall(cASTFunctionCall&);
   void visitLiteral(cASTLiteral&);
   void visitLiteralArray(cASTLiteralArray&);
   void visitVariableReference(cASTVariableReference&);
+  void visitUnpackTarget(cASTUnpackTarget&);
 
 private:
   inline void indent();

Modified: branches/energy/source/script/cASTVisitor.h
===================================================================
--- branches/energy/source/script/cASTVisitor.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/cASTVisitor.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -48,14 +48,17 @@
   
   virtual void visitFunctionDefinition(cASTFunctionDefinition&) = 0;
   virtual void visitVariableDefinition(cASTVariableDefinition&) = 0;
+  virtual void visitVariableDefinitionList(cASTVariableDefinitionList&) = 0;
 
   virtual void visitExpressionBinary(cASTExpressionBinary&) = 0;
   virtual void visitExpressionUnary(cASTExpressionUnary&) = 0;
 
+  virtual void visitArgumentList(cASTArgumentList&) = 0;
   virtual void visitFunctionCall(cASTFunctionCall&) = 0;
   virtual void visitLiteral(cASTLiteral&) = 0;
   virtual void visitLiteralArray(cASTLiteralArray&) = 0;
   virtual void visitVariableReference(cASTVariableReference&) = 0;
+  virtual void visitUnpackTarget(cASTUnpackTarget&) = 0;
 };
 
 #endif

Modified: branches/energy/source/script/cLexer.l
===================================================================
--- branches/energy/source/script/cLexer.l	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/cLexer.l	2007-08-28 18:53:26 UTC (rev 2022)
@@ -83,7 +83,7 @@
 \^          return AS_TOKEN_ARR_EXPAN;
 \.\.        return AS_TOKEN_ARR_WILD;
 
-\?          return AS_TOKEN_MAT_MODIFY;    // Matrix Modifier
+\$          return AS_TOKEN_MAT_MODIFY;    // Matrix Modifier
 
 array       return AS_TOKEN_TYPE_ARRAY;    // Built-in Types
 char        return AS_TOKEN_TYPE_CHAR;
@@ -93,19 +93,13 @@
 string      return AS_TOKEN_TYPE_STRING;
 void        return AS_TOKEN_TYPE_VOID;
 
-if          return AS_TOKEN_CMD_IF;        // If Blocks
+if          return AS_TOKEN_CMD_IF;        // Blocks
 else        return AS_TOKEN_CMD_ELSE;
-endif       return AS_TOKEN_CMD_ENDIF;
+elseif      return AS_TOKEN_CMD_ELSEIF;
+while       return AS_TOKEN_CMD_WHILE;
+foreach     return AS_TOKEN_CMD_FOREACH;
+function    return AS_TOKEN_CMD_FUNCTION;
 
-while       return AS_TOKEN_CMD_WHILE;     // While Blocks
-endwhile    return AS_TOKEN_CMD_ENDWHILE;
-
-foreach     return AS_TOKEN_CMD_FOREACH;   // Foreach Blocks
-endforeach  return AS_TOKEN_CMD_ENDFOREACH;
-
-function    return AS_TOKEN_CMD_FUNCTION;  // Function Blocks
-endfunction return AS_TOKEN_CMD_ENDFUNCTION;
-
 return      return AS_TOKEN_CMD_RETURN;
 
 ([a-zA-Z]|_+[a-zA-Z])[a-zA-Z0-9_]*  return AS_TOKEN_ID;      // Identifiers

Modified: branches/energy/source/script/cParser.cc
===================================================================
--- branches/energy/source/script/cParser.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/cParser.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -159,16 +159,12 @@
 
  loose_block: ARR_OPEN statement_list ARR_CLOSE
  
- if_block: CMD_IF PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ENDIF
-         | CMD_IF PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ELSE lineterm statement_list CMD_ENDIF
-         | CMD_IF PREC_OPEN expr PREC_CLOSE loose_block CMD_ENDIF
-         | CMD_IF PREC_OPEN expr PREC_CLOSE loose_block CMD_ELSE loose_block CMD_ENDIF
+ if_block: CMD_IF PREC_OPEN expr PREC_CLOSE loose_block
+         | CMD_IF PREC_OPEN expr PREC_CLOSE loose_block CMD_ELSE loose_block
  
- while_block: CMD_WHILE PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ENDWHILE
-            | CMD_WHILE PREC_OPEN expr PREC_CLOSE loose_block
+ while_block: CMD_WHILE PREC_OPEN expr PREC_CLOSE loose_block
  
- foreach_block: CMD_FOREACH type_def ID PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ENDFOREACH
-              | CMD_FOREACH type_def ID PREC_OPEN expr PREC_CLOSE loose_block
+ foreach_block: CMD_FOREACH type_def ID PREC_OPEN expr PREC_CLOSE loose_block
 
  var_declare: type_def ID
             | type_def ID ASSIGN expr
@@ -183,8 +179,7 @@
                    | 
  
  declare_function: REF CMD_FUNCTION type_any ID PREC_OPEN var_declare_list PREC_CLOSE
- define_function: CMD_FUNCTION type_any ID PREC_OPEN var_declare_list PREC_CLOSE lineterm statement_list CMD_ENDFUNCTION
-                | CMD_FUNCTION type_any ID PREC_OPEN var_declare_list PREC_CLOSE loose_block
+ define_function: CMD_FUNCTION type_any ID PREC_OPEN var_declare_list PREC_CLOSE loose_block
  
  return_stmt: CMD_RETURN expr
 
@@ -195,7 +190,7 @@
 #define PARSE_TRACE(x) { std::cerr << "trace: " << x << std::endl; }
 
 #define PARSE_ERROR(x) reportError(AS_PARSE_ERR_ ## x, __LINE__)
-#define PARSE_UNEXPECT() { if (currentToken()) { PARSE_ERROR(UNEXPECTED_TOKEN); } else { PARSE_ERROR(EOF); } }
+#define PARSE_UNEXPECT() { if (currentToken()) { PARSE_ERROR(UNEXPECTED_TOKEN); } else { PARSE_ERROR(EOF); } return NULL; }
 
 #define TOKEN(x) AS_TOKEN_ ## x
 
@@ -219,7 +214,7 @@
   
   m_tree = parseStatementList();
 
-  if (!m_eof) PARSE_UNEXPECT();
+  if (!m_eof && m_success) PARSE_ERROR(UNEXPECTED_TOKEN);
   if (!m_tree) PARSE_ERROR(EMPTY);
 
   delete m_lexer;
@@ -270,43 +265,45 @@
 cASTNode* cParser::parseArrayUnpack()
 {
   PARSE_TRACE("parseArrayUnpack");
-  cASTNode* au = NULL;
   
-  if (nextToken() != TOKEN(ID)) {
-    PARSE_ERROR(UNEXPECTED_TOKEN);
-    return au;
-  }
+  if (nextToken() != TOKEN(ID)) PARSE_UNEXPECT();
+
+  tAutoRelease<cASTUnpackTarget> ut(new cASTUnpackTarget());
+  (*ut).AddVar(currentText());
   
   while (nextToken()) {
     if (currentToken() == TOKEN(COMMA)) {
       nextToken();
       if (currentToken() == TOKEN(ID)) {
+        (*ut).AddVar(currentText());
         continue;
       } else if (currentToken() == TOKEN(ARR_WILD)) {
+        (*ut).SetLastWild();
         break;
       } else {
         PARSE_ERROR(UNEXPECTED_TOKEN);
         break;
       }
     } else if (currentToken() == TOKEN(ARR_WILD)) {
+      (*ut).SetLastNamed();
       break;
     } else {
       PARSE_UNEXPECT();
-      break;      
     }
   }
 
-  return au;
+  return ut.Release();
 }
 
-cASTNode* cParser::parseArgumentList()
+cASTArgumentList* cParser::parseArgumentList()
 {
   PARSE_TRACE("parseArgumentList");
-  cASTNode* al = NULL;
-  
-  parseExpression();
+  cASTArgumentList* al = new cASTArgumentList();
+
+  al->AddNode(parseExpression());
   while (currentToken() == TOKEN(COMMA)) {
-    parseExpression();
+    nextToken(); // consume ','
+    al->AddNode(parseExpression());
   }
   
   return al;
@@ -326,71 +323,55 @@
   return an;
 }
 
-cASTNode* cParser::parseCallExpression()
+cASTNode* cParser::parseCallExpression(cASTNode* target, bool required)
 {
   PARSE_TRACE("parseCallExpression");
-  cASTNode* ce = NULL;
+  tAutoRelease<cASTNode> ce(target);
   
-  nextToken();
-  
   bool eoe = false;
   while (!eoe) {
     switch (currentToken()) {
       case TOKEN(DOT):
-        if (nextToken() != TOKEN(ID)) {
-          PARSE_UNEXPECT();
-          return ce;
-        }
+        if (nextToken() != TOKEN(ID)) PARSE_UNEXPECT();
+        ce.Set(new cASTExpressionBinary(TOKEN(DOT), ce.Release(), new cASTVariableReference(currentText())));
+        nextToken(); // consume id
         break;
       case TOKEN(PREC_OPEN):
-        if (nextToken() != TOKEN(PREC_CLOSE)) parseArgumentList();
-        if (currentToken() != TOKEN(PREC_CLOSE)) {
-          PARSE_UNEXPECT();
-          return ce;   
-        }
-        switch (nextToken()) {
-          case TOKEN(IDX_OPEN):
-            do {
-              parseIndexExpression();
-            } while (nextToken() == TOKEN(IDX_OPEN));
-            break;
-          case TOKEN(DOT):
-            continue;
-
-          default:
-            eoe = true;
-        }
+        cASTFunctionCall* fc = new cASTFunctionCall(ce.Release());
+        ce.Set(fc);
+        if (nextToken() != TOKEN(PREC_CLOSE)) fc->SetArguments(parseArgumentList());
+        if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
+        nextToken(); // consume ')'
+        
+        // If the next token is not a continued call expression, then set the end-of-expression flag
+        if (currentToken() != TOKEN(IDX_OPEN) && currentToken() != TOKEN(DOT)) eoe = true;
         break;
       case TOKEN(IDX_OPEN):
         do {
-          parseIndexExpression();
+          nextToken(); // consume '['
+          ce.Set(new cASTExpressionBinary(TOKEN(IDX_OPEN), ce.Release(), parseExpression()));
+          if (currentToken() != TOKEN(IDX_CLOSE)) PARSE_UNEXPECT();
         } while (nextToken() == TOKEN(IDX_OPEN));
-
+        break;
       default:
-        PARSE_UNEXPECT();
-        return ce;
+        if (required) { PARSE_UNEXPECT(); }
+        else eoe = true;
     }
   }
     
-  return ce;
+  return ce.Release();
 }
 
-cASTNode* cParser::parseCodeBlock(bool& loose)
+cASTNode* cParser::parseCodeBlock()
 {
   PARSE_TRACE("parseCodeBlock");
-  cASTNode* cb = NULL;
 
-  if (currentToken() == TOKEN(ARR_OPEN)) {
-    loose = true;
-    cb = parseLooseBlock();
-  } else if (currentToken() == TOKEN(SUPPRESS) || currentToken() == TOKEN(ENDL)) {
-    cb = parseStatementList();
-  } else {
-    PARSE_UNEXPECT();
-    return cb;
-  }
+  // Swallow all newlines and suppress tokens
+  while (currentToken() == TOKEN(ENDL) || currentToken() == TOKEN(SUPPRESS)) nextToken();
   
-  return cb;  
+  if (currentToken() == TOKEN(ARR_OPEN)) return parseLooseBlock();
+  
+  PARSE_UNEXPECT();
 }
 
 cASTNode* cParser::parseExpression()
@@ -567,107 +548,71 @@
 cASTNode* cParser::parseExprP6()
 {
   PARSE_TRACE("parseExprP6");
-  cASTNode* expr = NULL;
+  tAutoRelease<cASTNode> expr;
   
+  bool is_matrix = false;
+  
   switch (currentToken()) {
     case TOKEN(FLOAT):
-      expr = new cASTLiteral(AS_TYPE_FLOAT, currentText());
+      expr.Set(new cASTLiteral(AS_TYPE_FLOAT, currentText()));
       break;
     case TOKEN(INT):
-      expr = new cASTLiteral(AS_TYPE_INT, currentText());
+      expr.Set(new cASTLiteral(AS_TYPE_INT, currentText()));
       break;
     case TOKEN(CHAR):
-      expr = new cASTLiteral(AS_TYPE_CHAR, currentText());
+      expr.Set(new cASTLiteral(AS_TYPE_CHAR, currentText()));
       break;
     case TOKEN(STRING):
-      expr = new cASTLiteral(AS_TYPE_STRING, currentText());
+      expr.Set(new cASTLiteral(AS_TYPE_STRING, currentText()));
       break;
     case TOKEN(ID):
       if (peekToken() == TOKEN(PREC_OPEN)) {
-        nextToken();
-        if (nextToken() != TOKEN(PREC_CLOSE)) parseArgumentList();
-        if (currentToken() != TOKEN(PREC_CLOSE)) {
-          PARSE_UNEXPECT();
-          return expr;
-        }
-        expr = new cASTFunctionCall(); // @todo
+        cASTNode* vr = new cASTVariableReference(currentText());
+        nextToken(); // consume id token
+        cASTFunctionCall* fc = new cASTFunctionCall(vr);
+        expr.Set(fc);
+        if (nextToken() != TOKEN(PREC_CLOSE)) fc->SetArguments(parseArgumentList());        
+        if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
       } else {
         expr = new cASTVariableReference(currentText());
       }
       break;
     case TOKEN(PREC_OPEN):
-      nextToken();
-      expr = parseExpression();
-      if (!expr) PARSE_ERROR(NULL_EXPR);
-      if (currentToken() != TOKEN(PREC_CLOSE)) {
-        PARSE_UNEXPECT();
-        return expr;
-      }
+      nextToken(); // consume '('
+      expr.Set(parseExpression());
+      if (expr.IsNull()) PARSE_ERROR(NULL_EXPR);
+      if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
       break;
     case TOKEN(MAT_MODIFY):
-      if (nextToken() != TOKEN(ARR_OPEN)) {
-        PARSE_UNEXPECT();
-        return expr;
-      }
+      if (nextToken() != TOKEN(ARR_OPEN)) PARSE_UNEXPECT();
+      is_matrix = true;
     case TOKEN(ARR_OPEN):
-      if (nextToken() != TOKEN(ARR_CLOSE)) parseArgumentList();
-      if (currentToken() != TOKEN(ARR_CLOSE)) {
-        PARSE_UNEXPECT();
-        return expr;
-      }
-      // @todo - return literal array
+      if (nextToken() != TOKEN(ARR_CLOSE)) expr.Set(parseArgumentList());
+      if (currentToken() != TOKEN(ARR_CLOSE)) PARSE_UNEXPECT();
+      expr.Set(new cASTLiteralArray(expr.Release(), is_matrix));
       break;
       
     case TOKEN(OP_BIT_NOT):
     case TOKEN(OP_LOGIC_NOT):
     case TOKEN(OP_SUB):
       ASToken_t op = currentToken();
-      expr = new cASTExpressionUnary(op, parseExpression());
-      if (!expr) PARSE_ERROR(NULL_EXPR);
+      cASTNode* r = parseExpression();
+      if (!r) {
+        PARSE_ERROR(NULL_EXPR);
+        return NULL;
+      }
+      expr.Set(new cASTExpressionUnary(op, r));
       nextToken();
-      return expr;
+      return expr.Release();
       
     default:
-      break;
+      return NULL;
   }
 
   nextToken();
-  if (expr) expr = parseExprP6_Index(expr);
-  return expr;
-}
-
-cASTNode* cParser::parseExprP6_Index(cASTNode* l)
-{
-  PARSE_TRACE("parseExprP6_Index");
-  while (currentToken() == TOKEN(DOT) || currentToken() == TOKEN(IDX_OPEN)) {
-    if (currentToken() == TOKEN(DOT)) {
-      if (nextToken() != TOKEN(ID)) {
-        PARSE_UNEXPECT();
-        return l;
-      }
-      if (peekToken() == TOKEN(PREC_OPEN)) {
-        nextToken();
-        if (nextToken() != TOKEN(PREC_CLOSE)) parseArgumentList();
-        if (currentToken() != TOKEN(PREC_CLOSE)) {
-          PARSE_UNEXPECT();
-          return l;
-        }
-        // @todo
-      } else {
-        // @todo
-      }
-    } else { // IDX_OPEN:
-      nextToken();
-      parseExpression();
-      if (currentToken() != TOKEN(IDX_CLOSE)) {
-        PARSE_UNEXPECT();
-        return l;
-      }
-      // @todo
-    }
-  }
+  if (!expr.IsNull()) return parseCallExpression(expr.Release());
   
-  return l;
+  return NULL;
 }
 
 
@@ -719,31 +664,23 @@
   }
   nextToken(); // consume ')'
   
-  bool loose = false;
-  tAutoRelease<cASTNode> code(parseCodeBlock(loose));
-  if (!loose && currentToken() != TOKEN(CMD_ENDFOREACH)) PARSE_UNEXPECT();
-  if (!loose) nextToken(); // consume 'endforeach'
+  cASTNode* code = parseCodeBlock();
   
-  return new cASTForeachBlock(var.Release(), expr.Release(), code.Release());
+  return new cASTForeachBlock(var.Release(), expr.Release(), code);
 }
 
 cASTNode* cParser::parseFunctionDefine()
 {
   PARSE_TRACE("parseFunctionDefine");
-  cASTFunctionDefinition* fd = parseFunctionHeader(false);
+  cASTFunctionDefinition* fd = parseFunctionHeader();
   
-  bool loose = false;
-  fd->SetCode(parseCodeBlock(loose));
-  if (!loose && currentToken() != TOKEN(CMD_ENDFUNCTION)) {
-    PARSE_UNEXPECT();
-    return fd;
-  }
-  if (!loose) nextToken();
+  // If the returned function definition is valid, parse the body
+  if (fd) fd->SetCode(parseCodeBlock());
 
   return fd;
 }
 
-cASTFunctionDefinition* cParser::parseFunctionHeader(bool declare)
+cASTFunctionDefinition* cParser::parseFunctionHeader()
 {
   PARSE_TRACE("parseFunctionHeader");
   
@@ -757,215 +694,160 @@
     case TOKEN(TYPE_STRING): type = AS_TYPE_STRING; break;
     case TOKEN(TYPE_VOID):   type = AS_TYPE_VOID;   break;
     case TOKEN(ID):
-      if (peekToken() != TOKEN(REF)) {
-        nextToken();
-        PARSE_UNEXPECT();
-        return NULL;
-      }
+      if (nextToken() != TOKEN(REF)) PARSE_UNEXPECT();
       type = AS_TYPE_OBJECT_REF;
       break;
       
     default:
       PARSE_UNEXPECT();
-      return NULL;
   }
   
   if (nextToken() != TOKEN(ID)) {
     PARSE_UNEXPECT();
-    return NULL;
   }
   cString name(currentText());
   
-  if (nextToken() != TOKEN(PREC_OPEN)) {
-    PARSE_UNEXPECT();
-    return NULL;
-  }
+  if (nextToken() != TOKEN(PREC_OPEN)) PARSE_UNEXPECT();
   
-  tAutoRelease<cASTNode> args;
-  if (nextToken() != TOKEN(PREC_CLOSE)) {
-    if (declare) {
-      args = parseVarDeclareList();
-    } else {
-      args = parseArgumentList();
-    }
-  }
+  tAutoRelease<cASTVariableDefinitionList> args;
+  if (nextToken() != TOKEN(PREC_CLOSE)) args.Set(parseVariableDefinitionList());
+  if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
+  nextToken(); // consume ')'
   
-  if (currentToken() != TOKEN(PREC_CLOSE)) {
-    PARSE_UNEXPECT();
-    return NULL;    
-  }
-  
-  nextToken();
-  
   return new cASTFunctionDefinition(type, name, args.Release());
 }
 
 cASTNode* cParser::parseIDStatement()
 {
   PARSE_TRACE("parseIDStatement");
-  cASTNode* is = NULL;
   
   switch (peekToken()) {
     case TOKEN(ASSIGN):
-      is = parseAssignment();
+      return parseAssignment();
       break;
     case TOKEN(DOT):
     case TOKEN(IDX_OPEN):
     case TOKEN(PREC_OPEN):
-      is = parseCallExpression();
+      cASTNode* target = new cASTVariableReference(currentText());
+      nextToken(); // consume id
+      return parseCallExpression(target, true);
       break;
     case TOKEN(REF):
-      is = parseVarDeclare();
+      return parseVariableDefinition();
       break;
       
     default:
       PARSE_UNEXPECT();
-      break;
-  }      
-  
-  return is;
+  }
 }
 
 cASTNode* cParser::parseIfStatement()
 {
   PARSE_TRACE("parseIfStatement");
   
-  if (nextToken() != TOKEN(PREC_OPEN)) {
-    PARSE_UNEXPECT();
-    return NULL;
-  }
+  if (nextToken() != TOKEN(PREC_OPEN)) PARSE_UNEXPECT();
   
   nextToken();
   tAutoRelease<cASTNode> cond(parseExpression());
-  
-  if (currentToken() != TOKEN(PREC_CLOSE)) {
-    PARSE_UNEXPECT();
-    return NULL;
-  }
+  if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
   nextToken();
   
-  bool loose = false;
-  cASTIfBlock* is = new cASTIfBlock(cond.Release(), parseCodeBlock(loose));
+  tAutoRelease<cASTIfBlock> is(new cASTIfBlock(cond.Release(), parseCodeBlock()));
 
+  while (currentToken() == TOKEN(CMD_ELSEIF)) {
+    
+    if (nextToken() != TOKEN(PREC_OPEN)) PARSE_UNEXPECT();
+    nextToken(); // consume '('
+    
+    tAutoRelease<cASTNode> elifcond(parseExpression());
+    
+    if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
+    nextToken(); // consume ')'
+    
+    cASTNode* elifcode = parseCodeBlock();
+    (*is).AddElseIf(elifcond.Release(), elifcode);
+  }
+  
   if (currentToken() == TOKEN(CMD_ELSE)) {
     nextToken(); // consume 'else'
-    loose = false;
-    tAutoRelease<cASTNode> code(parseCodeBlock(loose));
-    if (!loose && currentToken() != TOKEN(CMD_ENDIF)) {
-      PARSE_UNEXPECT();
-      return is;
-    }
-    if (!loose) nextToken();
-    is->SetElseCode(code.Release());
-  } else if (!loose && currentToken() != TOKEN(CMD_ENDIF)) {
-    PARSE_UNEXPECT();
-    return is;
-  } else if (!loose) {
-    nextToken(); // consume 'endif'
+    cASTNode* code = parseCodeBlock();
+    (*is).SetElseCode(code);
   }
   
-  return is;
+  return is.Release();
 }
 
-cASTNode* cParser::parseIndexExpression()
-{
-  PARSE_TRACE("parseIndexExpression");
-  cASTNode* ie = NULL;
-  
-  nextToken();
-  parseExpression();
-  if (currentToken() != TOKEN(IDX_CLOSE)) {
-    PARSE_UNEXPECT();
-  }
-  
-  return ie;
-}
-
 cASTNode* cParser::parseLooseBlock()
 {
   PARSE_TRACE("parseLooseBlock");
   nextToken();
-  cASTNode* sl = parseStatementList();
-  if (currentToken() != TOKEN(ARR_CLOSE)) {
-    PARSE_UNEXPECT();
-  }
-  nextToken();
-  return sl;
+  tAutoRelease<cASTNode> sl(parseStatementList());
+  
+  if (currentToken() != TOKEN(ARR_CLOSE)) PARSE_UNEXPECT();
+  nextToken(); // consume '}'
+
+  return sl.Release();
 }
 
 cASTNode* cParser::parseRefStatement()
 {
   PARSE_TRACE("parseRefStatement");
-  cASTNode* rs = NULL;
 
   switch (nextToken()) {
     case TOKEN(ARR_OPEN):
-      rs = parseArrayUnpack();
-      break;
+      return parseArrayUnpack();
     case TOKEN(CMD_FUNCTION):
-      rs = parseFunctionHeader();
-      break;
+      return parseFunctionHeader();
     default:
       PARSE_UNEXPECT();
   }
-  
-  return rs;
 }
 
 cASTNode* cParser::parseReturnStatement()
 {
   PARSE_TRACE("parseReturnStatement");
   
-  nextToken();
+  nextToken(); // consume 'return'
   cASTNode* rs = new cASTReturnStatement(parseExpression());
   
   return rs;
 }
 
 
-#define CHECK_LINETERM() { if (!checkLineTerm(sl)) return sl; }
 cASTNode* cParser::parseStatementList()
 {
   PARSE_TRACE("parseStatementList");
-  cASTStatementList* sl = new cASTStatementList();
+  tAutoRelease<cASTStatementList> sl(new cASTStatementList());
   
-  cASTNode* node = NULL;
+  tAutoRelease<cASTNode> node;
 
   while (nextToken()) {
     switch (currentToken()) {
       case TOKEN(ARR_OPEN):
-        node = parseLooseBlock();
-        CHECK_LINETERM();
+        node.Set(parseLooseBlock());
         break;
       case TOKEN(CMD_IF):
-        node = parseIfStatement();
-        CHECK_LINETERM();
+        node.Set(parseIfStatement());
         break;
       case TOKEN(CMD_FOREACH):
-        node = parseForeachStatement();
-        CHECK_LINETERM();
+        node.Set(parseForeachStatement());
         break;
       case TOKEN(CMD_FUNCTION):
-        node = parseFunctionDefine();
-        CHECK_LINETERM();
+        node.Set(parseFunctionDefine());
         break;
       case TOKEN(CMD_RETURN):
-        node = parseReturnStatement();
-        CHECK_LINETERM();
+        node.Set(parseReturnStatement());
         break;
       case TOKEN(CMD_WHILE):
-        node = parseWhileStatement();
-        CHECK_LINETERM();
+        node.Set(parseWhileStatement());
         break;
       case TOKEN(ENDL):
         continue;
       case TOKEN(ID):
-        node = parseIDStatement();
-        CHECK_LINETERM();
+        node.Set(parseIDStatement());
         break;
       case TOKEN(REF):
-        node = parseRefStatement();
-        CHECK_LINETERM();
+        node.Set(parseRefStatement());
         break;
       case TOKEN(SUPPRESS):
         continue;
@@ -975,32 +857,35 @@
       case TOKEN(TYPE_INT):
       case TOKEN(TYPE_MATRIX):
       case TOKEN(TYPE_STRING):
-        node = parseVarDeclare();
-        CHECK_LINETERM();
+        node.Set(parseVariableDefinition());
         break;
         
       default:
-        return sl;
+        return sl.Release();
     }
     
-    if (node == NULL) {
+    if (node.IsNull()) {
       // Some error has occured, so terminate early
       if (m_success) PARSE_ERROR(INTERNAL); // Should not receive a null response without an error flag
-      break;
     }
-    sl->AddNode(node);
+    
+    if (currentToken() == TOKEN(SUPPRESS)) {
+      // @todo - mark output as suppressed
+    } else if (currentToken() != TOKEN(ENDL)) {
+      PARSE_ERROR(UNTERMINATED_EXPR);
+    }
+
+    (*sl).AddNode(node.Release());
   }
   
   if (!currentToken()) m_eof = true;
-  return sl;
+  return sl.Release();
 }
-#undef CHECK_LINETERM()
 
 
-cASTNode* cParser::parseVarDeclare()
+cASTVariableDefinition* cParser::parseVariableDefinition()
 {
-  PARSE_TRACE("parseVarDeclare");
-  cASTVariableDefinition* vd = NULL;
+  PARSE_TRACE("parseVariableDefinition");
   
   ASType_t vtype = AS_TYPE_INVALID;
   switch (currentToken()) {
@@ -1011,105 +896,73 @@
     case TOKEN(TYPE_MATRIX): vtype = AS_TYPE_MATRIX; break;
     case TOKEN(TYPE_STRING): vtype = AS_TYPE_STRING; break;
     case TOKEN(ID):
-      if (nextToken() != TOKEN(REF)) {
-        PARSE_UNEXPECT();
-        return vd;
-      }
+      if (nextToken() != TOKEN(REF)) PARSE_UNEXPECT();
+
       vtype = AS_TYPE_OBJECT_REF;
       break;
       
     default:
       PARSE_UNEXPECT();
-      return vd;
   }
   
-  if (nextToken() != TOKEN(ID)) {
-    PARSE_UNEXPECT();
-    return vd;
-  }
+  if (nextToken() != TOKEN(ID)) PARSE_UNEXPECT();
   
-  vd = new cASTVariableDefinition(vtype, currentText());
+  tAutoRelease<cASTVariableDefinition> vd(new cASTVariableDefinition(vtype, currentText()));
   
   switch (nextToken()) {
     case TOKEN(ASSIGN):
       nextToken();
       cASTNode* expr = parseExpression();
-      vd->SetAssignmentExpression(expr);
+      (*vd).SetAssignmentExpression(expr);
       break;
     case TOKEN(PREC_OPEN):
-      // @todo - array/matrix size declaration
-      if (nextToken() != TOKEN(PREC_CLOSE)) parseArgumentList();
-      if (currentToken() != TOKEN(PREC_CLOSE)) {
-        PARSE_UNEXPECT();
-        return vd;
-      }
+      if (nextToken() != TOKEN(PREC_CLOSE)) (*vd).SetDimensions(parseArgumentList());
+      if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
+      nextToken(); // consume ')'
       break;
       
     default:
       break;
   }
   
-  return vd;
+  return vd.Release();
 }
 
-cASTNode* cParser::parseVarDeclareList()
+cASTVariableDefinitionList* cParser::parseVariableDefinitionList()
 {
-  PARSE_TRACE("parseVarDeclareList");
-  cASTNode* vl = NULL;
+  PARSE_TRACE("parseVariableDefinitionList");
+  tAutoRelease<cASTVariableDefinitionList> vl(new cASTVariableDefinitionList());
+ 
+  cASTVariableDefinition* vd = parseVariableDefinition();
+  if (!vd) return NULL;
   
-  parseVarDeclare();
+  (*vl).AddNode(vd);
   while (currentToken() == TOKEN(COMMA)) {
-    parseVarDeclare();
+    nextToken(); // consume ','
+    vd = parseVariableDefinition();
+    if (!vd) return NULL;
+    (*vl).AddNode(vd);
   }
   
-  return vl;
+  return vl.Release();
 }
 
 cASTNode* cParser::parseWhileStatement()
 {
   PARSE_TRACE("parseWhileStatement");
   
-  if (nextToken() != TOKEN(PREC_OPEN)) {
-    PARSE_UNEXPECT();
-    return NULL;
-  }
+  if (nextToken() != TOKEN(PREC_OPEN)) PARSE_UNEXPECT();
   
   nextToken();
   tAutoRelease<cASTNode> cond(parseExpression());
-  
-  if (currentToken() != TOKEN(PREC_CLOSE)) {
-    PARSE_UNEXPECT();
-    return NULL;
-  }
+  if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
   nextToken();
   
-  bool loose = false;
-  tAutoRelease<cASTNode> code(parseCodeBlock(loose));
-  if (!loose && currentToken() != TOKEN(CMD_ENDWHILE)) {
-    PARSE_UNEXPECT();
-    return NULL;
-  }
-  if (!loose) nextToken();
-  
-  return new cASTWhileBlock(cond.Release(), code.Release());
+  cASTNode* code = parseCodeBlock();
+  return new cASTWhileBlock(cond.Release(), code);
 }
 
 
-bool cParser::checkLineTerm(cASTNode* node)
-{
-  PARSE_TRACE("checkLineTerm");
-  if (currentToken() == TOKEN(SUPPRESS)) {
-    // @todo - mark output as suppressed
-    return true;
-  } else if (currentToken() == TOKEN(ENDL)) {
-    return true;
-  }
-  
-  PARSE_ERROR(UNTERMINATED_EXPR);
-  return false;
-}
-
-
 void cParser::reportError(ASParseError_t err, const int line)
 {
 #define ERR_ENDL "  (cParser.cc:" << line << ")" << std::endl
@@ -1145,6 +998,7 @@
       break;
     case AS_PARSE_ERR_INTERNAL:
       std::cerr << "internal parser error at cParser.cc:" << line << std::endl;
+      break;
     case AS_PARSE_ERR_UNKNOWN:
     default:
       std::cerr << "parse error" << std::endl;

Modified: branches/energy/source/script/cParser.h
===================================================================
--- branches/energy/source/script/cParser.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/script/cParser.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -83,17 +83,17 @@
   
   
 private:
-  inline ASToken_t currentToken() { return m_cur_tok; }
+  inline ASToken_t currentToken() const { return m_cur_tok; }
   ASToken_t nextToken();
   ASToken_t peekToken();
   
   const cString& currentText();
   
-  cASTNode* parseArgumentList();
+  cASTArgumentList* parseArgumentList();
   cASTNode* parseArrayUnpack();
   cASTNode* parseAssignment();
-  cASTNode* parseCallExpression();
-  cASTNode* parseCodeBlock(bool& loose);
+  cASTNode* parseCallExpression(cASTNode* target, bool required = false);
+  cASTNode* parseCodeBlock();
   cASTNode* parseExpression();
   cASTNode* parseExprP0();
   cASTNode* parseExprP1();
@@ -105,7 +105,7 @@
   cASTNode* parseExprP6_Index(cASTNode* l);
   cASTNode* parseForeachStatement();
   cASTNode* parseFunctionDefine();
-  cASTFunctionDefinition* parseFunctionHeader(bool declare = true);
+  cASTFunctionDefinition* parseFunctionHeader();
   cASTNode* parseIDStatement();
   cASTNode* parseIfStatement();
   cASTNode* parseIndexExpression();
@@ -113,12 +113,10 @@
   cASTNode* parseRefStatement();
   cASTNode* parseReturnStatement();
   cASTNode* parseStatementList();
-  cASTNode* parseVarDeclare();
-  cASTNode* parseVarDeclareList();
+  cASTVariableDefinition* parseVariableDefinition();
+  cASTVariableDefinitionList* parseVariableDefinitionList();
   cASTNode* parseWhileStatement();
   
-  bool checkLineTerm(cASTNode* node);
-  
   void reportError(ASParseError_t err, const int line);
 };
 

Modified: branches/energy/source/tools/cRandom.cc
===================================================================
--- branches/energy/source/tools/cRandom.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/tools/cRandom.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -10,7 +10,7 @@
 
 #include "cRandom.h"
 
-#include "platform.h"
+#include "../platform/platform.h"
 #include "tArray.h"
 
 #if AVIDA_PLATFORM(WINDOWS)

Modified: branches/energy/source/tools/cRandom.h
===================================================================
--- branches/energy/source/tools/cRandom.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/tools/cRandom.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -12,7 +12,7 @@
 #define cRandom_h
 
 #ifndef cMutex_h
-#include "cMutex.h"
+#include "../platform/cMutex.h"
 #endif
 
 #if USE_tMemTrack

Modified: branches/energy/source/tools/tArray.h
===================================================================
--- branches/energy/source/tools/tArray.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/tools/tArray.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -75,27 +75,23 @@
     return *this;
   }
 
-  tArray operator+(const tArray in) const {
-    tArray tmp(0);
-    for(int i = 0; i < GetSize(); i++) {
-      tmp.Push(m_data[i]);
-    }
-    
-    for(int i = 0; i < in.GetSize(); i++) {
-      tmp.Push(in[i]);
-    }
+  inline tArray operator+(const tArray& in_array) const {
+    tArray tmp(m_size + in_array.m_size);
+    for(int i = 0; i < m_size; i++) tmp[i] = m_data[i];
+    for(int i = 0; i < in_array.GetSize(); i++) tmp[i + m_size] = in_array[i];
+
     return tmp;
   }
   
-  tArray Subset(int start, int end) {
+  inline tArray Subset(int start, int end) const {
     assert(start <= end);
     assert(0 <= start && start <= GetSize());
     assert(0 <= end && end <= GetSize());
     
-    tArray tmp(0);
-    for(int i = start; i < end; i++) {
-      tmp.Push(m_data[i]);
-    }
+    const int new_size = end - start;
+    tArray tmp(end - start);
+    for(int i = 0; i < new_size; i++) tmp[i] = m_data[i + start];
+
     return tmp;
   }
   

Modified: branches/energy/source/tools/tAutoRelease.h
===================================================================
--- branches/energy/source/tools/tAutoRelease.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/tools/tAutoRelease.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -43,6 +43,11 @@
   inline void Set(T* value) { delete m_value; m_value = value; }
   inline tAutoRelease<T>& operator=(T* value) { delete m_value; m_value = value; return *this; }
   
+  inline bool IsNull() const { return !(m_value); }
+  
+  //! Access the contents
+  inline T& operator*() { return *m_value; }
+  
   //! Take control of the contents
   inline T* Release() { T* value = m_value; m_value = NULL; return value; }
 };

Modified: branches/energy/source/tools/tList.h
===================================================================
--- branches/energy/source/tools/tList.h	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/tools/tList.h	2007-08-28 18:53:26 UTC (rev 2022)
@@ -92,9 +92,9 @@
   const tList<T> & GetConstList() { return list; }
   const tListNode<T> * GetConstNode() { return node; }
 public:
-    explicit tListIterator(tList<T> & _list);
-  explicit tListIterator(tList<T> & _list, tListNode<T> * start_node);
-  explicit tListIterator(tListIterator<T>& _tli);
+  explicit tListIterator(tList<T>& _list);
+  explicit tListIterator(tList<T>& _list, tListNode<T>* start_node);
+  tListIterator(const tListIterator<T>& _tli);
   ~tListIterator();
   
   void Set(tListNode<T> * in_node) { node = in_node; }
@@ -562,7 +562,7 @@
   list.AddIterator(this);
 }
 
-template <class T> tListIterator<T>::tListIterator(tListIterator<T>& _tli)
+template <class T> tListIterator<T>::tListIterator(const tListIterator<T>& _tli)
 : tBaseIterator<T>(), list(_tli.list), node(_tli.node)
 {
 	list.AddIterator(this);

Modified: branches/energy/source/utils/process_map/Makefile
===================================================================
--- branches/energy/source/utils/process_map/Makefile	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/utils/process_map/Makefile	2007-08-28 18:53:26 UTC (rev 2022)
@@ -30,7 +30,7 @@
 SRC		= process_map.cc		../../tools/cFile.cc  \
 		../../tools/cInitFile.cc	../../tools/cString.cc  \
 		../../tools/cStringList.cc  ../../tools/cStringIterator.cc  \
-		../../tools/cRandom.cc
+		../../tools/cRandom.cc ../../tools/cStringUtil.o
 
 ### List Object Files (for each source file there is a object file) ###########
 OBJ	 	= $(SRC:.cc=.o)

Copied: branches/energy/source/utils/process_map/mypcolor.m (from rev 2021, development/source/utils/process_map/mypcolor.m)
===================================================================
--- branches/energy/source/utils/process_map/mypcolor.m	                        (rev 0)
+++ branches/energy/source/utils/process_map/mypcolor.m	2007-08-28 18:53:26 UTC (rev 2022)
@@ -0,0 +1,65 @@
+function h = pcolor(x,y,c)
+%PCOLOR Pseudocolor (checkerboard) plot.
+%   PCOLOR(C) is a pseudocolor or "checkerboard" plot of matrix C.
+%   The values of the elements of C specify the color in each
+%   cell of the plot. In the default shading mode, 'faceted',
+%   each cell has a constant color and the last row and column of
+%   C are not used. With shading('interp'), each cell has color
+%   resulting from bilinear interpolation of the color at its 
+%   four vertices and all elements of C are used. 
+%   The smallest and largest elements of C are assigned the first and
+%   last colors given in the color table; colors for the remainder of the 
+%   elements in C are determined by table-lookup within the remainder of 
+%   the color table.
+%   PCOLOR(X,Y,C), where X and Y are vectors or matrices, makes a
+%   pseudocolor plot on the grid defined by X and Y.  X and Y could 
+%   define the grid for a "disk", for example.
+%   PCOLOR is really a SURF with its view set to directly above.
+%   PCOLOR returns a handle to a SURFACE object.
+%
+%   See also CAXIS, SURF, MESH, IMAGE, SHADING.
+
+%-------------------------------
+%   Additional details:
+%
+%
+%   PCOLOR sets the View property of the SURFACE object to directly 
+%   overhead.
+%
+%   If the NextPlot axis property is REPLACE (HOLD is off), PCOLOR resets 
+%   all axis properties, except Position, to their default values
+%   and deletes all axis children (line, patch, surf, image, and 
+%   text objects).  View is set to [0 90].
+
+%   Copyright (c) 1984-96 by The MathWorks, Inc.
+%   $Revision: 5.3 $  $Date: 1996/01/01 23:34:43 $
+
+%   J.N. Little 1-5-92
+
+if nargin < 1
+    error('Too few input arguments.');
+elseif nargin > 4
+    error('Too many input arguments.')
+end
+
+cax = gca;
+hold_state = ishold;
+
+if nargin == 1
+    hh = surface(zeros(size(x)),x);
+    [m,n] = size(x);
+    lims = [ 1 n 1 m];
+elseif nargin == 3
+    hh = surface(x,y,zeros(size(c)),c);
+    lims = [min(min(x)) max(max(x)) min(min(y)) max(max(y))];
+else
+    error('Must have one or three input arguments.')
+end
+if ~hold_state
+    set(cax,'View',[0 90]);
+    set(cax,'Box','on');
+    axis(lims);
+end
+if nargout == 1
+    h = hh;
+end

Copied: branches/energy/source/utils/process_map/pcolor_all.m (from rev 2021, development/source/utils/process_map/pcolor_all.m)
===================================================================
--- branches/energy/source/utils/process_map/pcolor_all.m	                        (rev 0)
+++ branches/energy/source/utils/process_map/pcolor_all.m	2007-08-28 18:53:26 UTC (rev 2022)
@@ -0,0 +1,10 @@
+function pcolor_all(matrix)
+%PCOLOR_ALL  Make a psudo-color plot of 'matrix' including all columns and rows
+%  Works by appending a row and column of zeros 'matrix'
+%
+%  By default, does 'shading flat'
+
+[tmp1, tmp2] = size(matrix);
+matrix = [ matrix zeros(tmp1,1) ; zeros(1,tmp2+1) ];
+mypcolor(matrix)
+shading flat

Modified: branches/energy/source/utils/process_map/process_map.cc
===================================================================
--- branches/energy/source/utils/process_map/process_map.cc	2007-08-28 18:50:39 UTC (rev 2021)
+++ branches/energy/source/utils/process_map/process_map.cc	2007-08-28 18:53:26 UTC (rev 2022)
@@ -119,8 +119,8 @@
   if (type == 0) filename.Set("grid_genotype_id.%d.dat", (UD_step + UD_start));
   else filename.Set("grid_phenotype_id.%d.dat", (UD_step + UD_start));
   cInitFile file1(filename);
-  file1.Load();
-  file1.Close();
+  // file1.Load();
+  // file1.Close();
 
   const int height = file1.GetNumLines();
   const int width = file1.GetLine(0).CountNumWords();
@@ -165,18 +165,19 @@
     else filename.Set("grid_phenotype_id.%d.dat", update);
     
     cInitFile file(filename);
-    file.Load();
+    // file.Load();
 
     // Load in this file...
     cString cur_line;
+    int cur_line_num = 0;
     for (int pos = 0; pos < num_cells; pos++) {
-      if (cur_line.GetSize() == 0) cur_line = file.GetNextLine();
+      if (cur_line.GetSize() == 0) cur_line = file.GetLine(cur_line_num++);
       const int cur_id = cur_line.PopWord().AsInt();
       if (cur_id > max_id) max_id = cur_id;
       grid_matrix(file_id, pos) = cur_id;
     }
 
-    file.Close();
+    // file.Close();
   }
   cerr << endl << "LOADING COMPLETE" << endl;
   cerr << "Max ID = " << max_id << endl;




More information about the Avida-cvs mailing list