ReprSimp.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2006, Johns Hopkins University.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or
00007  * without modification, are permitted provided that the following
00008  * conditions are met:
00009  *
00010  *   - Redistributions of source code must contain the above 
00011  *     copyright notice, this list of conditions, and the following
00012  *     disclaimer. 
00013  *
00014  *   - Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions, and the following
00016  *     disclaimer in the documentation and/or other materials 
00017  *     provided with the distribution.
00018  *
00019  *   - Neither the names of the copyright holders nor the names of any
00020  *     of any contributors may be used to endorse or promote products
00021  *     derived from this software without specific prior written
00022  *     permission. 
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  **************************************************************************/
00037 
00038 #include <stdint.h>
00039 #include <stdlib.h>
00040 #include <dirent.h>
00041 #include <fstream>
00042 #include <iostream>
00043 #include <string>
00044 #include <sstream>
00045 #include <libsherpa/UExcept.hxx>
00046 #include <libsherpa/CVector.hxx>
00047 #include <libsherpa/avl.hxx>
00048 #include <assert.h>
00049 #include "AST.hxx"
00050 #include "Type.hxx"
00051 #include "inter-pass.hxx"
00052 
00053 using namespace sherpa;
00054 
00055 void
00056 CollectBodyTags(GCPtr<AST> body, GCPtr<CVector<std::string> > tags, std::string tagPrefix)
00057 {
00058   GCPtr<CVector<GCPtr<AST> > > subCases = new CVector<GCPtr<AST> >;
00059 
00060   // Keep track of where this pass started adding tags.
00061   size_t startTagNdx = tags->size();
00062 
00063   // First, collect all tags and sub-bodies that appear at the current 
00064   // level.
00065   for (size_t i = 0; i < body->children->size(); i++) {
00066     GCPtr<AST> bform = body->child(i);
00067 
00068     if (bform->astType == at_reprtag) {
00069       for(size_t tag = 0; tag < bform->children->size(); tag++) {
00070         // Remember that at this point we have not done symbol
00071         // resolution yet, so we must manipulate the ASTs using the
00072         // 's' field!
00073         GCPtr<AST> tagID = bform->child(tag);
00074         std::string accumTag = tagPrefix + tagID->s + "#";
00075 
00076         // If this tag is not already present in the tag collection, add it:
00077         bool found = false;
00078         for (size_t etg = 0; !found && etg < tags->size(); etg++) {
00079           if (tags->elem(etg) == accumTag) 
00080             found = true;
00081         }
00082 
00083         if (!found) {
00084           REPR_SIMP_DEBUG std::cerr << "Appending tag " 
00085                                     << accumTag << std::endl;
00086           tags->append(accumTag);
00087         }
00088       }
00089     }
00090     else if (bform->astType == at_reprcase) {
00091       for (size_t leg = 0; leg < bform->children->size(); leg++) {
00092         GCPtr<AST> theLeg = bform->child(leg);
00093         subCases->append(theLeg);
00094       }
00095     }
00096   }
00097 
00098   size_t endTagNdx = tags->size();
00099 
00100   if (subCases->size()) {
00101     REPR_SIMP_DEBUG std::cerr << "There are subcases to process." 
00102                               << std::endl;
00103 
00104     for (size_t i = startTagNdx; i < endTagNdx; i++) {
00105       std::string prefix = tags->elem(i);
00106 
00107       for (size_t leg = 0; leg < subCases->size(); leg++) {
00108         GCPtr<AST> theLeg = subCases->elem(leg);
00109         GCPtr<AST> body = theLeg->child(0);
00110 
00111         for (size_t tag = 1; tag < theLeg->children->size(); tag++) {
00112           GCPtr<AST> theTagID = theLeg->child(tag);
00113           std::string matchThis = std::string("#") + theTagID->s + "#";
00114 
00115           // We now have the tag on this leg in a form that we can
00116           // pattern match against the accumulated supertag. If it is
00117           // present in the supertag, then this body is active and we
00118           // need to process it for this case.
00119           if (prefix.find(matchThis, 0) != std::string::npos)
00120             CollectBodyTags(body, tags, prefix);
00121         }
00122       }
00123     }
00124   }
00125 }
00126 
00127 void
00128 CollectReprLeg(GCPtr<AST> body, GCPtr<AST> ctor, std::string theTag)
00129 {
00130   //GCPtr<CVector<GCPtr<AST> > > subCases = new CVector<GCPtr<AST> >;
00131 
00132   for (size_t i = 0; i < body->children->size(); i++) {
00133     GCPtr<AST> bform = body->child(i);
00134 
00135     if (bform->astType == at_field) {
00136       GCPtr<AST> ident = bform->child(0);
00137       REPR_SIMP_DEBUG std::cerr << "  Appending field " 
00138                                 << ident->s << std::endl;
00139 
00140       ctor->children->append(bform);
00141     }
00142     else if (bform->astType == at_reprcase) {
00143       for (size_t leg = 0; leg < bform->children->size(); leg++) {
00144         GCPtr<AST> theLeg = bform->child(leg);
00145         GCPtr<AST> subBody = theLeg->child(0);
00146 
00147         for (size_t tag = 1; tag < theLeg->children->size(); tag++) {
00148           GCPtr<AST> theTagID = theLeg->child(tag);
00149           std::string matchThis = std::string("#") + theTagID->s + "#";
00150 
00151           // std::cerr << "Checking " << matchThis << std::endl;
00152 
00153           if (theTag.find(matchThis, 0) != std::string::npos)
00154             CollectReprLeg(subBody, ctor, theTag);
00155         }
00156       }
00157     }
00158   }
00159 }
00160 
00161 // ReprSimp -- simplify defrepr forms to unions.
00162 //
00163 // This version simply wipes out the defrepr forms altogether and 
00164 // replaces them with unions.
00165 //
00166 static GCPtr<AST> 
00167 ReprSimp(GCPtr<AST> ast)
00168 {
00169   switch (ast->astType) {
00170   case at_defrepr:
00171     {
00172       GCPtr<AST> body = ast->child(4);
00173       GCPtr<AST> ctors = new AST(at_constructors, ast->loc);
00174 
00175       REPR_SIMP_DEBUG std::cerr << "Processing defrepr " 
00176                                 << ast->fqn << std::endl;
00177       GCPtr< CVector<std::string> > tagVec = new CVector<std::string>;
00178       CollectBodyTags(body, tagVec, "#");
00179 
00180       for (size_t tag = 0; tag < tagVec->size(); tag++) {
00181         std::string theTag = tagVec->elem(tag);
00182         GCPtr<AST> ident = new AST(at_ident, LToken(ast->loc, theTag));
00183         GCPtr<AST> ctor = new AST(at_constructor, ast->loc, ident);
00184 
00185         REPR_SIMP_DEBUG std::cerr << "Processing leg for " 
00186                                   << theTag << std::endl; 
00187 
00188         CollectReprLeg(body, ctor, theTag);
00189         ctors->children->append(ctor);
00190       }
00191 
00192       // ast->child(4) = FlattenBody(body, ctors, "");
00193       ast->child(4) = ctors;
00194 
00195       ast->astType = at_defunion;
00196 
00197       return ast;
00198     }
00199 
00200   case at_declrepr:
00201     {
00202       ast->astType = at_declunion;
00203       return ast;
00204     }
00205 
00206   default:
00207     break;
00208   }
00209 
00210   GCPtr< CVector<GCPtr<AST> > > newChildren = new CVector<GCPtr<AST> >;
00211   for (size_t i = 0; i < ast->children->size(); i++) {
00212     GCPtr<AST> newAst = ReprSimp(ast->child(i));
00213     if (newAst)
00214       newChildren->append(newAst);
00215   }
00216   ast->children->erase();
00217 
00218   for (size_t i = 0; i < newChildren->size(); i++)
00219     ast->children->append(newChildren->elem(i));
00220 
00221   return ast;
00222 }
00223 
00224 bool
00225 UocInfo::fe_reprSimp(std::ostream& errStream, 
00226                      bool init, unsigned long flags)
00227 {
00228   ReprSimp(ast);
00229   return true;
00230 }
00231 

Generated on Thu May 17 23:59:16 2012 for BitC Compiler by  doxygen 1.4.7