[Avida-SVN] r2431 - development/source/script

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Thu Mar 6 21:03:09 PST 2008


Author: brysonda
Date: 2008-03-07 00:03:09 -0500 (Fri, 07 Mar 2008)
New Revision: 2431

Modified:
   development/source/script/cDirectInterpretASTVisitor.cc
   development/source/script/cDirectInterpretASTVisitor.h
Log:
AS:
Fix assignment to handle global scope properly.
Implement
- return statements
- if and while blocks
- function calls
- variable definitions
- variable references
Add wrapping Interpret method that handles global return value.


Modified: development/source/script/cDirectInterpretASTVisitor.cc
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.cc	2008-03-06 22:09:04 UTC (rev 2430)
+++ development/source/script/cDirectInterpretASTVisitor.cc	2008-03-07 05:03:09 UTC (rev 2431)
@@ -50,24 +50,36 @@
   for (int i = 0; i < m_global_symtbl->GetNumVariables(); i++) m_call_stack[i].as_string = NULL;
 }
 
+
+int cDirectInterpretASTVisitor::Interpret(cASTNode* node)
+{
+  node->Accept(*this);
+  
+  if (m_has_returned) return asInt(m_rtype, m_rvalue, *node);
+
+  return 0;
+}
+
+
 void cDirectInterpretASTVisitor::visitAssignment(cASTAssignment& node)
 {
   cSymbolTable* symtbl = node.IsVarGlobal() ? m_global_symtbl : m_cur_symtbl;
-  int vid = node.GetVarID();
+  int sp = node.IsVarGlobal() ? 0 : m_sp;
+  int var_id = node.GetVarID();
   
   node.GetExpression()->Accept(*this);
   
-  switch (symtbl->GetVariableType(vid)) {
+  switch (symtbl->GetVariableType(var_id)) {
     case TYPE(ARRAY):       INTERPRET_ERROR(INTERNAL); // @TODO - assignment
-    case TYPE(BOOL):        m_call_stack[m_sp + vid].as_bool = asBool(m_rtype, m_rvalue, node); break;
-    case TYPE(CHAR):        m_call_stack[m_sp + vid].as_char = asChar(m_rtype, m_rvalue, node); break;
-    case TYPE(FLOAT):       m_call_stack[m_sp + vid].as_float = asFloat(m_rtype, m_rvalue, node); break;
-    case TYPE(INT):         m_call_stack[m_sp + vid].as_int = asInt(m_rtype, m_rvalue, node); break;
+    case TYPE(BOOL):        m_call_stack[sp + var_id].as_bool = asBool(m_rtype, m_rvalue, node); break;
+    case TYPE(CHAR):        m_call_stack[sp + var_id].as_char = asChar(m_rtype, m_rvalue, node); break;
+    case TYPE(FLOAT):       m_call_stack[sp + var_id].as_float = asFloat(m_rtype, m_rvalue, node); break;
+    case TYPE(INT):         m_call_stack[sp + var_id].as_int = asInt(m_rtype, m_rvalue, node); break;
     case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
     case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
     case TYPE(STRING):
-      delete m_call_stack[m_sp + vid].as_string;
-      m_call_stack[m_sp + vid].as_string = asString(m_rtype, m_rvalue, node);
+      delete m_call_stack[sp + var_id].as_string;
+      m_call_stack[sp + var_id].as_string = asString(m_rtype, m_rvalue, node);
       break;
       
     default:
@@ -78,8 +90,7 @@
 
 void cDirectInterpretASTVisitor::visitReturnStatement(cASTReturnStatement& node)
 {
-  // @TODO - handle return statement
-  
+  node.GetExpression()->Accept(*this);
   m_has_returned = true;
 }
 
@@ -98,19 +109,43 @@
 
 void cDirectInterpretASTVisitor::visitForeachBlock(cASTForeachBlock& node)
 {
-  // @TODO - handle foreach block
+  //int var_id = node.GetVariable()->GetVarID();
+  
+  // @TODO - foreach block
 }
 
 
 void cDirectInterpretASTVisitor::visitIfBlock(cASTIfBlock& node)
 {
-  // @TODO - handle if block
+  node.GetCondition()->Accept(*this);
+  
+  if (asBool(m_rtype, m_rvalue, node)) {
+    node.GetCode()->Accept(*this);
+  } else {
+    bool exec = false;
+    tListIterator<cASTIfBlock::cElseIf> it = node.ElseIfIterator();
+    cASTIfBlock::cElseIf* ei = NULL;
+    while ((ei = it.Next())) {
+      ei->GetCondition()->Accept(*this);
+      if (asBool(m_rtype, m_rvalue, node)) {
+        exec = true;
+        ei->GetCode()->Accept(*this);
+        break;
+      }
+    }
+    
+    if (!exec && node.HasElse()) node.GetElseCode()->Accept(*this);
+  }
 }
 
 
 void cDirectInterpretASTVisitor::visitWhileBlock(cASTWhileBlock& node)
 {
-  // @TODO - handle while block
+  node.GetCondition()->Accept(*this);
+  while (asBool(m_rtype, m_rvalue, node)) {
+    node.GetCode()->Accept(*this);
+    node.GetCondition()->Accept(*this);
+  }
 }
 
 
@@ -123,7 +158,30 @@
 
 void cDirectInterpretASTVisitor::visitVariableDefinition(cASTVariableDefinition& node)
 {
-  // @TODO - handle variable definition
+  if (node.GetAssignmentExpression()) {
+    int var_id = node.GetVarID();
+    
+    node.GetAssignmentExpression()->Accept(*this);
+    
+    switch (m_cur_symtbl->GetVariableType(var_id)) {
+      case TYPE(ARRAY):       INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(BOOL):        m_call_stack[m_sp + var_id].as_bool = asBool(m_rtype, m_rvalue, node); break;
+      case TYPE(CHAR):        m_call_stack[m_sp + var_id].as_char = asChar(m_rtype, m_rvalue, node); break;
+      case TYPE(FLOAT):       m_call_stack[m_sp + var_id].as_float = asFloat(m_rtype, m_rvalue, node); break;
+      case TYPE(INT):         m_call_stack[m_sp + var_id].as_int = asInt(m_rtype, m_rvalue, node); break;
+      case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(STRING):
+        delete m_call_stack[m_sp + var_id].as_string;
+        m_call_stack[m_sp + var_id].as_string = asString(m_rtype, m_rvalue, node);
+        break;
+        
+      default:
+        INTERPRET_ERROR(INTERNAL);
+    }
+  } else if (node.GetDimensions()) {
+    INTERPRET_ERROR(INTERNAL); // @TODO - array/matrix dimensions
+  }
 }
 
 
@@ -492,7 +550,71 @@
 
 void cDirectInterpretASTVisitor::visitFunctionCall(cASTFunctionCall& node)
 {
-  // @TODO - handle function call
+  // Save previous scope information
+  cSymbolTable* prev_symtbl = m_cur_symtbl;
+  
+  // Get function information
+  cSymbolTable* func_symtbl = node.IsFuncGlobal() ? m_global_symtbl : m_cur_symtbl;
+  int fun_id = node.GetFuncID();
+  
+  // Set current scope to the function symbol table
+  m_cur_symtbl = func_symtbl->GetFunctionSymbolTable(fun_id);
+  m_sp += prev_symtbl->GetNumVariables();
+  for (int i = 0; i < m_cur_symtbl->GetNumVariables(); i++) m_call_stack[m_sp + i].as_string = NULL;
+  
+  // Process the arguments to the function
+  tListIterator<cASTVariableDefinition> sit = func_symtbl->GetFunctionSignature(fun_id)->Iterator();
+  tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
+  cASTVariableDefinition* arg_def = NULL;
+  while ((arg_def = sit.Next())) {
+    cASTNode* arg = cit.Next();
+    if (arg) arg->Accept(*this);
+    else arg_def->GetAssignmentExpression()->Accept(*this);
+    
+    int var_id = arg_def->GetVarID();
+
+    switch (m_cur_symtbl->GetVariableType(var_id)) {
+      case TYPE(ARRAY):       INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(BOOL):        m_call_stack[m_sp + var_id].as_bool = asBool(m_rtype, m_rvalue, node); break;
+      case TYPE(CHAR):        m_call_stack[m_sp + var_id].as_char = asChar(m_rtype, m_rvalue, node); break;
+      case TYPE(FLOAT):       m_call_stack[m_sp + var_id].as_float = asFloat(m_rtype, m_rvalue, node); break;
+      case TYPE(INT):         m_call_stack[m_sp + var_id].as_int = asInt(m_rtype, m_rvalue, node); break;
+      case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(STRING):      m_call_stack[m_sp + var_id].as_string = asString(m_rtype, m_rvalue, node); break;
+        
+      default:
+        INTERPRET_ERROR(INTERNAL);
+    }
+  }
+  
+  
+  // Execute the function
+  func_symtbl->GetFunctionDefinition(fun_id)->Accept(*this);
+  
+  // Handle function return value
+  switch (node.GetType()) {
+    case TYPE(ARRAY):       INTERPRET_ERROR(INTERNAL); // @TODO - return
+    case TYPE(BOOL):        m_rvalue.as_bool = asBool(m_rtype, m_rvalue, node); break;
+    case TYPE(CHAR):        m_rvalue.as_char = asChar(m_rtype, m_rvalue, node); break;
+    case TYPE(FLOAT):       m_rvalue.as_float = asFloat(m_rtype, m_rvalue, node); break;
+    case TYPE(INT):         m_rvalue.as_int = asInt(m_rtype, m_rvalue, node); break;
+    case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - return
+    case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - return
+    case TYPE(STRING):      m_rvalue.as_string = asString(m_rtype, m_rvalue, node); break;
+    case TYPE(VOID):        break;
+      
+    default:
+      INTERPRET_ERROR(INTERNAL);
+  }
+  m_rtype = node.GetType();
+  
+  // @TODO - cleanup scope (delete local string objects on the stack)
+  
+  // Restore previous scope
+  m_has_returned = false;
+  m_sp -= prev_symtbl->GetNumVariables();
+  m_cur_symtbl = prev_symtbl;
 }
 
 
@@ -517,8 +639,7 @@
       m_rtype = TYPE(FLOAT);
       break;
     case TYPE(STRING):
-      // @TODO - handle string...
-      
+      m_rvalue.as_string = new cString(node.GetValue());
       m_rtype = TYPE(STRING);
       break;
     default:
@@ -530,6 +651,7 @@
 void cDirectInterpretASTVisitor::visitLiteralArray(cASTLiteralArray& node)
 {
   // @TODO - handle literal array
+  INTERPRET_ERROR(INTERNAL);
 }
 
 
@@ -547,7 +669,23 @@
 
 void cDirectInterpretASTVisitor::visitVariableReference(cASTVariableReference& node)
 {
-  // @TODO - handle variable reference
+  int var_id = node.GetVarID();
+  int sp = node.IsVarGlobal() ? 0 : m_sp;
+  
+  switch (node.GetType()) {
+    case TYPE(ARRAY):       INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+    case TYPE(BOOL):        m_rvalue.as_bool = m_call_stack[sp + var_id].as_bool; break;
+    case TYPE(CHAR):        m_rvalue.as_char = m_call_stack[sp + var_id].as_char; break;
+    case TYPE(FLOAT):       m_rvalue.as_float = m_call_stack[sp + var_id].as_float; break;
+    case TYPE(INT):         m_rvalue.as_int = m_call_stack[sp + var_id].as_int; break;
+    case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+    case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+    case TYPE(STRING):      m_rvalue.as_string = new cString(*m_call_stack[sp + var_id].as_string); break;
+      
+    default:
+      INTERPRET_ERROR(INTERNAL);
+  }
+  m_rtype = node.GetType();
 }
 
 

Modified: development/source/script/cDirectInterpretASTVisitor.h
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.h	2008-03-06 22:09:04 UTC (rev 2430)
+++ development/source/script/cDirectInterpretASTVisitor.h	2008-03-07 05:03:09 UTC (rev 2431)
@@ -61,6 +61,7 @@
 public:
   cDirectInterpretASTVisitor(cSymbolTable* global_symtbl);
   
+  int Interpret(cASTNode* node);
   
   void visitAssignment(cASTAssignment&);
   




More information about the Avida-cvs mailing list