[Avida-SVN] r2002 - in development/source: script tools

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Fri Aug 24 11:35:07 PDT 2007


Author: brysonda
Date: 2007-08-24 14:35:07 -0400 (Fri, 24 Aug 2007)
New Revision: 2002

Modified:
   development/source/script/cASTDumpVisitor.cc
   development/source/script/cParser.cc
   development/source/script/cParser.h
   development/source/tools/tAutoRelease.h
Log:
AS: Parse all forms of call expressions.

Modified: development/source/script/cASTDumpVisitor.cc
===================================================================
--- development/source/script/cASTDumpVisitor.cc	2007-08-24 13:38:48 UTC (rev 2001)
+++ development/source/script/cASTDumpVisitor.cc	2007-08-24 18:35:07 UTC (rev 2002)
@@ -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;
   }
 }

Modified: development/source/script/cParser.cc
===================================================================
--- development/source/script/cParser.cc	2007-08-24 13:38:48 UTC (rev 2001)
+++ development/source/script/cParser.cc	2007-08-24 18:35:07 UTC (rev 2002)
@@ -190,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
 
@@ -214,7 +214,7 @@
   
   m_tree = parseStatementList();
 
-  if (!m_eof) PARSE_UNEXPECT();
+  if (!m_eof) PARSE_ERROR(UNEXPECTED_TOKEN);
   if (!m_tree) PARSE_ERROR(EMPTY);
 
   delete m_lexer;
@@ -267,10 +267,7 @@
   PARSE_TRACE("parseArrayUnpack");
   cASTNode* au = NULL;
   
-  if (nextToken() != TOKEN(ID)) {
-    PARSE_ERROR(UNEXPECTED_TOKEN);
-    return au;
-  }
+  if (nextToken() != TOKEN(ID)) PARSE_UNEXPECT();
   
   while (nextToken()) {
     if (currentToken() == TOKEN(COMMA)) {
@@ -287,7 +284,6 @@
       break;
     } else {
       PARSE_UNEXPECT();
-      break;      
     }
   }
 
@@ -321,51 +317,39 @@
   return an;
 }
 
-cASTNode* cParser::parseCallExpression()
+cASTNode* cParser::parseCallExpression(cASTNode* target, bool required)
 {
   PARSE_TRACE("parseCallExpression");
-  tAutoRelease<cASTNode> ce(new cASTVariableReference(currentText()));
+  tAutoRelease<cASTNode> ce(target);
   
-  nextToken();
-  
   bool eoe = false;
   while (!eoe) {
     switch (currentToken()) {
       case TOKEN(DOT):
-        if (nextToken() != TOKEN(ID)) {
-          PARSE_UNEXPECT();
-          return ce.Release();
-        }
+        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):
         cASTFunctionCall* fc = new cASTFunctionCall(ce.Release());
         ce.Set(fc);
         if (nextToken() != TOKEN(PREC_CLOSE)) fc->SetArguments(parseArgumentList());
-        if (currentToken() != TOKEN(PREC_CLOSE)) {
-          PARSE_UNEXPECT();
-          return ce.Release();   
-        }
-        switch (nextToken()) {
-          case TOKEN(IDX_OPEN):
-            do {
-              parseIndexExpression();
-            } while (nextToken() == TOKEN(IDX_OPEN));
-            break;
-          case TOKEN(DOT):
-            continue;
-
-          default:
-            eoe = true;
-        }
+        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.Release();
+        if (required) { PARSE_UNEXPECT(); }
+        else eoe = true;
     }
   }
     
@@ -375,18 +359,13 @@
 cASTNode* cParser::parseCodeBlock()
 {
   PARSE_TRACE("parseCodeBlock");
-  cASTNode* cb = NULL;
 
   // Swallow all newlines and suppress tokens
   while (currentToken() == TOKEN(ENDL) || currentToken() == TOKEN(SUPPRESS)) nextToken();
   
-  if (currentToken() == TOKEN(ARR_OPEN)) {
-    cb = parseLooseBlock();
-  } else {
-    PARSE_UNEXPECT();
-  }
+  if (currentToken() == TOKEN(ARR_OPEN)) return parseLooseBlock();
   
-  return cb;  
+  PARSE_UNEXPECT();
 }
 
 cASTNode* cParser::parseExpression()
