MethDecl.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2008, 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 /* In order to successfully polyinstantiate instances that contain
00039    immediate lambdas, we need to hoist them and give them proper
00040    names so that the polyinstantiator has something to mangle. */
00041 
00042 #include <assert.h>
00043 #include <stdint.h>
00044 #include <stdlib.h>
00045 #include <dirent.h>
00046 #include <fstream>
00047 #include <iostream>
00048 #include <sstream>
00049 #include <string>
00050 
00051 #include <libsherpa/UExcept.hxx>
00052 
00053 #include "AST.hxx"
00054 #include "inter-pass.hxx"
00055 
00056 using namespace boost;
00057 using namespace sherpa;
00058 using namespace std;
00059 
00067 static void
00068 insertMethDecls(shared_ptr<AST> ast, std::ostream& errStream, bool &errFree)
00069 {
00070   assert(ast->astType == at_interface || ast->astType == at_module);
00071 
00072   // We rely here on the fact that the top-level AST must be
00073   // at_interface or at_module, and that DEFSTRUCT and DEFOBJECT can
00074   // only appear as children of these nodes.
00075 
00076   std::vector<shared_ptr<AST> > newChildren;
00077 
00078   for (size_t c = 0; c < ast->children.size(); c++) {
00079     shared_ptr<AST> theTypeDefn = ast->child(c);
00080     newChildren.push_back(theTypeDefn);
00081 
00082     if ((theTypeDefn->astType != at_defstruct) &&
00083         (theTypeDefn->astType != at_defobject))
00084       continue;
00085 
00086     // Typename might be an at_usesel here, but the parser has set
00087     // the "s" field in that case.
00088     shared_ptr<AST> typeName = theTypeDefn->child(0);
00089 
00090     shared_ptr<AST> fields = theTypeDefn->child(4);
00091 
00092     for (size_t f = 0; f < fields->children.size(); f++) {
00093       shared_ptr<AST> fld = fields->child(f);
00094 
00095       if (fld->astType != at_methdecl)
00096         continue;
00097 
00098       shared_ptr<AST> methName = fld->child(0);
00099       shared_ptr<AST> methFnType = fld->child(1)->getDeepCopy();
00100       methFnType->astType = at_fn;
00101       shared_ptr<AST> methFnArgs = methFnType->child(0);
00102 
00103       // Assume initially that this is a non-parameterize type. We
00104       // will fix that in a moment.
00105       shared_ptr<AST> structArgType = theTypeDefn->child(0)->getDeepCopy();
00106 
00107       // If the structure type is parameterized, it's tvList will be
00108       // non-empty, and we need to build an at_typeapp node:
00109       shared_ptr<AST> tvList = theTypeDefn->child(1);
00110       assert(tvList->astType == at_tvlist);
00111 
00112       if (tvList->children.size()) {
00113         structArgType = AST::make(at_typeapp, tvList->loc, structArgType);
00114         for (size_t tv = 0; tv < tvList->children.size(); tv++) {
00115           shared_ptr<AST> theTV = tvList->child(tv);
00116           structArgType->addChild(theTV->getDeepCopy());
00117         }
00118       }
00119 
00120       // If the structure is an unboxed type, we need to wrap the argument
00121       // type in a BY-REF. Check child(4):
00122       if (theTypeDefn->child(4)->astType == at_unboxedCat)
00123         structArgType = 
00124           AST::make(at_byRefType, structArgType->child(4)->loc,
00125                     structArgType);
00126 
00127       // Fetch the (possibly empty) constraint set from the original
00128       // structure:
00129       size_t nChildren = theTypeDefn->children.size();
00130       shared_ptr<AST> constraintSet = theTypeDefn->child(nChildren - 1);
00131 
00132 #if 0
00133       if (constraintSet->children.size()) {
00134         // There are constraints. Wrap the AST describing the type in
00135         // an at_qualtype node:
00136 
00137         structArgType =
00138           AST::make(at_qualType, constraintSet->loc,
00139                     constraintSet->getDeepCopy(), structArgType);
00140       }
00141 #endif
00142 
00143       methFnArgs->children.insert(methFnArgs->children.begin(),
00144                                   structArgType);
00145 
00146       // We should probably build a at_usesel here, but the resolver
00147       // pass will simply smash that into an identifier anyway, so go
00148       // ahead and build the identifier directly:
00149 
00150       shared_ptr<AST> methFnIdentNode = 
00151         AST::make(at_usesel, 
00152                   methName->loc,
00153                   typeName->getDeepCopy(),
00154                   methName->getDeepCopy());
00155 
00156       shared_ptr<AST> mFnDecl = 
00157         AST::make(at_proclaim, fld->loc, 
00158                   methFnIdentNode,
00159                   methFnType,
00160                   constraintSet->getDeepCopy());
00161 
00162       mFnDecl->isDecl = true;
00163 
00164       // FIX: Not convinced that this is correct:
00165       mFnDecl->flags |= PROCLAIM_IS_INTERNAL;
00166 
00167       mFnDecl->printVariant = pf_IMPLIED;
00168 
00169       newChildren.push_back(mFnDecl);
00170     }
00171   }
00172 
00173   ast->children = newChildren;
00174 }
00175 
00176 bool
00177 UocInfo::fe_methDecl(std::ostream& errStream,
00178                       bool init, unsigned long flags)
00179 {
00180   DEBUG(METH_DECL) if (isSourceUoc())
00181     PrettyPrint(errStream);
00182 
00183   DEBUG(BEG_SIMP) std::cerr << "fe_beginSimp" << std::endl;
00184   bool errFree = true;
00185   insertMethDecls(uocAst, errStream, errFree);
00186 
00187   DEBUG(METH_DECL) if (isSourceUoc())
00188     PrettyPrint(errStream);
00189 
00190   return true;
00191 }

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