00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
00061 size_t startTagNdx = tags->size();
00062
00063
00064
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
00071
00072
00073 GCPtr<AST> tagID = bform->child(tag);
00074 std::string accumTag = tagPrefix + tagID->s + "#";
00075
00076
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
00116
00117
00118
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
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
00152
00153 if (theTag.find(matchThis, 0) != std::string::npos)
00154 CollectReprLeg(subBody, ctor, theTag);
00155 }
00156 }
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164
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
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