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 "AST.hxx"
00045 #include "Environment.hxx"
00046 #include "Symtab.hxx"
00047 #include "Unify.hxx"
00048 #include "inter-pass.hxx"
00049 #include <sstream>
00050
00051 using namespace sherpa;
00052
00053 bool
00054 isTrivialInit(AST *ast)
00055 {
00056 switch(ast->astType) {
00057
00058 case at_boolLiteral:
00059 case at_charLiteral:
00060 case at_intLiteral:
00061 case at_floatLiteral:
00062 case at_stringLiteral:
00063 case at_unit:
00064 case at_lambda:
00065 {
00066 return true;
00067 }
00068
00069 case at_ident:
00070 {
00071 return ast->symType->isAtomic();
00072 }
00073
00074 case at_tqexpr:
00075 {
00076 return isTrivialInit(ast->children[0]);
00077 }
00078
00079
00080
00081
00082
00083
00084 case at_begin:
00085 {
00086 for(size_t c = 0; c < ast->children.size(); c++)
00087 if(!isTrivialInit(ast->children[c]))
00088 return false;
00089 return true;
00090 }
00091
00092 default:
00093 return false;
00094 }
00095 }
00096
00097 AST *
00098 FixDefs(AST *mod)
00099 {
00100 AST *newMod = new AST(mod->astType, mod->loc);
00101 for(size_t c = 0; c < mod->children.size(); c++) {
00102 AST *ast = mod->children[c];
00103 switch(ast->astType) {
00104 case at_define:
00105 {
00106 AST *expr = ast->children[1];
00107 if(expr->astType != at_lambda) {
00108 if(!isTrivialInit(expr)) {
00109
00110
00111
00112
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 AST *id = AST::genSym(ast, "init");
00130 AST *ip = new AST(at_identPattern, id->loc, id);
00131 AST *argVec = new AST(at_argVec, ast->loc);
00132 AST *lam = new AST(at_lambda, ast->loc,
00133 argVec, expr);
00134 AST *initDef = new AST(at_define, ast->loc, ip, lam);
00135 initDef->addChild(new AST(at_constraints));
00136 newMod->children.append(initDef);
00137
00138
00139
00140
00141
00142
00143
00144
00145 AST *idUse = id->getDCopy();
00146 AST *app = new AST(at_apply, ast->loc, idUse);
00147 ast->children[1] = app;
00148 ast->Flags |= DEF_IS_INIT_AUX;
00149 app->Flags2 |= APP_IS_VALUE;
00150 app->Flags2 |= APP_NATIVE_FNXN;
00151 newMod->children.append(ast);
00152 }
00153 else {
00154 if(expr->astType == at_begin) {
00155
00156
00157
00158 ast->children[1] = expr->children[expr->children.size() - 1];
00159 }
00160 newMod->children.append(ast);
00161 }
00162 }
00163 else {
00164 newMod->children.append(ast);
00165 }
00166 break;
00167 }
00168 default:
00169 newMod->children.append(ast);
00170 break;
00171 }
00172 }
00173 return newMod;
00174 }
00175
00176 bool
00177 fixinit(std::ostream& errStream, UocInfo *uoc)
00178 {
00179 bool errFree = true;
00180 AST *mod = uoc->ast->children[0];
00181 uoc->ast->children[0] = FixDefs(mod);
00182
00183 return errFree;
00184 }
00185
00186
00187 bool
00188 UocInfo::be_fix4c(std::ostream& errStream,
00189 bool init, unsigned long flags)
00190 {
00191 bool errFree = true;
00192 UocInfo *uoc = &(UocInfo::linkedUoc);
00193 assert(uoc != NULL);
00194
00195 CHKERR(errFree, fixinit(errStream, uoc));
00196
00197 errStream << "Fixinit AST = " << std::endl
00198 << uoc->ast->asString() << std::endl;
00199
00200 CHKERR(errFree, RandT(errStream, uoc, true,
00201 CL_SYM_FLAGS, CL_TYP_FLAGS));
00202
00203 return errFree;
00204 }