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 <stdlib.h>
00039 #include <errno.h>
00040 #include <dirent.h>
00041 #include <fstream>
00042 #include <iostream>
00043 #include <string>
00044 #include <assert.h>
00045 #include <sstream>
00046 #include "AST.hxx"
00047 #include "Type.hxx"
00048 #include "Options.hxx"
00049 #include "inter-pass.hxx"
00050 using namespace sherpa;
00051 using namespace std;
00052
00053 extern void AlphaRename(GCPtr<AST> ast);
00054
00055 extern GCPtr<AST> loop2letrec(GCPtr<AST>);
00056
00057 enum DeclsOrDefs {
00058 WantForward,
00059 WantDecl,
00060 WantGC,
00061 WantConstructors,
00062 WantDefs
00063 };
00064
00065
00066
00067 struct INOstream {
00068 long depth;
00069 bool needIndent;
00070 std::ostream &ostrm;
00071 void doIndent();
00072
00073 INOstream(std::ostream &os)
00074 :ostrm(os)
00075 {
00076 depth = 0;
00077 needIndent = true;
00078 }
00079
00080 inline void indent(int i)
00081 {
00082 depth += i;
00083 }
00084
00085 inline void more()
00086 {
00087 indent(2);
00088 }
00089
00090 inline void less()
00091 {
00092 indent(-2);
00093 }
00094 };
00095
00096 void
00097 INOstream::doIndent()
00098 {
00099 if (needIndent) {
00100 for (int i = 0; i < depth; i++) {
00101 ostrm << ' ';
00102 }
00103 }
00104 needIndent = false;
00105 }
00106
00107
00108
00109
00110 inline
00111 INOstream& operator<<(INOstream& inostrm, ostream& (*pf)(ostream&))
00112 {
00113 inostrm.doIndent();
00114 inostrm.ostrm << pf;
00115 if (pf == (ostream& (*)(ostream&)) std::endl)
00116 inostrm.needIndent = true;
00117 return inostrm;
00118 }
00119
00120 inline
00121 INOstream& operator<<(INOstream& inostrm, const char *s)
00122 {
00123 inostrm.doIndent();
00124 for (size_t i = 0; i < strlen(s); i++) {
00125 if (s[i] != '\n')
00126 inostrm.ostrm << s[i];
00127 else {
00128 inostrm << std::endl;
00129 }
00130 }
00131
00132 return inostrm;
00133 }
00134
00135 inline
00136 INOstream& operator<<(INOstream& inostrm, const uint64_t ull)
00137 {
00138 inostrm.doIndent();
00139 inostrm.ostrm << ull;
00140
00141 return inostrm;
00142 }
00143
00144 inline
00145 INOstream& operator<<(INOstream& inostrm, const std::string& s)
00146 {
00147 inostrm.doIndent();
00148 for (size_t i = 0; i < s.size(); i++) {
00149 if (s[i] != '\n')
00150 inostrm.ostrm << s[i];
00151 else {
00152 inostrm << std::endl;
00153 }
00154 }
00155
00156 return inostrm;
00157 }
00158
00159 template<typename T>
00160 inline
00161 INOstream& operator<<(INOstream& inostrm, T ob)
00162 {
00163 inostrm.doIndent();
00164 inostrm.ostrm << ob;
00165 return inostrm;
00166 }
00167
00169
00170
00171
00173
00174
00175
00176
00177
00178 bool
00179 getDefs(std::ostream& errStream,
00180 GCPtr<AST> bp, GCPtr< CVector< GCPtr<AST> > > defs)
00181 {
00182 bool errFree = true;
00183 switch(bp->astType) {
00184 case at_identPattern:
00185 {
00186
00187 defs->append(bp->children[0]);
00188 break;
00189 }
00190
00191 case at_unitPattern:
00192 break;
00193 case at_cpairPattern:
00194 case at_pairPattern:
00195 {
00196
00197 for (size_t c = 0; c < bp->children.size(); c++)
00198 CHKERR(errFree, getDefs(errStream, bp->children[c], defs));
00199 break;
00200 }
00201
00202 default:
00203 {
00204 errStream << bp->loc << ": "
00205 << "Internal Compiler Error."
00206 << "Unexpected Binding Pattern type "
00207 << bp->astTypeName()
00208 << " obtained by getDefs() routine."
00209 << std::endl;
00210 errFree = false;
00211 break;
00212 }
00213 }
00214 return errFree;
00215 }
00216
00217
00218 void
00219 getDefNames(GCPtr<AST> bp, CVector<std::string>& names)
00220 {
00221 GCPtr< CVector < GCPtr<AST> > > defs = new CVector< GCPtr<AST> >;
00222
00223 getDefs(std::cerr, bp, defs);
00224
00225 for (size_t i = 0; i < defs->size(); i++) {
00226 GCPtr<AST> ident = (*defs)[i];
00227
00228 names.append(ident->s);
00229 }
00230 }
00231
00232
00233
00234 bool
00235 pureLoop(std::ostream& errStream, const GCPtr<AST>& ast,
00236 std::string nm, bool isTail)
00237 {
00238 bool result = true;
00239
00240 switch(ast->astType) {
00241 case at_Null:
00242 case at_boolLiteral:
00243 case at_charLiteral:
00244 case at_intLiteral:
00245 case at_floatLiteral:
00246 case at_stringLiteral:
00247 return true;
00248
00249 case at_ident:
00250 {
00251 if (!isTail && ast->s == nm) {
00252 errStream << ast->loc.asString()
00253 << ": error: loop name "
00254 << nm
00255 << " appears in non-tail position."
00256 << std::endl;
00257
00258 result = false;
00259 }
00260
00261 break;
00262 }
00263
00264 case at_usesel:
00265
00266
00267 return true;
00268
00269 case at_begin:
00270 case at_ibegin:
00271 {
00272 for (size_t i = 0; i < ast->children.size() - 1; i++) {
00273 GCPtr<AST> child = ast->children[i];
00274 if (!pureLoop(errStream, child, nm, false))
00275 result = false;
00276 }
00277 GCPtr<AST> child = ast->children[ast->children.size()-1];
00278 if (!pureLoop(errStream, child, nm, isTail))
00279 result = false;
00280 break;
00281 }
00282
00283 case at_if:
00284 {
00285 GCPtr<AST> tst = ast->children[0];
00286 GCPtr<AST> thn = ast->children[1];
00287 GCPtr<AST> els = ast->children[2];
00288
00289 if (!pureLoop(errStream, tst, nm, false))
00290 result = false;
00291 if (!pureLoop(errStream, thn, nm, isTail))
00292 result = false;
00293 if (!pureLoop(errStream, els, nm, isTail))
00294 result = false;
00295
00296 break;
00297 }
00298
00299 case at_apply:
00300 {
00301 for (size_t i = 0; i < ast->children.size(); i++) {
00302 GCPtr<AST> child = ast->children[i];
00303 if (!pureLoop(errStream, child, nm, (i > 0) ? false : isTail))
00304 result = false;
00305 }
00306 break;
00307 }
00308
00309 case at_try:
00310 {
00311
00312 if (!pureLoop(errStream, ast->children[0], nm, isTail))
00313 result = false;
00314
00315 if (!pureLoop(errStream, ast->children[1], nm, isTail))
00316 result = false;
00317
00318 if (!pureLoop(errStream, ast->children[2], nm, isTail))
00319 result = false;
00320 break;
00321 }
00322
00323 case at_loop:
00324 {
00325
00326 GCPtr<AST> last = loop2letrec(ast);
00327 GCPtr<AST> bindings = last->children[0];
00328 GCPtr<AST> binding = bindings->children[0];
00329 GCPtr<AST> looplambda = binding->children[1];
00330
00331 if (!pureLoop(errStream, looplambda->children[1], nm, isTail))
00332 result = false;
00333 break;
00334 }
00335
00336 case at_let:
00337 case at_letrec:
00338 {
00339
00340 GCPtr<AST> bindings = ast->children[0];
00341 GCPtr<AST> body = ast->children[1];
00342
00343 CVector<std::string> names;
00344
00345
00346 for (size_t i = 0; i < bindings->children.size(); i++) {
00347 GCPtr<AST> binding = bindings->children[i];
00348 GCPtr<AST> bp = binding->children[0];
00349
00350 getDefNames(bp, names);
00351 }
00352
00353 bool shadowed = false;
00354
00355
00356 for (size_t i = 0; i < names.size(); i++) {
00357 if (names[i] == nm) {
00358 shadowed = true;
00359 break;
00360 }
00361 }
00362
00363
00364
00365 if (ast->astType == at_letrec || !shadowed) {
00366 for (size_t i = 0; i < bindings->children.size(); i++) {
00367 GCPtr<AST> binding = bindings->children[i];
00368 GCPtr<AST> expr = binding->children[1];
00369
00370 if (!pureLoop(errStream, expr, nm, false))
00371 result = false;
00372 }
00373 }
00374
00375
00376
00377 if (!shadowed && !pureLoop(errStream, body, nm, isTail));
00378 result = false;
00379
00380 break;
00381 }
00382
00383 case at_case:
00384 {
00385
00386 if (!pureLoop(errStream, ast->children[0], nm, false))
00387 result = false;
00388
00389 if (!pureLoop(errStream, ast->children[1], nm, isTail))
00390 result = false;
00391
00392 if (!pureLoop(errStream, ast->children[2], nm, isTail))
00393 result = false;
00394 break;
00395 }
00396
00397 case at_cond:
00398 {
00399
00400 if (!pureLoop(errStream, ast->children[0], nm, isTail))
00401 result = false;
00402
00403 if (!pureLoop(errStream, ast->children[1], nm, isTail))
00404 result = false;
00405 break;
00406 }
00407
00408 case at_cond_legs:
00409 case at_case_legs:
00410 {
00411
00412 for (size_t i = 0; i < ast->children.size(); i++) {
00413 GCPtr<AST> child = ast->children[i];
00414 if (!pureLoop(errStream, child, nm, isTail))
00415 result = false;
00416 }
00417 break;
00418 }
00419 case at_cond_leg:
00420 case at_case_leg:
00421 {
00422
00423
00424 if (!pureLoop(errStream, ast->children[0], nm, false))
00425 result = false;
00426
00427 if (!pureLoop(errStream, ast->children[1], nm, isTail))
00428 result = false;
00429 break;
00430 }
00431 case at_otherwise:
00432 {
00433
00434 if (!pureLoop(errStream, ast->children[0], nm, isTail))
00435 result = false;
00436 break;
00437 }
00438
00439
00440 case at_and:
00441 case at_or:
00442
00443 case at_throw:
00444 case at_setbang:
00445 case at_deref:
00446
00447 case at_makevector:
00448 case at_vector:
00449 case at_array:
00450
00451 case at_select:
00452 case at_array_ref:
00453 case at_vector_ref:
00454 case at_array_length:
00455 case at_vector_length:
00456 {
00457 for (size_t i = 0; i < ast->children.size(); i++) {
00458 GCPtr<AST> child = ast->children[i];
00459 if (!pureLoop(errStream, child, nm, false))
00460 result = false;
00461 }
00462 break;
00463 }
00464
00465 case at_lambda:
00466 case at_ilambda:
00467 {
00468 errStream << ast->loc.asString()
00469 << ": error: Something is wrong. This lambda should not have"
00470 << " survived to this pass."
00471 << std::endl;
00472 exit(1);
00473 break;
00474 }
00475 default:
00476 {
00477 errStream << ast->loc.asString()
00478 << ": error: Unhandled case in pureLoop()."
00479 << std::endl;
00480 exit(1);
00481 break;
00482 }
00483 }
00484
00485 return result;
00486 }
00487
00488 bool
00489 hasPureLoops(std::ostream& errStream, const GCPtr<AST>& ast)
00490 {
00491 bool result = true;
00492
00493 switch(ast->astType) {
00494 case at_loop:
00495 {
00496
00497 GCPtr<AST> last = loop2letrec(ast);
00498 GCPtr<AST> bindings = last->children[0];
00499 GCPtr<AST> binding = bindings->children[0];
00500 GCPtr<AST> idPattern = binding->children[0];
00501 GCPtr<AST> id = idPattern->children[0];
00502 GCPtr<AST> looplambda = binding->children[1];
00503 GCPtr<AST> body = last->children[1];
00504
00505 if (!pureLoop(errStream, looplambda->children[1], id->s, true))
00506 result = false;
00507 if (!hasPureLoops(errStream, looplambda))
00508 result = false;
00509
00510 break;
00511 }
00512
00513 default:
00514 {
00515 for (size_t i = 0; i < ast->children.size(); i++) {
00516 if (!hasPureLoops(errStream, ast->children[i]))
00517 result = false;
00518 }
00519 break;
00520 }
00521 }
00522
00523
00524 return result;
00525 }
00526
00527 bool
00528 hasLambda(std::ostream& errStream, const GCPtr<AST>& ast)
00529 {
00530 bool result = false;
00531
00532 if (ast->astType == at_lambda || ast->astType == at_ilambda) {
00533 errStream << ast->loc
00534 << ": Error: bootstrap backend does not support "
00535 << ast->atKwd()
00536 << " in this context."
00537 << std::endl;
00538 result = true;
00539 }
00540
00541
00542 if (ast->astType == at_loop) {
00543
00544 GCPtr<AST> last = loop2letrec(ast);
00545 GCPtr<AST> bindings = last->children[0];
00546 GCPtr<AST> binding = bindings->children[0];
00547 GCPtr<AST> looplambda = binding->children[1];
00548 GCPtr<AST> body = last->children[1];
00549
00550 for (size_t i = 0; i < looplambda->children.size(); i++) {
00551 if (hasLambda(errStream, looplambda->children[i]))
00552 result = true;
00553 }
00554 if (hasLambda(errStream, body))
00555 result = true;
00556 }
00557 else {
00558 for (size_t i = 0; i < ast->children.size(); i++) {
00559 if (hasLambda(errStream, ast->children[i]))
00560 result = true;
00561 }
00562 }
00563
00564 return result;
00565 }
00566
00567 bool
00568 hasInnerLambdas(std::ostream& errStream, const GCPtr<AST>& ast)
00569 {
00570 bool result = false;
00571
00572 switch(ast->astType) {
00573 case at_define:
00574 {
00575
00576
00577
00578 GCPtr<AST> expr = ast->children[1];
00579
00580 for (size_t i = 0; i < expr->children.size(); i++) {
00581 if (hasLambda(errStream, expr->children[i]))
00582 result = true;
00583 }
00584
00585 break;
00586 }
00587
00588 default:
00589 break;
00590 }
00591
00592 for (size_t i = 0; i < ast->children.size(); i++) {
00593 if (hasInnerLambdas(errStream, ast->children[i]))
00594 result = true;
00595 }
00596
00597 return result;
00598 }
00599
00600 bool
00601 hasPatternBindings(std::ostream& errStream, const GCPtr<AST>& ast)
00602 {
00603 bool result = false;
00604
00605 switch(ast->astType) {
00606 case at_define:
00607 {
00608 GCPtr<AST> bp = ast->children[0];
00609
00610 if (ast->getType()->kind == ty_fn) {
00611 }
00612 }
00613
00614 case at_letbinding:
00615 {
00616 GCPtr<AST> bp = ast->children[0];
00617 if (bp->astType != at_identPattern) {
00618 errStream << bp->loc.asString()
00619 << ": Error: bootstrap backend does not support "
00620 << "binding patterns."
00621 << std::endl;
00622 result = true;
00623 }
00624 break;
00625 }
00626 default:
00627 break;
00628 }
00629
00630 for (size_t i = 0; i < ast->children.size(); i++) {
00631 if (hasPatternBindings(errStream, ast->children[i]))
00632 result = true;
00633 }
00634
00635 return result;
00636 }
00637
00638
00639
00640 static bool
00641 SimplifyAST(std::ostream& errStream, const GCPtr<AST>& ast)
00642 {
00643 bool result = true;
00644
00645 switch(ast->astType) {
00646 case at_and:
00647 case at_or:
00648 {
00649
00650 if (ast->children.size() > 2) {
00651 GCPtr<AST> newAST = new AST(ast->astType, ast->loc);
00652
00653 newAST->symType = ast->symType;
00654 newAST->scheme = ast->scheme;
00655 newAST->uocInfo = ast->uocInfo;
00656 newAST->expr = ast->expr;
00657 newAST->isDecl = false;
00658
00659 for (size_t ndx = 1; ndx < ast->children.size(); ndx++)
00660 newAST->children.append(ast->child(ndx));
00661
00662 while(ast->children.size() > 2)
00663 ast->children.remove(1);
00664
00665 ast->children[1] = newAST;
00666 }
00667
00668 break;
00669 }
00670
00671 default:
00672 break;
00673 }
00674
00675 for (size_t i = 0; i < ast->children.size(); i++) {
00676 if (!SimplifyAST(errStream, ast->children[i]))
00677 result = false;
00678 }
00679
00680 return result;
00681 }
00682
00683
00684
00685 static char *kwd_blacklist[] = {
00686 "BitcArray",
00687 "BitcDouble_t",
00688 "BitcFloat_t",
00689 "BitcInt16_t",
00690 "BitcInt32_t",
00691 "BitcInt64_t",
00692 "BitcInt8_t",
00693 "BitcPair",
00694 "BitcQuad_t",
00695 "BitcString",
00696 "BitcUnit_t",
00697 "BitcUns16_t",
00698 "BitcUns32_t",
00699 "BitcUns64_t",
00700 "BitcUns8_t",
00701 "BitcVector",
00702 "BitcWord_t",
00703 "asm",
00704 "auto",
00705 "bool",
00706 "break",
00707 "case",
00708 "catch",
00709 "cdecl",
00710 "char",
00711 "class",
00712 "const",
00713 "const_cast",
00714 "continue",
00715 "default",
00716 "defined",
00717 "delete",
00718 "do",
00719 "double",
00720 "dynamic_cast",
00721 "else",
00722 "entry",
00723 "enum",
00724 "explicit",
00725 "extern",
00726 "false",
00727 "far",
00728 "float",
00729 "for",
00730 "fortran",
00731 "friend",
00732 "generic",
00733 "globaldef",
00734 "globalref",
00735 "globalvalue",
00736 "goto",
00737 "huge",
00738 "if",
00739 "inline",
00740 "int",
00741 "int16",
00742 "int32",
00743 "int64",
00744 "int8",
00745 "interface",
00746 "long",
00747 "mutable",
00748 "namespace",
00749 "near",
00750 "new",
00751 "operator",
00752 "pascal",
00753 "pragma",
00754 "private",
00755 "protected",
00756 "public",
00757 "quad",
00758 "readonly",
00759 "register",
00760 "reinterpret_cast",
00761 "return",
00762 "short",
00763 "signed",
00764 "sizeof",
00765 "static",
00766 "static_cast",
00767 "string",
00768 "struct",
00769 "super",
00770 "switch",
00771 "template",
00772 "this",
00773 "throw",
00774 "true",
00775 "try",
00776 "typedef",
00777 "typeid",
00778 "typename",
00779 "uint16",
00780 "uint32",
00781 "uint64",
00782 "uint8",
00783 "union",
00784 "unsigned",
00785 "use",
00786 "using",
00787 "virtual",
00788 "void",
00789 "volatile",
00790 "while",
00791 "word",
00792
00793
00794 0
00795 };
00796 enum { nkwd = (sizeof(kwd_blacklist)/sizeof(kwd_blacklist[0])) - 1 };
00797
00798 int istrcmp(const void *vp1, const void *vp2)
00799 {
00800 const char *s1 = *((const char **) vp1);
00801 const char *s2 = *((const char **) vp2);
00802 return strcmp(s1, s2);
00803 }
00804
00805 bool is_kwd(const std::string& s)
00806 {
00807 const char *cs = s.c_str();
00808
00809 if (bsearch(&cs, kwd_blacklist, nkwd, sizeof(kwd_blacklist[0]), istrcmp))
00810 return true;
00811 return false;
00812 }
00813
00814 const struct MangleMap {
00815 char c;
00816 const char *s;
00817 } mangleMap[] = {
00818 { '#', "_SH" },
00819 { '!', "_EX" },
00820 { '$', "_DL" },
00821 { '%', "_PC" },
00822 { '*', "_ST" },
00823 { '+', "_PL" },
00824 { '\\', "_RS" },
00825 { '-', "_HY" },
00826 { '/', "_FS" },
00827 { '<', "_LT" },
00828 { '>', "_GT" },
00829 { '=', "_EQ" },
00830 { '?', "_QU" },
00831 { '@', "_AT" },
00832 { '_', "_US" },
00833 { '~', "_TL" },
00834
00835
00836 { '.', "::" },
00837 #ifdef NAMESPACE
00838 { ':', ":" },
00839 #else
00840 { ':', "__" },
00841 #endif
00842 };
00843 enum { nSpecial = sizeof(mangleMap) / sizeof(MangleMap) };
00844
00845 std::string
00846 mangleComponent(const std::string& s)
00847 {
00848 stringstream ss;
00849
00850 for (size_t i = 0; i < s.size(); i++) {
00851 if (isalnum(s[i])) {
00852 ss << s[i];
00853 }
00854 else {
00855 size_t sp;
00856 for (sp = 0; sp < nSpecial; sp++) {
00857 if (mangleMap[sp].c == s[i]) {
00858 ss << mangleMap[sp].s;
00859 break;
00860 }
00861 }
00862
00863
00864 assert(sp != nSpecial);
00865 }
00866 }
00867
00868 std::string os = ss.str();
00869 #if 0
00870 return (is_kwd(os) ? ('_' + os) : os);
00871 #else
00872 return 'I' + os;
00873 #endif
00874 }
00875
00876 static std::string
00877 xmangle(std::string s, const char *pfx)
00878 {
00879 stringstream ss;
00880
00881 size_t pos;
00882
00883 while((pos = s.find(".")) != std::string::npos) {
00884 ss << mangleComponent(s.substr(0, pos));
00885 #ifdef NAMESPACE
00886 ss << "::";
00887 #else
00888 ss << "__";
00889 #endif
00890 s = s.substr(pos+1);
00891 }
00892
00893 ss << pfx;
00894 ss << mangleComponent(s);
00895
00896 return ss.str();
00897 }
00898
00899 static inline std::string
00900 xmangle(const FQName& fqn, const char *pfx)
00901 {
00902 return xmangle(fqn.asString("."), pfx);
00903 }
00904
00905 static std::string
00906 idname(GCPtr<AST> ast, const char *pfx = "")
00907 {
00908 if (ast->isGlobal())
00909 return xmangle(ast->fqn, pfx);
00910
00911 if (ast->identFlags & ID_IS_GENSYM)
00912 return ast->s;
00913
00914 return xmangle(ast->s, pfx);
00915 }
00916
00917 #define CD_FNCONST 1u
00918 #define CD_IN_STRUCT 2u
00919 std::string
00920 c_decl(TvPrinter& tvp, GCPtr<Type> ty, const std::string& id,
00921 unsigned flags = 0)
00922 {
00923 stringstream ss;
00924 std::string sep = " ";
00925
00926 ty = ty->getType();
00927
00928 if (ty->kind == ty_mutable) {
00929 ss << c_decl(tvp, ty->components[0]->typ, id, flags & ~CD_FNCONST);
00930 return ss.str();
00931 }
00932
00933
00934 switch(ty->kind) {
00935
00936 case ty_bool:
00937 ss << "bool";
00938 break;
00939 case ty_char:
00940 ss << "BitcChar_t";
00941 break;
00942 case ty_string:
00943 ss << "BitcString_t *";
00944 break;
00945 case ty_int8:
00946 ss << "BitcInt8_t";
00947 break;
00948 case ty_int16:
00949 ss << "BitcInt16_t";
00950 break;
00951 case ty_int32:
00952 ss << "BitcInt32_t";
00953 break;
00954 case ty_int64:
00955 ss << "BitcInt64_t";
00956 break;
00957 case ty_uint8:
00958 ss << "BitcUns8_t";
00959 break;
00960 case ty_uint16:
00961 ss << "BitcUns16_t";
00962 break;
00963 case ty_uint32:
00964 ss << "BitcUns32_t";
00965 break;
00966 case ty_uint64:
00967 ss << "BitcUns64_t";
00968 break;
00969 case ty_word:
00970 ss << "BitcWord_t";
00971 break;
00972 case ty_float:
00973 ss << "BitcFloat_t";
00974 break;
00975 case ty_double:
00976 ss << "BitcDouble_t";
00977 break;
00978 case ty_quad:
00979 ss << "BitcQuad_t";
00980 break;
00981
00982 case ty_bitfield:
00983 {
00984 ss << c_decl(tvp, ty->components[0]->typ, "");
00985 break;
00986 }
00987
00988 case ty_tvar:
00989 ss << tvp.tvName(ty);
00990 break;
00991
00992 case ty_unionv:
00993 case ty_unionr:
00994 case ty_structv:
00995 case ty_structr:
00996 case ty_closure:
00997 {
00998 GCPtr<AST> defAst = ty->defAst;
00999 ss << idname(defAst);
01000
01001 if (ty->typeArgs.size()) {
01002 ss << "< ";
01003
01004 for (size_t tparam = 0; tparam < ty->typeArgs.size(); tparam++) {
01005 GCPtr<Type> targ = ty->typeArgs[tparam]->getType();
01006
01007 if (tparam > 0)
01008 ss << ", ";
01009 ss << c_decl(tvp, targ, "");
01010 }
01011
01012 ss << " >";
01013 }
01014 if (ty->kind == ty_unionr ||
01015 ty->kind == ty_structr ||
01016 ty->kind == ty_closure)
01017 ss << " *";
01018 }
01019 break;
01020
01021 case ty_ref:
01022 {
01023 assert(ty->components.size() == 1);
01024 ss << "BitcRef< " << c_decl(tvp, ty->components[0]->typ, "")
01025 << " >";
01026
01027 break;
01028 }
01029
01030 case ty_vector:
01031 {
01032 assert(ty->components.size() == 1);
01033 ss << "BitcVector< " << c_decl(tvp, ty->components[0]->typ, "")
01034 << " > *";
01035 break;
01036 }
01037
01038 case ty_array:
01039 {
01040 assert(ty->components.size() == 1);
01041 ss << "BitcArray< " << c_decl(tvp, ty->components[0]->typ, "")
01042 << ", "
01043 << ty->components[0]->typ->getType()->arrlen
01044 << " >";
01045 break;
01046 }
01047
01048 case ty_pair:
01049 {
01050 assert(ty->components.size() == 2);
01051 ss << "BitcPair< "
01052 << c_decl(tvp, ty->components[0]->typ, "")
01053 << ", "
01054 << c_decl(tvp, ty->components[1]->typ, "")
01055 << " >";
01056 break;
01057 }
01058
01059 case ty_fn:
01060 {
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 assert(ty->components.size() == 2);
01090
01091
01092 ss << c_decl(tvp, ty->components[1]->typ, "");
01093
01094 ss << ((flags & CD_FNCONST) ? " " : " (*");
01095 sep = "";
01096
01097 break;
01098 }
01099
01100 default:
01101 ss << "/* UNHANDLED TYPE " << ty->kindName() << " */";
01102 break;
01103 }
01104
01105 if (id.size())
01106 ss << sep << id;
01107
01108
01109
01110 switch(ty->kind) {
01111 case ty_bitfield:
01112 {
01113 if (flags & CD_IN_STRUCT)
01114 ss << ":" << ty->Isize;
01115 break;
01116 }
01117
01118 case ty_fn:
01119 {
01120 ss << ((flags & CD_FNCONST) ? "(" : ")(");
01121
01122 GCPtr<Type> fnargs = ty->components[0]->typ->getType();
01123
01124 for (size_t i = 0; i < fnargs->components.size(); i++) {
01125 if (i > 0) ss << ", ";
01126 ss << c_decl(tvp, fnargs->components[i]->typ, "");
01127 }
01128
01129 ss << ")";
01130
01131 break;
01132 }
01133
01134 case ty_bool:
01135 case ty_char:
01136 case ty_string:
01137 case ty_int8:
01138 case ty_int16:
01139 case ty_int32:
01140 case ty_int64:
01141 case ty_uint8:
01142 case ty_uint16:
01143 case ty_uint32:
01144 case ty_uint64:
01145 case ty_word:
01146 case ty_float:
01147 case ty_double:
01148 case ty_quad:
01149
01150 case ty_tvar:
01151 case ty_unionv:
01152 case ty_unionr:
01153 case ty_structv:
01154 case ty_structr:
01155 case ty_closure:
01156 case ty_ref:
01157 case ty_vector:
01158 case ty_pair:
01159
01160 break;
01161
01162 default:
01163 ss << "/* UNHANDLED POST-DECL " << ty->kindName() << " */";
01164 break;
01165 }
01166
01167 return ss.str();
01168 }
01169
01170 #if 0
01171 std::string
01172 c_name(GCPtr<AST> ast)
01173 {
01174 stringstream ss;
01175
01176 #if 0
01177 if (ast->defn)
01178 assert(ast = ast->defn);
01179 #endif
01180
01181 #if 0
01182 GCPtr<Type> ty = ast->getType();
01183
01184 if (ast->isGlobal) {
01185 switch(ty->kind) {
01186 case ty_tvar:
01187 ss << "T_";
01188 break;
01189 case ty_fn:
01190 ss << "F_";
01191 break;
01192 case ty_structv:
01193 ss << "S_";
01194 break;
01195 case ty_unionv:
01196 ss << "U_";
01197 break;
01198 case ty_structr:
01199 case ty_closure:
01200 ss << "RS_";
01201 break;
01202 case ty_unionr:
01203 ss << "RU_";
01204 break;
01205 case ty_array:
01206 ss << "V_";
01207 break;
01208 case ty_vector:
01209 ss << "V_";
01210 break;
01211 case ty_ref:
01212 ss << "V_";
01213 break;
01214 default:
01215 ss << "UNK_";
01216 break;
01217 }
01218 }
01219 #endif
01220
01221 ss << mangle(ast);
01222
01223 return ss.str();
01224 }
01225 #endif
01226
01227 static std::string
01228 EmitTypeScheme(TvPrinter& tvp, const GCPtr<AST>& id, DeclsOrDefs what)
01229 {
01230 stringstream ss;
01231
01232 const GCPtr<TypeScheme>& scm = id->scheme;
01233 if (!scm || scm->ftvs.size() == 0)
01234 return "";
01235
01236 ss << "template<";
01237 for (size_t i = 0; i < scm->ftvs.size(); i++) {
01238 GCPtr<Type> ty = scm->ftvs[i]->getType();
01239 assert(ty->kind == ty_tvar);
01240
01241 if (i > 0) ss << ", ";
01242 ss << "typename " << tvp.tvName(ty);
01243 }
01244 ss << ">";
01245
01246 if (what == WantDecl)
01247 ss << "\n";
01248 else
01249 ss << " ";
01250
01251 return ss.str();
01252 }
01253
01254 std::string
01255 EmitTypeExpansion(TvPrinter& tvp, const GCPtr<AST>& id, DeclsOrDefs what)
01256 {
01257 stringstream ss;
01258
01259 const GCPtr<TypeScheme>& scm = id->scheme;
01260 if (!scm || scm->ftvs.size() == 0)
01261 return "";
01262
01263 ss << "<";
01264 for (size_t i = 0; i < scm->ftvs.size(); i++) {
01265 GCPtr<Type> ty = scm->ftvs[i]->getType();
01266 assert(ty->kind == ty_tvar);
01267
01268 if (i > 0) ss << ", ";
01269 ss << tvp.tvName(ty);
01270 }
01271 ss << ">";
01272 return ss.str();
01273 }
01274
01275 static void
01276 EmitExpr(INOstream& ino, TvPrinter& tvp, GCPtr<AST> ast)
01277 {
01278 switch(ast->astType) {
01279 case at_ibegin:
01280 case at_begin:
01281 {
01282 ino << "({ ";
01283 ino.indent(3);
01284
01285 for (size_t i = 0; i < ast->children.size(); i++) {
01286 if (i > 0) ino << ", ";
01287 EmitExpr(ino, tvp, ast->child(i));
01288 }
01289
01290 ino.indent(-3);
01291 ino << " ;})";
01292
01293 break;
01294 }
01295 #if 0
01296 case at_identPattern:
01297 {
01298 EmitExpr(ino, tvp, ast->child(0));
01299 break;
01300 }
01301 #endif
01302
01303 case at_ident:
01304 {
01305 ino << idname(ast);
01306 break;
01307 }
01308
01309 case at_if:
01310 {
01311 ino << "(";
01312 EmitExpr(ino, tvp, ast->child(0));
01313 ino << std::endl;
01314 ino.more();
01315 ino << "? ";
01316 EmitExpr(ino, tvp, ast->child(1));
01317 ino << std::endl;
01318 ino << ": ";
01319 EmitExpr(ino, tvp, ast->child(2));
01320 ino << ")";
01321 ino << std::endl;
01322
01323 ino.less();
01324 break;
01325 }
01326
01327 case at_and:
01328 {
01329 assert(ast->children.size() == 2);
01330
01331 ino << "({ ";
01332 ino.indent(3);
01333
01334 ino << c_decl(tvp, ast->child(0)->getType(), "_tmp", 0);
01335 ino << " = ";
01336 EmitExpr(ino, tvp, ast->child(0));
01337 ino << ";" << std::endl;
01338
01339 ino << "(_tmp ? ";
01340 EmitExpr(ino, tvp, ast->child(1));
01341 ino << std::endl;
01342 ino.indent(6);
01343 ino << ": _tmp) ;})";
01344 ino << std::endl;
01345 ino.indent(-6);
01346 ino.indent(-3);
01347
01348 break;
01349 }
01350
01351 case at_or:
01352 {
01353 assert(ast->children.size() == 2);
01354
01355 ino << "({ ";
01356 ino.indent(3);
01357
01358 ino << c_decl(tvp, ast->child(0)->getType(), "_tmp", 0);
01359 ino << " = ";
01360 EmitExpr(ino, tvp, ast->child(0));
01361 ino << ";" << std::endl;
01362
01363 ino << "(_tmp ? _tmp" << std::endl;
01364 ino.indent(6);
01365 ino << ": ";
01366 EmitExpr(ino, tvp, ast->child(1));
01367 ino << ") ;})";
01368 ino << std::endl;
01369 ino.indent(-6);
01370 ino.indent(-3);
01371
01372 break;
01373 }
01374
01375 case at_pair:
01376 case at_cpair:
01377 {
01378 ino << "BitcPair< "
01379 << c_decl(tvp, ast->child(0)->getType(), "")
01380 << ", "
01381 << c_decl(tvp, ast->child(1)->getType(), "")
01382 << " >(";
01383 EmitExpr(ino, tvp, ast->child(0));
01384 ino << ", ";
01385 EmitExpr(ino, tvp, ast->child(1));
01386 ino << ")";
01387 break;
01388 }
01389
01390 case at_vector:
01391 {
01392 ino << "({ "
01393 << c_decl(tvp, ast->getType(), "")
01394 << " *_tmp;" << std::endl;
01395
01396 ino.indent(3);
01397 ino << "void (*_markfn)("
01398 << c_decl(tvp, ast->getType(), "")
01399 << " *&) = gcMark;" << std::endl;
01400
01401 ino << "_tmp = "
01402 << std::endl;
01403 ino.more();
01404 ino << "( " << c_decl(tvp, ast->getType(), "")
01405 << " *)";
01406 ino << " allocate(sizeof(*_tmp) + sizeof("
01407 << c_decl(tvp, ast->child(0)->getType(), "")
01408 << ") * " << ast->children.size()
01409 << ", "
01410 << "(void (*)(...))_markfn"
01411 << ");" << std::endl;
01412 ino.less();
01413
01414 ino << "_tmp->length = "
01415 << ast->children.size() << ";"
01416 << std::endl;
01417
01418 for (size_t c = 0; c < ast->children.size(); c++) {
01419 ino << "_tmp->elements[" << c << "] = ";
01420 EmitExpr(ino, tvp, ast->child(c));
01421 ino << ";" << std::endl;
01422 }
01423
01424 ino << "_tmp ;})";
01425 ino.indent(-3);
01426 break;
01427 }
01428
01429 case at_makevector:
01430 {
01431 ino << "({ "
01432 << c_decl(tvp, ast->child(0)->getType(), "_len")
01433 << " = ";
01434 EmitExpr(ino, tvp, ast->child(0));
01435 ino << ";" << std::endl;
01436
01437 ino.indent(3);
01438
01439 ino << c_decl(tvp, ast->child(1)->getType(), "_e")
01440 << " = ";
01441 EmitExpr(ino, tvp, ast->child(1));
01442 ino << ";" << std::endl;
01443
01444 ino << c_decl(tvp, ast->getType(), "")
01445 << " *_tmp;" << std::endl;
01446
01447 ino << "void (*_markfn)("
01448 << c_decl(tvp, ast->getType(), "")
01449 << " *&) = gcMark;" << std::endl;
01450
01451 ino << "_tmp = "
01452 << std::endl;
01453 ino.more();
01454 ino << "( " << c_decl(tvp, ast->getType(), "")
01455 << " *)";
01456 ino << " allocate(sizeof(*_tmp) + sizeof("
01457 << c_decl(tvp, ast->child(1)->getType(), "")
01458 << ") * _len, "
01459 << "(void (*)(...))_markfn"
01460 << ");" << std::endl;
01461 ino.less();
01462
01463 ino << "_tmp->length = _len;"
01464 << std::endl;
01465
01466 ino << "for(BitcWord_t ndx = 0; ndx < _len; ndx++)"
01467 << std::endl;
01468 ino.more();
01469 ino << "_tmp->elements[ndx] = _e;" << std::endl;
01470 ino.less();
01471
01472 ino << "_tmp ;})";
01473 ino.indent(-3);
01474 break;
01475 }
01476
01477 case at_array:
01478 {
01479 ino << "({ "
01480 << c_decl(tvp, ast->getType(), "")
01481 << " _tmp;" << std::endl;
01482
01483 ino.indent(3);
01484
01485 for (size_t c = 0; c < ast->children.size(); c++) {
01486 ino << "_tmp.elements[" << c << "] = ";
01487 EmitExpr(ino, tvp, ast->child(c));
01488 ino << ";" << std::endl;
01489 }
01490
01491 ino << "_tmp ;})";
01492 ino.indent(-3);
01493 break;
01494 }
01495
01496 case at_array_length:
01497 {
01498 GCPtr<Type> ty = ast->child(0)->getType();
01499
01500 ino << "({ ";
01501 EmitExpr(ino, tvp, ast->child(0));
01502 ino << "," << std::endl;
01503
01504 ino << ty->arrlen
01505 << " ;})";
01506 break;
01507 }
01508
01509 case at_vector_length:
01510 {
01511 ino << "({ "
01512 << c_decl(tvp, ast->child(0)->getType(), " *_tmp = ")
01513 << std::endl;
01514 ino.indent(3);
01515 ino.more();
01516 EmitExpr(ino, tvp, ast->child(0));
01517 ino << ";" << std::endl;
01518 ino.less();
01519 ino << "_tmp->length ;})";
01520 ino.indent(-3);
01521 break;
01522 }
01523 case at_array_ref:
01524 {
01525 EmitExpr(ino, tvp, ast->child(0));
01526 ino << ".elements[";
01527 EmitExpr(ino, tvp, ast->child(1));
01528 ino << "]";
01529 break;
01530 }
01531 case at_vector_ref:
01532 {
01533 EmitExpr(ino, tvp, ast->child(0));
01534 ino << "->elements[";
01535 EmitExpr(ino, tvp, ast->child(1));
01536 ino << "]";
01537 break;
01538 }
01539
01540 case at_deref:
01541 {
01542 ino << "*(";
01543 EmitExpr(ino, tvp, ast->child(0));
01544 ino << ")";
01545 break;
01546 }
01547
01548 case at_select:
01549 {
01550 EmitExpr(ino, tvp, ast->child(0));
01551 ino << "."
01552 << idname(ast->child(1));
01553 break;
01554 }
01555
01556 case at_setbang:
01557 {
01558 ino << "({ "
01559 << c_decl(tvp, ast->child(0)->getType(), "& _target")
01560 << " = ";
01561 EmitExpr(ino, tvp, ast->child(0));
01562 ino << ";" << std::endl;
01563 ino.indent(3);
01564 ino << "_target = ";
01565 EmitExpr(ino, tvp, ast->child(1));
01566 ino << "; _target ;})" << std::endl;
01567 ino.indent(-3);
01568 break;
01569 }
01570
01571 case at_charLiteral:
01572 {
01573 std::streamsize w = ino.ostrm.width();
01574 char fillChar = ino.ostrm.fill('0');
01575
01576 ino.ostrm << right << oct;
01577
01578 ino << "'\\";
01579 ino << ast->litValue.c;
01580 ino.ostrm << dec;
01581 ino.ostrm.width(w);
01582 ino.ostrm.fill(fillChar);
01583 ino << "'";
01584
01585 break;
01586 }
01587
01588 case at_boolLiteral:
01589 {
01590 ino << (ast->litValue.b
01591 ? "true"
01592 : "false");
01593 break;
01594 }
01595
01596 case at_intLiteral:
01597 {
01598
01599
01600
01601
01602
01603
01604 GCPtr<Type> ty = ast->getType();
01605
01606 char valStr[mpz_sizeinbase(ast->litValue.i, 10)];
01607 mpz_get_str(valStr, 10, ast->litValue.i);
01608
01609 assert(ty->kind != ty_structv);
01610 ino << valStr;
01611
01612 break;
01613 }
01614
01615 case at_floatLiteral:
01616 {
01617 GCPtr<Type> ty = ast->getType();
01618
01619
01620
01621 double d = mpf_get_d(ast->litValue.d);
01622
01623 assert(ty->kind != ty_structv);
01624 ino << d;
01625
01626 break;
01627 }
01628 case at_stringLiteral:
01629
01630 {
01631
01632 const char *s = ast->litValue.s.c_str();
01633 const char *sbegin = s;
01634
01635 ino << "mkStringLiteral(\"";
01636
01637 std::streamsize w = ino.ostrm.width();
01638 char fillChar = ino.ostrm.fill('0');
01639
01640 ino.ostrm << right << oct;
01641
01642 while ((size_t)(s - sbegin) < ast->litValue.s.size())
01643 ino << "\\" << LitValue::DecodeRawCharacter(s, &s);
01644
01645 ino.ostrm << dec;
01646 ino.ostrm.width(w);
01647 ino.ostrm.fill(fillChar);
01648
01649 ino << "\")";
01650
01651 break;
01652 }
01653
01654 case at_case:
01655 case at_cond:
01656 case at_let:
01657 case at_letrec:
01658 case at_loop:
01659 case at_throw:
01660 case at_try:
01661 case at_unit:
01662 case at_apply:
01663 case at_struct_apply:
01664 case at_ucon_apply:
01665 default:
01666 {
01667 ino << "/* AST " << ast->ID << ": " << ast->astTypeName()
01668 << " */" << std::endl;
01669 ino << ast->astTypeName() << " IS NOT IMPLEMENTED IN EmitExpr YET"
01670 << std::endl;
01671 assert(false);
01672 break;
01673 }
01674 }
01675 }
01676
01677 static void
01678 EmitDeclValue(INOstream& ino, GCPtr<AST> ast, DeclsOrDefs what)
01679 {
01680 if (what != WantForward)
01681 return;
01682
01683 GCPtr<AST> id = ast->child(0);
01684
01685 TvPrinter tvp("TV_");
01686
01687
01688
01689
01690 ino << EmitTypeScheme(tvp, id, what)
01691 << "extern " << c_decl(tvp, id->getType(), idname(id),
01692 id->isGlobal() ? CD_FNCONST : 0)
01693 << ";" << std::endl;
01694 }
01695
01696 static void
01697 EmitDefine(INOstream& ino, GCPtr<AST> ast, DeclsOrDefs what)
01698 {
01699 GCPtr<AST> idPattern = ast->child(0);
01700 GCPtr<AST> id = idPattern->child(0);
01701
01702 TvPrinter tvp("TV_");
01703
01704 if (what == WantDefs) {
01705 ino << "/* AST " << ast->ID << " " << ast->astTypeName()
01706 << " " << id->s << " (" << id->fqn.asString() << ")"
01707 << " */" << std::endl;
01708
01709 switch(id->getType()->kind) {
01710 case ty_fn:
01711 {
01712 GCPtr<AST> lambda = ast->child(1);
01713 GCPtr<AST> args = lambda->child(0);
01714 GCPtr<AST> body = lambda->child(1);
01715
01716 ino << EmitTypeScheme(tvp, id, what)
01717 << c_decl(tvp, id->getType()->components[1]->typ, "")
01718 << std::endl << idname(id)
01719 << "(";
01720
01721 for (size_t arg = 0; arg < args->children.size(); arg++) {
01722 GCPtr<AST> idPattern = args->child(arg);
01723 GCPtr<AST> id = idPattern->child(0);
01724
01725 if (arg > 0) ino << ", ";
01726 ino << c_decl(tvp, id->getType(), idname(id));
01727 }
01728
01729 ino << ")" << std::endl;
01730 ino << "{" << std::endl;
01731 ino.more();
01732
01733 ino << "return ";
01734 ino.indent(7);
01735
01736 EmitExpr(ino, tvp, body);
01737 ino << ";" << std::endl;
01738 ino.indent(-7);
01739
01740 ino.less();
01741 ino << "}" << std::endl;
01742
01743 ino << std::endl;
01744 break;
01745 }
01746 default:
01747 {
01748 GCPtr<AST> body = ast->child(1);
01749 ino << c_decl(tvp, id->getType(), idname(id),
01750 id->isGlobal() ? CD_FNCONST : 0)
01751 << " = ";
01752 EmitExpr(ino, tvp, body);
01753 ino << ";" << std::endl;
01754 break;
01755 }
01756 }
01757 }
01758 else if (what == WantDecl) {
01759
01760
01761
01762 ino << EmitTypeScheme(tvp, id, what)
01763 << "extern " << c_decl(tvp, id->getType(), idname(id),
01764 id->isGlobal() ? CD_FNCONST : 0)
01765 << ";" << std::endl;
01766 }
01767 }
01768
01769 static void
01770 EmitDefexcept(INOstream& ino, GCPtr<AST> ast, DeclsOrDefs what)
01771 {
01772 GCPtr<AST> id = ast->child(0);
01773
01774
01775 assert(id->symType->isRefType());
01776
01777
01778
01779 assert(id->scheme->ftvs.size() == 0);
01780
01781 TvPrinter tvp("TV_");
01782
01783 if (what == WantForward) {
01784 ino << "struct " << idname(id) << ";" << std::endl;
01785 }
01786 else if (what == WantDecl) {
01787 ino << "struct " << idname(id) << ":public BitcException {"
01788 << " /* " << id->fqn.asString() << " */" << std::endl;
01789
01790 ino.more();
01791
01792 ino << "static BitcWord_t tagValue;" << std::endl;
01793
01794 ino << idname(id) << "()" << std::endl;
01795 ino << ": BitcException(&tagValue)" << std::endl;
01796 ino << "{ }" << std::endl;
01797
01798 for (size_t i = 0; i < ast->children.size() - 1; i++) {
01799 GCPtr<AST> fld = ast->child(i+1);
01800
01801 stringstream argName;
01802 argName << "arg" << i;
01803
01804 ino << c_decl(tvp, fld->getType(), argName.str())
01805 << ";" << std::endl;
01806 }
01807
01808 ino.less();
01809 ino << "};" << std::endl;
01810 }
01811 else if (what == WantGC) {
01812
01813 ino << "inline void gcMark(" << idname(id)
01814 << "*& pob"
01815 << ")" << std::endl
01816 << "{" << std::endl;
01817 ino.more();
01818
01819 if (ast->children.size() > 1) {
01820 ino << idname(id)
01821 << EmitTypeExpansion(tvp, id, what)
01822 << "& ob __attribute__((unused)) = *pob;" << std::endl;
01823
01824 for (size_t ndx = 0; ndx < ast->children.size() - 1; ndx++) {
01825 GCPtr<AST> fld = ast->child(ndx+1);
01826
01827 if (!fld->symType->isAtomic())
01828 ino << "gcMark(ob.arg" << ndx << ");" << std::endl;
01829 }
01830 }
01831
01832 ino.less();
01833 ino << "}" << std::endl;
01834 }
01835 else if (what == WantConstructors) {
01836
01837 ino << "BitcWord_t " << idname(id)
01838 << "::tagValue = 0;" << std::endl;
01839
01840
01841
01842 if (ast->children.size() == 1) {
01843 ino << idname(id)
01844 << " the" << idname(id)
01845 << ";" << std::endl;
01846
01847 return;
01848 }
01849
01850
01851
01852 ino << "inline " << idname(id)
01853 << "* C" << idname(id) << "(";
01854
01855 for (size_t ndx = 0; ndx < ast->children.size()-1; ndx++) {
01856 GCPtr<AST> arg = ast->child(ndx+1);
01857
01858 stringstream ss;
01859 ss << "arg" << ndx;
01860
01861 if (ndx > 0) ino << ", ";
01862 ino << c_decl(tvp, arg->getType(), ss.str());
01863 }
01864
01865 ino << ")" << std::endl;
01866
01867 ino << "{" << std::endl;
01868 ino.more();
01869
01870 ino << "void (*_markfn)(" << idname(id)
01871 << EmitTypeExpansion(tvp, id, what)
01872 << "*&) = gcMark;" << std::endl;
01873
01874 ino << idname(id)
01875 << "* _pInstance = ("
01876 << idname(id)
01877 << "*)" << std::endl;
01878
01879 ino << " allocate(sizeof("
01880 << idname(id)
01881 << "), "
01882 << "(void (*)(...))_markfn"
01883 << ");" << std::endl;
01884
01885 ino << idname(id)
01886 << "& _instance = *_pInstance;" << std::endl << std::endl;
01887
01888
01889
01890 ino << "_instance.tag = &"
01891 << idname(id)
01892 << "::tagValue;" << std::endl;
01893
01894 for (size_t ndx = 0; ndx < ast->children.size()-1; ndx++) {
01895 GCPtr<AST> arg = ast->child(ndx);
01896
01897 ino << "_instance.arg" << ndx
01898 << " = " << "arg" << ndx
01899 << ";" << std::endl;
01900 }
01901
01902 ino << "return &_instance;" << std::endl;
01903
01904 ino.less();
01905 ino << "}" << std::endl;
01906 }
01907 }
01908
01909 static void
01910 EmitDefstruct(INOstream& ino, GCPtr<AST> ast, DeclsOrDefs what)
01911 {
01912 GCPtr<AST> id = ast->child(0);
01913
01914
01915
01916
01917
01918 TvPrinter tvp("TV_");
01919
01920 if (what == WantForward) {
01921 ino << EmitTypeScheme(tvp, id, what)
01922 << "struct " << idname(id) << ";" << std::endl;
01923
01924 ino << EmitTypeScheme(tvp, id, what)
01925 << "extern " << idname(id,"C") << "(";
01926
01927 GCPtr<AST> fields = ast->children[4];
01928 for (size_t i = 0; i < fields->children.size(); i++) {
01929 GCPtr<AST> field = fields->children[i];
01930 GCPtr<AST> fname = field->children[0];
01931
01932 if (i > 0) ino << ", ";
01933 ino << c_decl(tvp, fname->getType(), "");
01934 }
01935
01936 ino << ");" << std::endl;
01937 return;
01938 }
01939 else if (what == WantDecl) {
01940 ino << EmitTypeScheme(tvp, id, what)
01941 << "struct " << idname(id) << " {"
01942 << " /* " << id->fqn.asString() << " */" << std::endl;
01943
01944 ino.more();
01945
01946 GCPtr<AST> fields = ast->children[4];
01947 for (size_t i = 0; i < fields->children.size(); i++) {
01948 GCPtr<AST> field = fields->children[i];
01949 GCPtr<AST> fname = field->children[0];
01950 ino << c_decl(tvp, fname->getType(), idname(fname), CD_IN_STRUCT)
01951 << ";" << std::endl;
01952 }
01953 ino.less();
01954
01955 ino << "};" << std::endl;
01956 }
01957 else if (what == WantGC) {
01958 GCPtr<AST> fields = ast->children[4];
01959
01960
01961 ino << EmitTypeScheme(tvp, id, what)
01962 << "inline void gcMark(" << idname(id)
01963 << EmitTypeExpansion(tvp, id, what)
01964 << (id->symType->isRefType()? "*& pob" : "& ob")
01965 << ")" << std::endl
01966 << "{" << std::endl;
01967 ino.more();
01968
01969 if (id->symType->isRefType()) {
01970 ino << idname(id)
01971 << EmitTypeExpansion(tvp, id, what)
01972 << "& ob __attribute__((unused)) = *pob;" << std::endl;
01973 }
01974
01975 for (size_t i = 0; i < fields->children.size(); i++) {
01976 GCPtr<AST> field = fields->children[i];
01977 GCPtr<AST> fname = field->children[0];
01978
01979 if (!fname->symType->isAtomic())
01980 ino << "gcMark(ob." << idname(fname) << ");" << std::endl;
01981 }
01982 ino.less();
01983 ino << "}" << std::endl;
01984 }
01985 else if (what == WantConstructors) {
01986 GCPtr<AST> fields = ast->children[4];
01987
01988
01989
01990 ino << EmitTypeScheme(tvp, id, what)
01991 << "inline " << idname(id)
01992 << EmitTypeExpansion(tvp, id, what)
01993 << (id->symType->isRefType() ? "*" : "")
01994 << " "
01995 << idname(id,"C") << "(";
01996
01997 for (size_t i = 0; i < fields->children.size(); i++) {
01998 GCPtr<AST> field = fields->children[i];
01999 GCPtr<AST> fname = field->children[0];
02000 if (i > 0) ino << ", ";
02001 ino << c_decl(tvp, fname->getType(), idname(fname));
02002 }
02003
02004 ino << ")" << std::endl;
02005 ino << "{" << std::endl;
02006 ino.more();
02007
02008 if (id->symType->isRefType()){
02009 ino << "void (*_markfn)(" << idname(id)
02010 << EmitTypeExpansion(tvp, id, what)
02011 << "*&) = gcMark;" << std::endl;
02012
02013 ino << idname(id)
02014 << EmitTypeExpansion(tvp, id, what)
02015 << "* _pInstance = ("
02016 << idname(id)
02017 << EmitTypeExpansion(tvp, id, what)
02018 << "*)" << std::endl;
02019 ino << " allocate(sizeof("
02020 << idname(id)
02021 << EmitTypeExpansion(tvp, id, what)
02022 << "), "
02023 << "(void (*)(...))_markfn"
02024 << ");" << std::endl;
02025
02026 ino << idname(id)
02027 << EmitTypeExpansion(tvp, id, what)
02028 << "& _instance = *_pInstance;" << std::endl;
02029 }
02030 else {
02031 ino << idname(id)
02032 << EmitTypeExpansion(tvp, id, what)
02033 << " _instance;" << std::endl;
02034 }
02035
02036 for (size_t i = 0; i < fields->children.size(); i++) {
02037 GCPtr<AST> field = fields->children[i];
02038 GCPtr<AST> fname = field->children[0];
02039 ino << "_instance." << idname(fname)
02040 << "= " << idname(fname) << ";" << std::endl;
02041 }
02042
02043 ino << "return "
02044 << (id->symType->isRefType() ? "&" : "")
02045 << "_instance;" << std::endl;
02046
02047 ino.less();
02048 ino << "}" << std::endl;
02049 }
02050 }
02051
02052 static void
02053 EmitDefunion(INOstream& ino, GCPtr<AST> ast, DeclsOrDefs what)
02054 {
02055 GCPtr<AST> id = ast->child(0);
02056 GCPtr<AST> legs = ast->children[4];
02057
02058
02059
02060
02061
02062 TvPrinter tvp("TV_");
02063
02064 if (what == WantForward) {
02065 ino << EmitTypeScheme(tvp, id, what)
02066 << "struct " << idname(id) << ";" << std::endl;
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076 for (size_t i = 0; i < legs->children.size(); i++) {
02077 GCPtr<AST> leg = legs->children[i];
02078 GCPtr<AST> cname = leg->children[0];
02079
02080 ino << EmitTypeScheme(tvp, id, what)
02081 << "extern struct "
02082 << idname(id)
02083 << ((leg->children.size() == 1) ? "& C" : " C")
02084 << idname(cname) << "(";
02085
02086 if (leg->children.size() > 1) {
02087 for (size_t ndx = 1; ndx < leg->children.size(); ndx++) {
02088 GCPtr<AST> arg = leg->child(ndx);
02089
02090 if (ndx > 0) ino << ", ";
02091 ino << c_decl(tvp, arg->getType(), "");
02092 }
02093 }
02094
02095 ino << ");" << std::endl;
02096 }
02097
02098 return;
02099 }
02100 else if (what == WantDecl) {
02101 ino << EmitTypeScheme(tvp, id, what)
02102 << "struct " << idname(id) << " {"
02103 << " /* " << id->fqn.asString() << " */" << std::endl;
02104
02105 bool needUnion = false;
02106
02107 ino.more();
02108
02109
02110 ino << "enum { " << std::endl;
02111
02112 ino.more();
02113
02114 for (size_t i = 0; i < legs->children.size(); i++) {
02115 GCPtr<AST> leg = legs->children[i];
02116 GCPtr<AST> cname = leg->children[0];
02117 if (leg->children.size() > 1)
02118 needUnion = true;
02119
02120
02121 ino << "tag" << idname(cname);
02122 if (i < (legs->children.size() - 1))
02123 ino << ", ";
02124 else
02125 ino << " ";
02126 ino << "/* "
02127 << cname->s
02128 << " */"
02129 << std::endl;
02130 }
02131
02132 ino.less();
02133
02134 ino << "} tag;" << std::endl;
02135
02136
02137
02138
02139
02140
02141
02142
02143 if (needUnion) {
02144 ino << "union {" << std::endl;
02145
02146
02147
02148 ino.more();
02149
02150 for (size_t i = 0; i < legs->children.size(); i++) {
02151 GCPtr<AST> leg = legs->children[i];
02152 GCPtr<AST> cname = leg->children[0];
02153 if (leg->children.size() > 1) {
02154 ino << "struct {" << std::endl;
02155 ino.more();
02156
02157 for (size_t ndx = 0; ndx < leg->children.size()-1; ndx++) {
02158 GCPtr<AST> arg = leg->child(ndx+1);
02159
02160 stringstream argName;
02161 argName << "arg" << ndx;
02162
02163 ino << c_decl(tvp, arg->getType(), argName.str(), CD_IN_STRUCT)
02164 << ";" << std::endl;
02165 }
02166 ino.less();
02167 ino << "} "<< idname(cname) << ";" << std::endl;
02168 }
02169 }
02170
02171 ino.less();
02172 ino << "} u;" << std::endl;
02173 }
02174
02175
02176
02177 for (size_t i = 0; i < legs->children.size(); i++) {
02178 GCPtr<AST> leg = legs->children[i];
02179 GCPtr<AST> cname = leg->children[0];
02180
02181 if (leg->children.size() == 1)
02182 ino << "static " << idname(id) << " "
02183 << idname(cname) << ";" << std::endl;
02184 }
02185
02186 ino.less();
02187 ino << "};" << std::endl;
02188 }
02189 else if (what == WantGC) {
02190 GCPtr<AST> fields = ast->children[4];
02191
02192
02193 ino << EmitTypeScheme(tvp, id, what)
02194 << "inline void gcMark(" << idname(id)
02195 << EmitTypeExpansion(tvp, id, what)
02196 << (id->symType->isRefType() ? "*& pob" : "& ob")
02197 << ")" << std::endl;
02198 ino << "{" << std::endl;
02199 ino.more();
02200 if (id->symType->isRefType()) {
02201 ino << idname(id)
02202 << EmitTypeExpansion(tvp, id, what)
02203 << "& ob __attribute__((unused))= *pob;" << std::endl;
02204 }
02205
02206 ino << "switch(ob.tag) {" << std::endl;
02207
02208 for (size_t i = 0; i < legs->children.size(); i++) {
02209 GCPtr<AST> leg = legs->children[i];
02210 GCPtr<AST> cname = leg->children[0];
02211
02212 ino << "case " << idname(id)
02213 << EmitTypeExpansion(tvp, id, what)
02214 << "::tag" << idname(cname) << ":" << endl;
02215 ino.more();
02216 ino << "{" << std::endl;
02217 ino.more();
02218
02219 if (leg->children.size() > 1) {
02220 for (size_t ndx = 0; ndx < leg->children.size()-1; ndx++) {
02221 GCPtr<AST> arg = leg->child(ndx+1);
02222
02223 stringstream argName;
02224 argName << "arg" << ndx;
02225
02226 if (!arg->symType->isAtomic())
02227 ino << "gcMark(ob.u." << idname(cname) << "."
02228 << argName.str() << ");" << std::endl;
02229 }
02230 }
02231 ino << "break;" << std::endl;
02232
02233 ino.less();
02234 ino << "}" << std::endl;
02235 ino.less();
02236 }
02237
02238 ino << "}" << std::endl;
02239
02240 ino.less();
02241 ino << "}" << std::endl;
02242
02243 }
02244 else if (what == WantConstructors) {
02245 for (size_t i = 0; i < legs->children.size(); i++) {
02246 GCPtr<AST> leg = legs->children[i];
02247 GCPtr<AST> cname = leg->children[0];
02248
02249
02250
02251
02252 if (leg->children.size() == 1) {
02253 ino << EmitTypeScheme(tvp, id, what)
02254 << idname(id)
02255 << EmitTypeExpansion(tvp, id, what)
02256 << " " << idname(id)
02257 << EmitTypeExpansion(tvp, id, what)
02258 << "::" << idname(cname)
02259 << " = { "
02260 << idname(id)
02261 << EmitTypeExpansion(tvp, id, what)
02262 << "::tag" << idname(cname)
02263 << " };" << std::endl;
02264
02265 continue;
02266 }
02267
02268
02269
02270 ino << EmitTypeScheme(tvp, id, what)
02271 << "inline " << idname(id)
02272 << EmitTypeExpansion(tvp, id, what)
02273 << (id->symType->isRefType() ? "*" : "")
02274 << " C" << idname(cname) << "(";
02275
02276 for (size_t ndx = 0; ndx < leg->children.size()-1; ndx++) {
02277 GCPtr<AST> arg = leg->child(ndx+1);
02278
02279 stringstream ss;
02280 ss << "arg" << ndx;
02281
02282 if (ndx > 0) ino << ", ";
02283 ino << c_decl(tvp, arg->getType(), ss.str());
02284 }
02285
02286 ino << ")" << std::endl;
02287
02288 ino << "{" << std::endl;
02289 ino.more();
02290
02291 if (id->symType->isRefType()){
02292 ino << "void (*_markfn)(" << idname(id)
02293 << EmitTypeExpansion(tvp, id, what)
02294 << "*&) = gcMark;" << std::endl;
02295
02296 ino << idname(id)
02297 << EmitTypeExpansion(tvp, id, what)
02298 << "* _pInstance = ("
02299 << idname(id)
02300 << EmitTypeExpansion(tvp, id, what)
02301 << "*)" << std::endl;
02302
02303 ino << " allocate(sizeof("
02304 << idname(id)
02305 << EmitTypeExpansion(tvp, id, what)
02306 << "), "
02307 << "(void (*)(...))_markfn"
02308 << ");" << std::endl;
02309
02310 ino << idname(id)
02311 << EmitTypeExpansion(tvp, id, what)
02312 << "& _instance = *_pInstance;" << std::endl << std::endl;
02313 }
02314 else {
02315 ino << idname(id)
02316 << EmitTypeExpansion(tvp, id, what)
02317 << " _instance;" << std::endl << std::endl;
02318 }
02319
02320 ino << "_instance.tag = "
02321 << idname(id)
02322 << EmitTypeExpansion(tvp, id, what)
02323 << "::tag" << idname(cname)
02324 << ";" << std::endl;
02325
02326 for (size_t ndx = 0; ndx < leg->children.size()-1; ndx++) {
02327 GCPtr<AST> arg = leg->child(ndx);
02328
02329 ino << "_instance.u." << idname(cname) << ".arg" << ndx
02330 << " = " << "arg" << ndx
02331 << ";" << std::endl;
02332 }
02333
02334 if (id->symType->isRefType())
02335 ino << "return &_instance;" << std::endl;
02336 else
02337 ino << "return _instance;" << std::endl;
02338
02339 ino.less();
02340 ino << "}" << std::endl;
02341 }
02342 }
02343 }
02344
02345 static void
02346 EmitSUDecl(INOstream& ino, GCPtr<AST> ast, DeclsOrDefs what)
02347 {
02348 if (what != WantDecl)
02349 return;
02350
02351
02352
02353 GCPtr<AST> id = ast->child(0);
02354 ino << "/* AST " << ast->ID << ": " << ast->astTypeName()
02355 << " " << idname(id)
02356 << " */" << std::endl;
02357 }
02358
02359 static void
02360 EmitAst(INOstream& ino, GCPtr<AST> ast, DeclsOrDefs what)
02361 {
02362 switch(ast->astType) {
02363 case at_defexception:
02364 {
02365 EmitDefexcept(ino, ast, what);
02366 break;
02367 }
02368 case at_defstruct:
02369 {
02370 EmitDefstruct(ino, ast, what);
02371 break;
02372 }
02373 case at_defunion:
02374 {
02375 EmitDefunion(ino, ast, what);
02376 break;
02377 }
02378 case at_define:
02379 {
02380 EmitDefine(ino, ast, what);
02381 break;
02382 }
02383
02384 case at_declValue:
02385 {
02386 EmitDeclValue(ino, ast, what);
02387 break;
02388 }
02389
02390 case at_declunionr:
02391 case at_declstructr:
02392 {
02393 EmitSUDecl(ino, ast, what);
02394 break;
02395 }
02396
02397 default:
02398 {
02399 ino << "/* AST " << ast->ID << ": " << ast->astTypeName()
02400 << " */" << std::endl;
02401 break;
02402 }
02403 }
02404 }
02405
02406 static void
02407 GenerateInterface(INOstream& ino, const GCPtr<UocInfo> &uoc,
02408 DeclsOrDefs what)
02409 {
02410 assert(uoc->ast->children.size() == 2);
02411 assert(uoc->ast->child(0)->astType == at_version);
02412
02413 GCPtr<AST> srcmod = uoc->ast->child(1);
02414
02415 assert((srcmod->astType == at_module) ||
02416 (srcmod->astType == at_interface));
02417
02418
02419
02420 for (size_t i = (srcmod->astType == at_interface) ? 1 : 0;
02421 i < srcmod->children.size(); i++) {
02422 GCPtr<AST> ast = srcmod->child(i);
02423
02424 EmitAst(ino, ast, what);
02425 }
02426 }
02427
02428 bool
02429 CheckBootstrapConstraints(std::ostream& errStream, const GCPtr<UocInfo> &uoc)
02430 {
02431 bool ok = true;
02432
02433 if (hasPatternBindings(errStream, uoc->ast))
02434 ok = false;
02435
02436 if(hasInnerLambdas(errStream, uoc->ast))
02437 ok = false;
02438
02439 if(!hasPureLoops(errStream, uoc->ast))
02440 ok = false;
02441
02442 return ok;
02443 }
02444
02445 #if 0
02446 void
02447 GenerateC(std::ostream& out, const GCPtr<UocInfo> &uoc)
02448 {
02449 #if 0
02450 if(!escapeCheck(uoc->ast)) {
02451 out << "Exiting due to errors during escape analysis."
02452 << std::endl;
02453 exit(1);
02454 }
02455 #endif
02456
02457 INOstream ino(out);
02458
02459 ino << "namespace " << mangle(uoc->ifName) << " {" << std::endl;
02460 ino.more();
02461
02462 GenerateInterface(ino, uoc, WantDecls);
02463
02464 ino.less();
02465 ino << "} /* namespace " << mangle(uoc->ifName) << " */;" << std::endl;
02466
02467 GenerateInterface(ino, uoc, WantDefs);
02468 }
02469 #endif
02470
02471 bool
02472 GenerateC()
02473 {
02474 for(size_t i = 0; i < UocInfo::ifList.size(); i++) {
02475 GCPtr<UocInfo> uoc = UocInfo::ifList[i];
02476
02477 if (!CheckBootstrapConstraints(std::cerr, uoc)) {
02478 std::cerr << "Errors found during bootstrap constraint check of "
02479 << uoc->path
02480 << std::endl;
02481 return false;
02482 }
02483
02484 if (!SimplifyAST(std::cerr, uoc->ast)) {
02485 std::cerr << "Unable to simplify AST for code generation in "
02486 << uoc->path
02487 << std::endl;
02488 return false;
02489 }
02490
02491 AlphaRename(uoc->ast);
02492 }
02493
02494 for(size_t i = 0; i < UocInfo::srcList.size(); i++) {
02495 GCPtr<UocInfo> uoc = UocInfo::srcList[i];
02496
02497 if (!CheckBootstrapConstraints(std::cerr, uoc)) {
02498 std::cerr << "Errors found during bootstrap constraint check of "
02499 << uoc->path
02500 << std::endl;
02501 return false;
02502 }
02503
02504 if (!SimplifyAST(std::cerr, uoc->ast)) {
02505 std::cerr << "Unable to simplify AST for code generation in "
02506 << uoc->path
02507 << std::endl;
02508 return false;
02509 }
02510
02511 AlphaRename(uoc->ast);
02512 }
02513
02514 if (Options::outputFileName.size() == 0)
02515 Options::outputFileName = "/dev/stdout";
02516
02517 std::ofstream out(Options::outputFileName.c_str(),
02518 std::ios_base::out|std::ios_base::trunc);
02519
02520 if (!out.is_open()) {
02521 std::cerr << "Couldn't open output file \""
02522 << Options::outputFileName
02523 << "\" -- "
02524 << strerror(errno)
02525 << "\n";
02526 exit(1);
02527 }
02528
02529 INOstream ino(out);
02530
02531 ino << "#include \""
02532 << BITCCDIR
02533 << "/BitcRuntime.hxx\"" << std::endl;
02534
02535 #if 0
02536
02537 for(size_t i = 0; i < UocInfo::ifList.size(); i++) {
02538 GCPtr<UocInfo> uoc = UocInfo::ifList[i];
02539
02540 ino << "namespace " << mangle(uoc->ifName) << " {" << std::endl;
02541 ino.more();
02542
02543 GenerateInterface(ino, uoc, WantForward);
02544
02545 ino.less();
02546 ino << "} /* namespace " << mangle(uoc->ifName) << " */;" << std::endl;
02547 }
02548
02549
02550 for(size_t i = 0; i < UocInfo::srcList.size(); i++) {
02551 GCPtr<UocInfo> uoc = UocInfo::srcList[i];
02552
02553 ino << "namespace " << mangle(uoc->ifName) << " {" << std::endl;
02554 ino.more();
02555
02556 GenerateInterface(ino, uoc, WantForward);
02557
02558 ino.less();
02559 ino << "} /* namespace " << mangle(uoc->ifName) << " */;" << std::endl;
02560 }
02561 #endif
02562
02563
02564 for(size_t i = 0; i < UocInfo::ifList.size(); i++) {
02565 GCPtr<UocInfo> uoc = UocInfo::ifList[i];
02566
02567 #ifdef NAMESPACE
02568 ino << "namespace " << xmangle(uoc->ifName) << " {" << std::endl;
02569 ino.more();
02570 #endif
02571
02572 GenerateInterface(ino, uoc, WantDecl);
02573
02574 #ifdef NAMESPACE
02575 ino.less();
02576 ino << "} /* namespace " << xmangle(uoc->ifName) << " */;" << std::endl;
02577 #endif
02578 }
02579
02580 for(size_t i = 0; i < UocInfo::srcList.size(); i++) {
02581 GCPtr<UocInfo> uoc = UocInfo::srcList[i];
02582
02583 #ifdef NAMESPACE
02584 ino << "namespace " << xmangle(uoc->ifName) << " {" << std::endl;
02585 ino.more();
02586 #endif
02587
02588 GenerateInterface(ino, uoc, WantDecl);
02589
02590 #ifdef NAMESPACE
02591 ino.less();
02592 ino << "} /* namespace " << xmangle(uoc->ifName) << " */;" << std::endl;
02593 #endif
02594 }
02595
02596
02597 for(size_t i = 0; i < UocInfo::ifList.size(); i++) {
02598 GCPtr<UocInfo> uoc = UocInfo::ifList[i];
02599
02600 GenerateInterface(ino, uoc, WantGC);
02601 }
02602
02603 for(size_t i = 0; i < UocInfo::srcList.size(); i++) {
02604 GCPtr<UocInfo> uoc = UocInfo::srcList[i];
02605
02606 GenerateInterface(ino, uoc, WantGC);
02607 }
02608
02609
02610 for(size_t i = 0; i < UocInfo::ifList.size(); i++) {
02611 GCPtr<UocInfo> uoc = UocInfo::ifList[i];
02612
02613 #ifdef NAMESPACE
02614 ino << "namespace " << xmangle(uoc->ifName) << " {" << std::endl;
02615 ino.more();
02616 #endif
02617
02618 GenerateInterface(ino, uoc, WantConstructors);
02619
02620 #ifdef NAMESPACE
02621 ino.less();
02622 ino << "} /* namespace " << xmangle(uoc->ifName) << " */;" << std::endl;
02623 #endif
02624 }
02625
02626 for(size_t i = 0; i < UocInfo::srcList.size(); i++) {
02627 GCPtr<UocInfo> uoc = UocInfo::srcList[i];
02628
02629 #ifdef NAMESPACE
02630 ino << "namespace " << xmangle(uoc->ifName) << " {" << std::endl;
02631 ino.more();
02632 #endif
02633
02634 GenerateInterface(ino, uoc, WantConstructors);
02635
02636 #ifdef NAMESPACE
02637 ino.less();
02638 ino << "} /* namespace " << xmangle(uoc->ifName) << " */;" << std::endl;
02639 #endif
02640 }
02641
02642
02643 ino << "/* HELPER ROUTINE */" << std::endl;
02644
02645 ino << "BitcString_t *" << std::endl;
02646 ino << "mkStringLiteral(const char *s)" << std::endl;
02647 ino << "{" << std::endl;
02648 ino.more();
02649 ino << "size_t len = strlen(s);" << std::endl;
02650 ino << "void (*markfn)(BitcString_t *&) = gcMark;" << std::endl;
02651 ino << std::endl;
02652 ino << "BitcString_t *tmp =" << std::endl;
02653 ino.more();
02654 ino << "(BitcString_t *) allocate(sizeof(BitcString_t) "
02655 << "+ sizeof(tmp->s[0]) * len,"
02656 << std::endl;
02657 ino << " (void (*)(...)) markfn);" << std::endl;
02658 ino.less();
02659
02660 ino << "tmp->length = len;" << std::endl;
02661 ino << "for(size_t i = 0; i < len; i ++)" << std::endl;
02662 ino.more();
02663 ino << "tmp->s[i] = s[i];" << std::endl;
02664 ino.less();
02665
02666 ino << "return tmp;" << std::endl;
02667
02668 ino.less();
02669 ino << "}";
02670
02671
02672 for(size_t i = 0; i < UocInfo::ifList.size(); i++) {
02673 GCPtr<UocInfo> uoc = UocInfo::ifList[i];
02674
02675 GenerateInterface(ino, uoc, WantDefs);
02676 }
02677
02678 for(size_t i = 0; i < UocInfo::srcList.size(); i++) {
02679 GCPtr<UocInfo> uoc = UocInfo::srcList[i];
02680
02681 GenerateInterface(ino, uoc, WantDefs);
02682 }
02683
02684
02685 #ifdef NAMESPACE
02686 ino << "using namespace Iprelude;" << std::endl;
02687 ino << std::endl;
02688 #endif
02689 ino << "int main(int argc, char *argv[])" << std::endl;
02690 ino << "{" << std::endl;
02691 ino.more();
02692 ino << "BitcInt32_t i = 1;" << std::endl;
02693 ino << "BitcChar_t c = 'c';" << std::endl;
02694 ino << "BitcFloat_t f = 3.414;" << std::endl;
02695 ino << std::endl;
02696 #ifdef NAMESPACE
02697 ino << "(void) Icgen::CIstr3(i, c, f);" << std::endl;
02698 #else
02699 ino << "(void) Icgen__CIstr3(i, c, f);" << std::endl;
02700 #endif
02701 ino << std::endl;
02702 ino << "majorGC();" << std::endl;
02703 ino.less();
02704 ino << "}" << std::endl;
02705 return true;
02706 }
02707