@@ -563,56 +542,44 @@
 cASTNode* cParser::parseExprP6()
 {
   PARSE_TRACE("parseExprP6");
-  cASTNode* expr = NULL;
+  tAutoRelease<cASTNode> expr;
   
   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)) {
         cASTNode* vr = new cASTVariableReference(currentText());
         nextToken(); // consume id token
         cASTFunctionCall* fc = new cASTFunctionCall(vr);
-        expr = fc;
+        expr.Set(fc);
         if (nextToken() != TOKEN(PREC_CLOSE)) fc->SetArguments(parseArgumentList());        
-        if (currentToken() != TOKEN(PREC_CLOSE)) {
-          PARSE_UNEXPECT();
-          return expr;
-        }
+        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();
     case TOKEN(ARR_OPEN):
       if (nextToken() != TOKEN(ARR_CLOSE)) parseArgumentList();
-      if (currentToken() != TOKEN(ARR_CLOSE)) {
-        PARSE_UNEXPECT();
-        return expr;
-      }
+      if (currentToken() != TOKEN(ARR_CLOSE)) PARSE_UNEXPECT();
       // @todo - return literal array
       break;
       
@@ -620,52 +587,23 @@
     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;
   }
 
   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;
 }
 
 
@@ -792,63 +730,51 @@
 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 parseVarDeclare();
       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();
   
   tAutoRelease<cASTIfBlock> is(new cASTIfBlock(cond.Release(), parseCodeBlock()));
 
   while (currentToken() == TOKEN(CMD_ELSEIF)) {
     
-    if (nextToken() != TOKEN(PREC_OPEN)) {
-      PARSE_UNEXPECT();
-      return NULL;
-    }
+    if (nextToken() != TOKEN(PREC_OPEN)) PARSE_UNEXPECT();
     
     nextToken(); // consume '('
     tAutoRelease<cASTNode> elifcond(parseExpression());
     
-    if (currentToken() != TOKEN(PREC_CLOSE)) {
-      PARSE_UNEXPECT();
-      return NULL;
-    }
+    if (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
+
     nextToken(); // consume ')'
     
     cASTNode* elifcode = parseCodeBlock();
@@ -865,49 +791,31 @@
   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()
@@ -998,7 +906,6 @@
 cASTNode* cParser::parseVarDeclare()
 {
   PARSE_TRACE("parseVarDeclare");
-  cASTVariableDefinition* vd = NULL;
   
   ASType_t vtype = AS_TYPE_INVALID;
   switch (currentToken()) {
@@ -1009,45 +916,36 @@
     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 (currentToken() != TOKEN(PREC_CLOSE)) PARSE_UNEXPECT();
       break;
       
     default:
       break;
   }
   
-  return vd;
+  return vd.Release();
 }
 
 cASTNode* cParser::parseVarDeclareList()
@@ -1067,18 +965,13 @@
 {
   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();
   
   cASTNode* code = parseCodeBlock();

Modified: development/source/script/cParser.h
===================================================================
--- development/source/script/cParser.h	2007-08-24 13:38:48 UTC (rev 2001)
+++ development/source/script/cParser.h	2007-08-24 18:35:07 UTC (rev 2002)
@@ -92,7 +92,7 @@
   cASTNode* parseArgumentList();
   cASTNode* parseArrayUnpack();
   cASTNode* parseAssignment();
-  cASTNode* parseCallExpression();
+  cASTNode* parseCallExpression(cASTNode* target, bool required = false);
   cASTNode* parseCodeBlock();
   cASTNode* parseExpression();
   cASTNode* parseExprP0();

Modified: development/source/tools/tAutoRelease.h
===================================================================
--- development/source/tools/tAutoRelease.h	2007-08-24 13:38:48 UTC (rev 2001)
+++ development/source/tools/tAutoRelease.h	2007-08-24 18:35:07 UTC (rev 2002)
@@ -43,6 +43,8 @@
   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; }
   




More information about the Avida-cvs mailing list