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
00039 #include "../config.h"
00040
00041 #include <stdint.h>
00042 #include <stdlib.h>
00043 #include <dirent.h>
00044 #include <errno.h>
00045 #include <fstream>
00046 #include <iostream>
00047 #include <string>
00048 #include <set>
00049 #include <sstream>
00050 #include <cctype>
00051
00052 #ifdef HAVE_SYS_WAIT_H
00053 #include <sys/wait.h>
00054 #endif
00055
00056 #include <libsherpa/utf8.hxx>
00057 #include <libsherpa/INOstream.hxx>
00058 #include <libsherpa/BigNum.hxx>
00059 #include <boost/filesystem/operations.hpp>
00060
00061 #include "config.h"
00062
00063 #include "Version.hxx"
00064 #include "Options.hxx"
00065 #include "UocInfo.hxx"
00066 #include "AST.hxx"
00067 #include "Environment.hxx"
00068 #include "inter-pass.hxx"
00069 #include "backend.hxx"
00070
00071 #define TOC_HEADER_MODE 0x01u
00072
00073 using namespace std;
00074 using namespace boost;
00075 using namespace boost;
00076 using namespace sherpa;
00077
00078 const char *TY_PFX = "ty_";
00079 const char *CTOR_PFX = "ct_";
00080 const char *CVAL_PFX = "val_";
00081 const char *TAG_PFX = "tag_";
00082 const char *ENUM_PFX = "en_";
00083 const char *ARG_PFX = "arg_";
00084 const char *RET_PFX = "ret_";
00085 const char *ENV_PFX = "env_";
00086 const char *XFN_PFX = "xfn_";
00087 const char *MFN_PFX = "mfn_";
00088
00089 const char *WFN_PFX = "wfn_";
00090
00091
00092
00093
00094
00095 const char *LBL_PFX = "__escape___";
00096
00097
00098 #if 0
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 static char *kwd_blacklist[] = {
00109 "asm",
00110 "auto",
00111 "bitc_bool_t",
00112 "bitc_char_t",
00113 "bitc_double_t",
00114 "bitc_float_t",
00115 "bitc_int16_t",
00116 "bitc_int32_t",
00117 "bitc_int64_t",
00118 "bitc_int8_t",
00119 "bitc_quad_t",
00120 "bitc_string",
00121 "bitc_uns16_t",
00122 "bitc_uns32_t",
00123 "bitc_uns64_t",
00124 "bitc_uns8_t",
00125 "bitc_vector",
00126 "bitc_word_t",
00127 "bool",
00128 "break",
00129 "case",
00130 "catch",
00131 "cdecl",
00132 "char",
00133 "class",
00134 "const",
00135 "const_cast",
00136 "continue",
00137 "default",
00138 "defined",
00139 "delete",
00140 "do",
00141 "double",
00142 "dynamic_cast",
00143 "else",
00144 "entry",
00145 "enum",
00146 "explicit",
00147 "extern",
00148 "false",
00149 "far",
00150 "float",
00151 "for",
00152 "fortran",
00153 "friend",
00154 "generic",
00155 "globaldef",
00156 "globalref",
00157 "globalvalue",
00158 "goto",
00159 "huge",
00160 "if",
00161 "inline",
00162 "int",
00163 "int16",
00164 "int32",
00165 "int64",
00166 "int8",
00167 "interface",
00168 "long",
00169 "mutable",
00170 "namespace",
00171 "near",
00172 "new",
00173 "operator",
00174 "pascal",
00175 "pragma",
00176 "private",
00177 "protected",
00178 "public",
00179 "quad",
00180 "readonly",
00181 "register",
00182 "reinterpret_cast",
00183 "return",
00184 "short",
00185 "signed",
00186 "sizeof",
00187 "static",
00188 "static_cast",
00189 "string",
00190 "struct",
00191 "super",
00192 "switch",
00193 "template",
00194 "this",
00195 "throw",
00196 "true",
00197 "try",
00198 "typedef",
00199 "typeid",
00200 "typename",
00201 "uint16",
00202 "uint32",
00203 "uint64",
00204 "uint8",
00205 "union",
00206 "unsigned",
00207 "use",
00208 "using",
00209 "virtual",
00210 "void",
00211 "volatile",
00212 "while",
00213 "word",
00214
00215
00216 0
00217 };
00218
00219 enum { nkwd = (sizeof(kwd_blacklist)/sizeof(kwd_blacklist[0])) - 1 };
00220
00221 bool
00222 is_kwd(const std::string& s)
00223 {
00224 const char *cs = s.c_str();
00225
00226
00227 if (bsearch(&cs, kwd_blacklist, nkwd, sizeof(kwd_blacklist[0]),
00228 ((int (*)(const void*, const void*)) strcmp)))
00229 return true;
00230 return false;
00231 }
00232 #endif
00233
00234
00235
00236 const struct MangleMap {
00237 char c;
00238 const char *s;
00239 } mangleMap[] = {
00240 { '#', "_SH" },
00241 { '!', "_EX" },
00242 { '$', "_DL" },
00243 { '%', "_PC" },
00244 { '*', "_ST" },
00245 { '+', "_PL" },
00246 { '\\', "_RS" },
00247 { '-', "_HY" },
00248 { '/', "_FS" },
00249 { '<', "_LT" },
00250 { '>', "_GT" },
00251 { '=', "_EQ" },
00252 { '?', "_QU" },
00253 { '@', "_AT" },
00254 { '~', "_TL" },
00255 { ':', "_CN" },
00256 { '_', "_" },
00257 { '.', "_DT"},
00258 { '\'', "_QT" }
00259 };
00260 enum { nSpecial = sizeof(mangleMap) / sizeof(MangleMap) };
00261
00262 const char *
00263 punctMangle(uint32_t codePoint)
00264 {
00265 for (size_t sp = 0; sp < nSpecial; sp++) {
00266 if (mangleMap[sp].c == (char) codePoint) {
00267 return mangleMap[sp].s;
00268 }
00269 }
00270
00271 return 0;
00272 }
00273
00274 std::string
00275 CMangle(std::string idName)
00276 {
00277 std::stringstream ss;
00278 const char *s = idName.c_str();
00279
00280 while (*s) {
00281 const char *snext;
00282 uint32_t codePoint = sherpa::utf8_decode(s, &snext);
00283 const char *pm;
00284
00285 if (isalnum(codePoint)) {
00286 ss << *s;
00287 }
00288 else if ((pm=punctMangle(codePoint))) {
00289 ss << pm;
00290 }
00291 else {
00292 ss << "_UC"
00293 << hex
00294 << codePoint
00295 << dec
00296 << "_";
00297 }
00298 s = snext;
00299 }
00300
00301 return ss.str();
00302 }
00303
00304 #define CMGL_ID_FLD 0x1u
00305 std::string
00306 CMangle(shared_ptr<AST> ast, unsigned long flags = 0)
00307 {
00308 assert(ast->astType == at_ident);
00309
00310 shared_ptr<AST> id = ast;
00311
00312 if (id->symbolDef)
00313 id = id->symbolDef;
00314
00315 if (id->isDecl && (id->defn))
00316 id = id->defn;
00317
00318 if (id->externalName.size())
00319 return id->externalName;
00320
00321 std::stringstream ss;
00322 if ((id->flags & ID_IS_GLOBAL) ||
00323 (id->flags & ID_IS_GENSYM) ||
00324 (flags & CMGL_ID_FLD))
00325 ss << id->s;
00326 else
00327 ss << id->s << "#" << id->ID;
00328 string idName = ss.str();
00329
00330 return CMangle(ss.str());
00331 }
00332
00333
00334 bool
00335 toc(std::ostream& errStream, shared_ptr<UocInfo> uoc,
00336 shared_ptr<AST> ast, INOstream &out, const string &IDname,
00337 set<string> &decls,
00338 shared_ptr<AST> parent,
00339 const size_t chno, unsigned long flags);
00340
00341 #define CTYP_EMIT_BF 0x01u // bitfield
00342 #define CTYP_BYREF 0x02u // Used to declare by-ref
00343
00344
00345 static string
00346 toCtype(shared_ptr<Type> typ, string IDname="", unsigned long flags=0,
00347 uint64_t arrsz = 0)
00348 {
00349 shared_ptr<Type> t = typ->getBareType();
00350 stringstream out;
00351
00352 switch(t->typeTag) {
00353 case ty_tvar:
00354 {
00355
00356
00357
00358
00359 out << "bitc_tvar_t";
00360 break;
00361 }
00362
00363 case ty_mbTop:
00364 case ty_mbFull:
00365 out << toCtype(t->Core(), IDname, flags, arrsz);
00366 break;
00367
00368 case ty_mutable:
00369 out << toCtype(t->Base(), IDname, flags, arrsz);
00370 break;
00371
00372 case ty_const:
00373 out << toCtype(t->Base(), IDname, flags, arrsz);
00374 break;
00375
00376 case ty_dummy:
00377
00378 case ty_unit:
00379 out << "bitc_unit_t";
00380 break;
00381
00382 case ty_bool:
00383 out << "bitc_bool_t";
00384 break;
00385 case ty_char:
00386 out << "bitc_char_t";
00387 break;
00388 case ty_string:
00389 out << "bitc_string_t *";
00390 break;
00391 case ty_int8:
00392 out << "bitc_int8_t";
00393 break;
00394 case ty_int16:
00395 out << "bitc_int16_t";
00396 break;
00397 case ty_int32:
00398 out << "bitc_int32_t";
00399 break;
00400 case ty_int64:
00401 out << "bitc_int64_t";
00402 break;
00403 case ty_uint8:
00404 out << "bitc_uns8_t";
00405 break;
00406 case ty_uint16:
00407 out << "bitc_uns16_t";
00408 break;
00409 case ty_uint32:
00410 out << "bitc_uns32_t";
00411 break;
00412 case ty_uint64:
00413 out << "bitc_uns64_t";
00414 break;
00415 case ty_word:
00416 out << "bitc_word_t";
00417 break;
00418 case ty_float:
00419 out << "bitc_float_t";
00420 break;
00421 case ty_double:
00422 out << "bitc_double_t";
00423 break;
00424 case ty_quad:
00425 out << "bitc_quad_t";
00426 break;
00427
00428 #ifdef KEEP_BF
00429 case ty_bitfield:
00430 if (IDname.size() && (flags & CTYP_EMIT_BF))
00431 out << toCtype(t->CompType(0), IDname, flags, arrsz)
00432 << " " << IDname
00433 << ":" << t->Isize;
00434 else
00435 out << toCtype(t->CompType(0), IDname, flags, arrsz);
00436 #endif
00437
00438 break;
00439
00440 case ty_method:
00441 {
00442
00443
00444
00445
00446 assert(false);
00447 break;
00448 }
00449
00450 case ty_fn:
00451 {
00452 out << CMangle(t->mangledString(true));
00453 break;
00454 }
00455
00456 case ty_fnarg:
00457 {
00458 for (size_t i=0; i<t->components.size(); i++) {
00459 if (i > 0)
00460 out << ", ";
00461 out << toCtype(t->CompType(i), IDname, flags, arrsz);
00462 }
00463 break;
00464 }
00465
00466 case ty_structv:
00467 case ty_unionv:
00468 {
00469 out << TY_PFX << CMangle(t->defAst);
00470 break;
00471 }
00472
00473 case ty_structr:
00474 case ty_unionr:
00475 {
00476 out << TY_PFX << CMangle(t->defAst) << " *";
00477 break;
00478 }
00479
00480 case ty_uvalv:
00481 case ty_uconv:
00482 {
00483 out << TY_PFX <<CMangle(t->myContainer);
00484 break;
00485 }
00486
00487 case ty_uvalr:
00488 case ty_uconr:
00489 {
00490 out << TY_PFX << CMangle(t->myContainer) << " *";
00491 break;
00492 }
00493
00494 case ty_array:
00495 case ty_array_ref:
00496 {
00497 out << CMangle(t->mangledString(true));
00498 break;
00499 }
00500
00501 case ty_vector:
00502 {
00503 out << CMangle(t->mangledString(true)) << " *";
00504 break;
00505 }
00506
00507 case ty_byref:
00508 case ty_ref:
00509 {
00510 out << toCtype(t->Base(), IDname, flags, arrsz)
00511 << " *";
00512 break;
00513 }
00514
00515 case ty_exn:
00516 {
00517 if (t->defAst)
00518 out << TY_PFX << CMangle(t->defAst) << " *";
00519 else
00520 out << "bitc_exception_t *";
00521 break;
00522 }
00523
00524 case ty_tyfn:
00525 case ty_typeclass:
00526 case ty_pcst:
00527 case ty_kvar:
00528 case ty_kfix:
00529 case ty_letGather:
00530 case ty_field:
00531 assert(false);
00532 break;
00533 }
00534 return out.str();
00535 }
00536
00537 static inline bool
00538 isUnitType(shared_ptr<Type> ty)
00539 {
00540 return (ty->getBareType()->typeTag == ty_unit);
00541 }
00542
00543 static inline bool
00544 isUnitType(shared_ptr<AST> ast)
00545 {
00546 return isUnitType(ast->symType);
00547 }
00548
00549 static inline std::string
00550 decl(shared_ptr<Type> typ, string idName, unsigned flags=0,
00551 size_t field_bits=0)
00552 {
00553 stringstream ss;
00554 ss << toCtype(typ) << " ";
00555
00556 if (flags & CTYP_BYREF)
00557 ss << "*";
00558
00559 ss << idName;
00560
00561 if ((flags & CTYP_EMIT_BF) && field_bits)
00562 ss << ":" << field_bits;
00563
00564 return ss.str();
00565 }
00566
00567 static inline std::string
00568 decl(shared_ptr<AST> id, string idPrefix="", unsigned flags=0,
00569 unsigned long cmFlags=0)
00570 {
00571 assert(id->astType == at_ident);
00572 stringstream ss;
00573
00574 ss << toCtype(id->symType) << " ";
00575
00576 if (flags & CTYP_BYREF)
00577 ss << "*";
00578
00579 ss << idPrefix << CMangle(id, cmFlags);
00580
00581 if ((flags & CTYP_EMIT_BF) && (id->field_bits > 0))
00582 ss << ":" << id->field_bits;
00583
00584 return ss.str();
00585 }
00586
00587 static inline void
00588 declare(INOstream &out, shared_ptr<AST> id, string prefix="",
00589 unsigned flags=0)
00590 {
00591 out << decl(id, prefix, flags) << ";" << endl;
00592 }
00593
00594
00595 static void
00596 emit_ct_args(INOstream &out, shared_ptr<AST> fields, size_t start=0)
00597 {
00598 out << "(";
00599
00600 bool emitted1=false;
00601 for (size_t c = start; c < fields->children.size(); c++) {
00602 shared_ptr<AST> field = fields->child(c);
00603
00604 if (field->astType != at_field ||
00605 (field->flags & FLD_IS_DISCM))
00606 continue;
00607
00608 if (emitted1)
00609 out << ", ";
00610
00611 emitted1=true;
00612
00613 out << decl(field->child(1)->symType,
00614 "_" + CMangle(field->child(0), CMGL_ID_FLD));
00615 }
00616 out << ")" << endl;
00617 }
00618
00619 static void
00620 emit_ct_inits(INOstream &out, shared_ptr<AST> fields,
00621 string pre="", size_t start=0)
00622 {
00623 for (size_t i = start; i < fields->children.size(); i++) {
00624 shared_ptr<AST> field = fields->child(i);
00625
00626 if (field->astType == at_methdecl)
00627 continue;
00628
00629 if (field->astType == at_fill) {
00630 if(field->children.size() == 2) {
00631 out << pre << "__reserved" << field->ID
00632 << " = "
00633 << field->child(1)->litValue.i;
00634 out << ";" << endl;
00635 }
00636 continue;
00637 }
00638
00639 string fMang = CMangle(field->child(0), CMGL_ID_FLD);
00640 if (field->flags & FLD_IS_DISCM) {
00641 out << pre << fMang << " = "
00642 << field->unin_discm
00643 << ";" << endl;
00644 }
00645 else {
00646 out << pre << fMang << " = "
00647 << "_" << CMangle(field->child(0), CMGL_ID_FLD)
00648 << ";" << endl;
00649 }
00650 }
00651 }
00652
00653 static void
00654 emit_fnxn_type(INOstream &out, std::string &id, shared_ptr<Type> fn,
00655 bool makePointer=false)
00656 {
00657 fn = fn->getType();
00658 shared_ptr<Type> ret = fn->Ret()->getType();
00659 shared_ptr<Type> args = fn->Args()->getBareType();
00660
00661
00662 if (isUnitType(ret))
00663 out << "void ";
00664 else
00665 out << toCtype(ret) << " ";
00666
00667
00668 if (!makePointer)
00669 out << CMangle(id) << " ";
00670 else
00671 out << "(*" << CMangle(id) << ") ";
00672
00673 out << "(";
00674 size_t argCount = 0;
00675 for (size_t i=0; i < args->components.size(); i++) {
00676 shared_ptr<Type> arg = args->CompType(i);
00677 if (isUnitType(arg))
00678 continue;
00679 if (argCount > 0)
00680 out << ", ";
00681
00682 out << toCtype(arg) << " ";
00683 if (args->CompFlags(i) & COMP_BYREF)
00684 out << "*";
00685 out << " arg" << argCount;
00686 argCount++;
00687 }
00688 if (argCount == 0)
00689 out << "void";
00690 out << ")";
00691 }
00692
00693 static void
00694 emit_fnxn_decl(INOstream &out, shared_ptr<AST> ast,
00695 bool oneLine, std::string pfx="",
00696 size_t startParam=0)
00697 {
00698 shared_ptr<AST> id = ast->child(0)->child(0);
00699 shared_ptr<Type> fnType = id->symType->getBareType();
00700 shared_ptr<Type> retType = fnType->Ret()->getType();
00701 shared_ptr<AST> lam = ast->child(1);
00702 shared_ptr<AST> argvec = lam->child(0);
00703 shared_ptr<Type> fnargvec = fnType->Args()->getBareType();
00704 assert(argvec->children.size() == fnargvec->components.size());
00705
00706
00707 if (isUnitType(retType))
00708 out << "void";
00709 else
00710 out << toCtype(retType);
00711 if (!oneLine)
00712 out << endl;
00713
00714 out << pfx << CMangle(id) << " ";
00715 out << "(";
00716 assert(startParam <= argvec->children.size());
00717 int paramCount = 0;
00718 for (size_t i=startParam; i < argvec->children.size(); i++) {
00719 shared_ptr<AST> pat = argvec->child(i);
00720 assert(pat->astType == at_identPattern);
00721 shared_ptr<AST> arg = pat->child(0);
00722 unsigned long flags = ((fnargvec->CompFlags(i) & COMP_BYREF)
00723 ? CTYP_BYREF : 0);
00724
00725
00726
00727
00728
00729
00730
00731
00732 if (isUnitType(arg))
00733 continue;
00734
00735 if (paramCount)
00736 out << ", ";
00737
00738 out << decl(arg, "", flags);
00739 paramCount++;
00740 }
00741
00742
00743 if (paramCount == 0)
00744 out << "void";
00745
00746 out << ")";
00747 }
00748
00749 static bool
00750 emit_fnxn_label(std::ostream& errStream,
00751 shared_ptr<UocInfo> uoc,
00752 shared_ptr<AST> ast,
00753 INOstream &out,
00754 set<string> &decls,
00755 shared_ptr<AST> parent,
00756 const size_t chno,
00757 unsigned long flags)
00758 {
00759 bool errFree = true;
00760 assert(ast->astType == at_define || ast->astType == at_recdef);
00761 shared_ptr<AST> id = ast->child(0)->child(0);
00762 assert(id->isFnxn());
00763 bool isHeader = (flags & TOC_HEADER_MODE);
00764
00765 emit_fnxn_decl(out, ast, isHeader);
00766
00767 if (isHeader) {
00768 out << ";" << endl;
00769 return errFree;
00770 }
00771
00772 out << endl;
00773 out << "{"
00774 << endl;
00775 out.more();
00776
00777 shared_ptr<AST> lam = ast->child(1);
00778 shared_ptr<AST> body = lam->child(1);
00779 shared_ptr<AST> ret= GC_NULL;
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 shared_ptr<AST> argvec = lam->child(0);
00797 for (size_t i= 0; i < argvec->children.size(); i++) {
00798 shared_ptr<AST> pat = argvec->child(i);
00799
00800 assert(pat->astType == at_identPattern);
00801 shared_ptr<AST> arg = pat->child(0);
00802
00803 if (isUnitType(arg)) {
00804
00805
00806
00807
00808 out << decl(arg, "", 0) << " = " << "0;" << '\n';
00809 }
00810 }
00811
00812 assert(body->astType == at_container);
00813 if (body->child(1)->astType == at_letStar) {
00814 CHKERR(errFree, toc(errStream, uoc, body, out, CMangle(id),
00815 decls, lam, 1, flags));
00816 out << ";" << endl;
00817
00818 ret = FEXPR(body->child(1));
00819 }
00820 else {
00821 ret = body->child(1);
00822 }
00823 assert(ret);
00824
00825
00826
00827 if (! isUnitType(ret))
00828 out << "return ";
00829 CHKERR(errFree, toc(errStream, uoc, ret, out, CMangle(id),
00830 decls, lam, 1, flags));
00831 out << ";" << endl;
00832
00833 if (isUnitType(ret))
00834 out << "return;" << endl;
00835
00836 out.less();
00837 out << "}" << endl;
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 if (ast->flags & LAM_NEEDS_TRANS) {
00855
00856
00857
00858 assert(!id->symType->isMutable());
00859
00860 out << endl;
00861 out << "/* Transition Function */" << endl;
00862 emit_fnxn_decl(out, ast, false, XFN_PFX, 1);
00863 out << endl;
00864 out << "{"
00865 << endl;
00866 out.more();
00867
00868 out << "BITC_GET_CLOSURE_ENV(__bitc_closure_env);" << endl;
00869
00870 shared_ptr<AST> argvec = lam->child(0);
00871 if (! isUnitType(ret))
00872 out << "return ";
00873 out << CMangle(id) << "(__bitc_closure_env";
00874 for (size_t i=1; i < argvec->children.size(); i++) {
00875 shared_ptr<AST> pat = argvec->child(i);
00876 shared_ptr<AST> arg = pat->child(0);
00877 if (!isUnitType(arg))
00878 out << ", " << CMangle(arg);
00879 }
00880 out << ");" << endl;
00881 if (isUnitType(ret))
00882 out << "return;" << endl;
00883 out.less();
00884 out << "}" << endl <<endl;
00885 }
00886
00887 return errFree;
00888 }
00889
00890 bool
00891 typeIsUnmangled(shared_ptr<Type> typ)
00892 {
00893 typ = typ->getBareType();
00894 switch(typ->typeTag) {
00895
00896 case ty_tvar:
00897 case ty_unit:
00898 case ty_dummy:
00899 case ty_bool:
00900 case ty_char:
00901 case ty_string:
00902 case ty_int8:
00903 case ty_int16:
00904 case ty_int32:
00905 case ty_int64:
00906 case ty_uint8:
00907 case ty_uint16:
00908 case ty_uint32:
00909 case ty_uint64:
00910 case ty_word:
00911 case ty_float:
00912 case ty_double:
00913 case ty_quad:
00914 case ty_exn:
00915 #ifdef KEEP_BF
00916 case ty_bitfield:
00917 #endif
00918 return true;
00919
00920 case ty_ref:
00921 return typeIsUnmangled(typ->Base());
00922
00923 default:
00924 return false;
00925 }
00926 }
00927
00928 static bool
00929 needsBackslashEscape(uint32_t c)
00930 {
00931 return (c == '"' || c == '\'' || c == '\\');
00932 }
00933
00934 static bool
00935 asciiPrintableCharacter(uint32_t c)
00936 {
00937
00938
00939 return (c >= 0x20 && c < 0x7f);
00940 }
00941
00942
00943
00944 #define TOC(errStream, uoc, ast, out, IDname, \
00945 decla, parent, chno, flags) \
00946 do { \
00947 answer = toc((errStream), (uoc), (ast), (out), (IDname), \
00948 (decla), (parent), (chno), (flags)); \
00949 if (answer == false) \
00950 errorFree = false; \
00951 }while (0)
00952
00953 bool
00954 toc(std::ostream& errStream,
00955 shared_ptr<UocInfo> uoc,
00956 shared_ptr<AST> ast,
00957 INOstream &out,
00958 const string &IDname,
00959 set<string> &decls,
00960 shared_ptr<AST> parent,
00961 const size_t chno,
00962 unsigned long flags)
00963 {
00964 bool errorFree = true, answer = false;
00965
00966
00967
00968
00969 switch(ast->astType) {
00970
00971 case at_Null:
00972 case at_boxedCat:
00973 case at_unboxedCat:
00974 case at_oc_closed:
00975 case at_oc_open:
00976 case at_opaqueCat:
00977 case agt_category:
00978 case at_AnyGroup:
00979 case agt_literal:
00980 case agt_tvar:
00981 case agt_var:
00982 case agt_definition:
00983 case agt_type:
00984 case agt_expr:
00985 case agt_expr_or_define:
00986 case agt_eform:
00987 case agt_type_definition:
00988 case agt_value_definition:
00989 case agt_CompilationUnit:
00990 case agt_tc_definition:
00991 case agt_if_definition:
00992 case agt_openclosed:
00993 case agt_ow:
00994 case agt_qtype:
00995 case agt_fielditem:
00996 case at_localFrame:
00997 case at_frameBindings:
00998 case at_ifident:
00999 case agt_ucon:
01000 case agt_uselhs:
01001
01002 case at_declares:
01003 case at_declare:
01004
01005 case at_tcdecls:
01006 case at_tyfn:
01007 case at_tcapp:
01008 case at_method_decls:
01009 case at_method_decl:
01010 case at_usesel:
01011
01012 case at_boxedType:
01013 case at_byRefType:
01014 case at_arrayRefType:
01015 case at_exceptionType:
01016 case at_dummyType:
01017 case at_unboxedType:
01018 case at_fn:
01019 case at_fnargVec:
01020 case at_primaryType:
01021 case at_arrayType:
01022 case at_vectorType:
01023 case at_mutableType:
01024 case at_constType:
01025 case at_typeapp:
01026 case at_bitfieldType:
01027 case at_qualType:
01028 case at_constraints:
01029 case at_fieldType:
01030 case at_methType:
01031
01032 case at_deftypeclass:
01033 case at_definstance:
01034 case at_tcmethods:
01035 case at_tcmethod_binding:
01036 case at_importAs:
01037 case at_provide:
01038 case at_import:
01039 case at_ifsel:
01040 case at_tvlist:
01041
01042 case at_lambda:
01043 case at_argVec:
01044 case at_and:
01045 case at_or:
01046 case at_loopbindings:
01047 case at_loopbinding:
01048 case at_looptest:
01049
01050 case at_docString:
01051
01052 case at_cond:
01053 case at_cond_legs:
01054 case at_cond_leg:
01055 case at_letGather:
01056 {
01057 errStream << ast->loc << "Internal Compiler Error. "
01058 << "Function toc, unexpected astType: "
01059 << ast->tagName()
01060 << endl;
01061
01062 errorFree = false;
01063 break;
01064 }
01065
01066 case at_allocREF:
01067 {
01068 out << "GC_ALLOC_ATOMIC(sizeof("
01069 << toCtype(ast->child(0)->symType)
01070 << "))";
01071 break;
01072 }
01073
01074 case at_copyREF:
01075 {
01076 out << "*";
01077 TOC(errStream, uoc, ast->child(0), out,
01078 IDname, decls, ast, 0, flags);
01079 out << " = ";
01080 out << "*";
01081 TOC(errStream, uoc, ast->child(1), out,
01082 IDname, decls, ast, 1, flags);
01083 out << ";" << endl;
01084 break;
01085 }
01086
01087 case at_mkClosure:
01088 {
01089 shared_ptr<AST> fn = ast->child(1);
01090 shared_ptr<AST> env = ast->child(0);
01091 assert(IDname.size());
01092 assert(fn->astType == at_ident);
01093
01094 out << IDname << " = "
01095 << "(" << toCtype(ast->symType) << ")"
01096 << "bitc_emit_procedure_object("
01097 << XFN_PFX << CMangle(fn)
01098 << ", ";
01099 TOC(errStream, uoc, env, out, IDname, decls, ast, 0, flags);
01100 out << ");" << endl;
01101 break;
01102 }
01103
01104 case at_setClosure:
01105 {
01106
01107 assert(false);
01108 break;
01109 }
01110
01111 case at_ident:
01112 {
01113 shared_ptr<AST> id;
01114 if (ast->symbolDef)
01115 id = ast->symbolDef;
01116 else
01117 id = ast;
01118
01119 if (id->isIdentType(id_ucon0)) {
01120 shared_ptr<Type> t = id->symType->getBareType();
01121 if (t->typeTag == ty_uvalv || t->typeTag == ty_uvalr ||
01122 t->typeTag == ty_exn) {
01123 shared_ptr<AST> dummy = AST::make(at_ucon_apply, ast->loc, ast);
01124 dummy->symType = ast->symType;
01125 TOC(errStream, uoc, dummy, out, IDname,
01126 decls, GC_NULL, 0, flags);
01127 }
01128 break;
01129 }
01130
01131
01132 if (id->flags & ARG_BYREF)
01133 out << "(*";
01134
01135 out << CMangle(ast);
01136
01137 if (id->flags & ARG_BYREF)
01138 out << ")";
01139
01140 break;
01141 }
01142
01143 case at_identPattern:
01144 {
01145 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
01146 ast, 0, flags);
01147 break;
01148 }
01149
01150
01151 case at_interface:
01152 case at_module:
01153 {
01154 assert(false);
01155 break;
01156 }
01157
01158 case at_boolLiteral:
01159 {
01160 if (ast->litValue.b == true)
01161 out << "true";
01162 else
01163 out << "false";
01164 break;
01165 }
01166
01167 case at_charLiteral:
01168 {
01169 uint32_t c = ast->litValue.c;
01170
01171 if (asciiPrintableCharacter(c))
01172 out << (needsBackslashEscape(c) ? "'\\" : "'")
01173 << (unsigned char) c << "'";
01174 else
01175 out << (unsigned long)(ast->litValue.c);
01176 break;
01177 }
01178
01179 case at_intLiteral:
01180 {
01181 out << ast->litValue.i;
01182 break;
01183 }
01184
01185 case at_floatLiteral:
01186 {
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 char buf[256];
01201 snprintf(buf, sizeof(buf), " %f\n", ast->litValue.d);
01202 out << buf;
01203 break;
01204 }
01205
01206 case at_stringLiteral:
01207
01208 {
01209
01210 const char *s = ast->litValue.s.c_str();
01211 const char *send = s + ast->litValue.s.size();
01212
01213 out << "mkStringLiteral(\"";
01214
01215 while (s != send) {
01216 const char *snext;
01217 char utf8[7];
01218 uint32_t codePoint = LitValue::DecodeStringCharacter(s, &snext);
01219 unsigned len = sherpa::utf8_encode(codePoint, utf8);
01220
01221 if (asciiPrintableCharacter(codePoint)) {
01222 if (needsBackslashEscape(codePoint)) out << '\\';
01223 out << (unsigned char) codePoint;
01224 }
01225 else {
01226 for (unsigned pos = 0; pos < len; pos++) {
01227 unsigned char c = utf8[pos];
01228 char d2 = '0' + (c >> 6);
01229 char d1 = '0' + ((c >> 3) % 8);
01230 char d0 = '0' + (c % 8);
01231
01232 out << '\\' << d2 << d1 << d0;
01233 }
01234 }
01235
01236 s = snext;
01237 }
01238
01239 out << "\")";
01240
01241 break;
01242 }
01243
01244 case at_unit:
01245 {
01246 out << "0";
01247 break;
01248 }
01249
01250 case at_defstruct:
01251 {
01252 shared_ptr<AST> ident = ast->child(0);
01253 shared_ptr<AST> fields = ast->child(4);
01254 out << "struct " << TY_PFX << CMangle(ident) << "{" << endl;
01255 out.more();
01256 TOC(errStream, uoc, fields, out, IDname, decls, ast, 4, flags);
01257 out.less();
01258 out << "};" << endl
01259 << endl;
01260
01261
01262 out << "/* Constructor */" << endl;
01263 out << "INLINE " << toCtype(ident->symType) << endl
01264 << CTOR_PFX << CMangle(ident) << " ";
01265
01266 emit_ct_args(out, fields);
01267 out << "{" << endl;
01268
01269 out.more();
01270 std::string pre;
01271 if (ident->symType->getBareType()->typeTag == ty_structv) {
01272 out << toCtype(ident->symType)
01273 << " val;";
01274 pre = "val.";
01275 }
01276 else {
01277 out << toCtype(ident->symType)
01278 << " val = "
01279 << "(" << toCtype(ident->symType) << ") "
01280 << "GC_ALLOC(sizeof(" << TY_PFX << CMangle(ident) << "));" << endl;
01281 pre = "val->";
01282 }
01283
01284 emit_ct_inits(out, fields, pre);
01285 out << "return val;" << endl;
01286 out.less();
01287 out << "}" << endl;
01288 break;
01289 }
01290
01291 case at_fields:
01292 {
01293 for (size_t c=0; c < ast->children.size(); c++) {
01294 TOC(errStream, uoc, ast->child(c), out, IDname, decls,
01295 ast, c, flags);
01296 }
01297 break;
01298 }
01299
01300 case at_methdecl:
01301 break;
01302
01303 case at_field:
01304 {
01305 out << decl(ast->child(1)->symType,
01306 CMangle(ast->child(0), CMGL_ID_FLD),
01307 CTYP_EMIT_BF, ast->field_bits)
01308 << ";" << endl;
01309 break;
01310 }
01311
01312 case at_fill:
01313 {
01314 string s = "/* fill */";
01315 if(ast->children.size() == 2) {
01316 stringstream ss;
01317 ss << "__reserved" << ast->ID;
01318 s = CMangle(ss.str());
01319 }
01320
01321 out << decl(ast->child(0)->symType, s,
01322 CTYP_EMIT_BF, ast->field_bits)
01323 << ";" << endl;
01324
01325 break;
01326 }
01327
01328 case at_object_apply:
01329 {
01330
01331 errStream << "Object apply not yet implemented in code generator" << endl;
01332 break;
01333 }
01334 case at_ucon_apply:
01335 case at_struct_apply:
01336 {
01337 shared_ptr<AST> ctr = ast->child(0)->getCtr();
01338
01339 if (ctr->symType->isException() &&
01340 (ast->children.size() == 1)) {
01341 out << "&" << CVAL_PFX << CMangle(ast->child(0));
01342 break;
01343 }
01344
01345 out << CTOR_PFX << CMangle(ctr)
01346 << "(";
01347 for (size_t c=1; c < ast->children.size(); c++) {
01348 if (c > 1)
01349 out << ", ";
01350
01351 TOC(errStream, uoc, ast->child(c), out, IDname, decls,
01352 ast, c, flags);
01353 }
01354 out << ")";
01355
01356 break;
01357 }
01358
01359 case at_fqCtr:
01360 {
01361 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
01362 ast, 1, flags);
01363 break;
01364 }
01365
01366 case at_sel_ctr:
01367 {
01368 shared_ptr<Type> t = ast->child(0)->symType->getBareType();
01369 out << "(" << "TAG_" << CMangle(t->myContainer) << "(";
01370
01371 if (!ast->child(0)->symType->isRefType())
01372 out << "&";
01373
01374 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
01375 ast, 0, flags);
01376
01377 out << ") == ";
01378 out << ENUM_PFX << CMangle(ast->child(1), CMGL_ID_FLD)
01379 << ")";
01380 break;
01381 }
01382
01383 case at_select:
01384 {
01385 shared_ptr<Type> t = ast->child(0)->symType->getBareType();
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395 if (t->typeTag == ty_array) {
01396 out << t->arrLen->len;
01397 break;
01398 }
01399
01400 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
01401 ast, 0, flags);
01402
01403
01404
01405 if (t->typeTag == ty_vector) {
01406 out << "->length";
01407 }
01408 else if (t->typeTag == ty_array_ref) {
01409 out << ".length";
01410 }
01411 else {
01412 out << ((ast->child(0)->symType->isRefType()) ? "->" : "." );
01413 out << CMangle(ast->child(1), CMGL_ID_FLD);
01414 }
01415 break;
01416 }
01417
01418 case at_defunion:
01419 {
01420 shared_ptr<AST> ident = ast->child(0);
01421 shared_ptr<AST> ctrs = ast->child(4);
01422
01423 bool repr = ast->flags & UNION_IS_REPR;
01424 out << "/*** Tag Enumerations ***/" << endl;
01425 out << "typedef enum {" << endl;
01426 out.more();
01427
01428 if (ident->flags & NULLABLE_UN) {
01429 assert(!repr);
01430
01431
01432
01433 for (size_t c=0; c < ctrs->children.size(); c++) {
01434 shared_ptr<AST> ctr = ctrs->child(c);
01435 if (ctr->children.size() > 1) {
01436 out << ENUM_PFX << CMangle(ctr->child(0))
01437 << " = 1," << endl;
01438 }
01439 else {
01440 out << ENUM_PFX << CMangle(ctr->child(0));
01441 out << " = 0," << endl;
01442 }
01443 }
01444 }
01445 else if (ident->flags & CARDELLI_UN) {
01446 assert(!repr);
01447
01448 for (size_t c=0; c < ctrs->children.size(); c++) {
01449 shared_ptr<AST> ctr = ctrs->child(c);
01450 if (ctr->children.size() > 1) {
01451 out << ENUM_PFX << CMangle(ctr->child(0))
01452 << " = 0," << endl;
01453 }
01454 else {
01455 out << ENUM_PFX << CMangle(ctr->child(0));
01456 out << " = ";
01457 out << ((2*c)+1);
01458 out << "," << endl;
01459 }
01460 }
01461 }
01462 else {
01463 for (size_t c=0; c < ctrs->children.size(); c++) {
01464 shared_ptr<AST> ctr = ctrs->child(c);
01465 out << ENUM_PFX << CMangle(ctr->child(0))
01466 << " = " << c
01467 << "," << endl;
01468 }
01469 }
01470
01471 out.less();
01472 out << "} " << TAG_PFX << CMangle(ident) << ";"
01473 << endl << endl;
01474
01475
01476 out << "/*** Structures for constructor legs ***/" << endl;
01477 for (size_t c = 0; c < ctrs->children.size(); c++) {
01478 shared_ptr<AST> ctr = ctrs->child(c);
01479 shared_ptr<AST> ctrID = ctr->child(0);
01480
01481 if (ctrID->stCtr == ctrID) {
01482 out << "typedef struct {" << endl;
01483 out.more();
01484
01485 if (!repr)
01486 if ((ident->flags & SINGLE_LEG_UN) == 0)
01487 if ((((ident->flags & CARDELLI_UN) == 0) &&
01488 ((ident->flags & NULLABLE_UN) == 0)) ||
01489 (ctr->children.size() == 1)) {
01490 out << decl(ident->tagType, "tag", CTYP_EMIT_BF,
01491 ident->field_bits)<< ";" << endl;
01492 }
01493
01494 for (size_t i = 1; i < ctr->children.size(); i++) {
01495 shared_ptr<AST> field = ctr->child(i);
01496 TOC(errStream, uoc, field, out, IDname, decls, ctr, i, flags);
01497 }
01498
01499 out.less();
01500 out << "} " << TY_PFX << CMangle(ctrID)
01501 << ";" << endl << endl;
01502 }
01503 else {
01504 out << "typedef "
01505 << TY_PFX << CMangle(ctrID->stCtr) << " "
01506 << TY_PFX << CMangle(ctrID)
01507 << ";" << endl << endl;
01508 }
01509 }
01510
01511 out << "/*** Main union ***/" << endl;
01512 out << "union " << TY_PFX << CMangle(ident) << "{" << endl;
01513 out.more();
01514
01515 if (!repr)
01516 out << TAG_PFX << CMangle(ident) << " tag;" << endl;
01517
01518 for (size_t c = 0; c < ctrs->children.size(); c++) {
01519 shared_ptr<AST> ctr = ctrs->child(c);
01520 out << TY_PFX << CMangle(ctr->child(0)) << " "
01521 << "leg_" << CMangle(ctr->child(0)) << ";" << endl;
01522 }
01523 out.less();
01524 out << "};" << endl << endl;
01525
01526
01527 out << "/*** Tag Accessor ***/" << endl;
01528 if (!repr)
01529 out << "INLINE ";
01530 out << TAG_PFX << CMangle(ident) << endl
01531 << "TAG_" << CMangle(ident) << "("
01532 << toCtype(ident->symType);
01533 if (!ident->symType->isRefType())
01534 out << "*";
01535 out << " arg)"
01536 << endl
01537 << "{"
01538 << endl;
01539 out.more();
01540
01541 string accessor = "arg->tag";
01542
01543 if (repr) {
01544 for (size_t c = 0; c < ctrs->children.size(); c++) {
01545 shared_ptr<AST> ctr = ctrs->child(c);
01546 out << "if (";
01547 bool emitted1=false;
01548 for (size_t i = 1; i < ctr->children.size(); i++) {
01549 shared_ptr<AST> field = ctr->child(i);
01550 if (field->flags & FLD_IS_DISCM) {
01551 if (emitted1)
01552 out << " && ";
01553 out << "("
01554 << "((" << TY_PFX << CMangle(ctr->child(0)) << " *)"
01555 << "arg)->"
01556 << CMangle(field->child(0), CMGL_ID_FLD)
01557 << " == "
01558 << field->unin_discm
01559 << ")";
01560 emitted1=true;
01561 }
01562 }
01563 assert(emitted1);
01564 out << ")" << endl;
01565 out.more();
01566 out << "return " << ENUM_PFX << CMangle(ctr->child(0)) << ";" << endl;
01567 out.less();
01568 }
01569
01570 out << " /* Keep the Compiler happy */ " << endl;
01571 out << " assert(false);" << endl;
01572 out << " return 0;" << endl;
01573 }
01574 else if (ident->flags & SINGLE_LEG_UN) {
01575 out << "return 0;" << endl;
01576 }
01577 else if (ident->flags & NULLABLE_UN) {
01578 out << "if (" << accessor << ")" << endl;
01579 out.more();
01580 out << "return 1;" << endl;
01581 out.less();
01582 out << "else" << endl;
01583 out.more();
01584 out << "return 0;" << endl;
01585 out.less();
01586 }
01587 else if (ident->flags & CARDELLI_UN) {
01588 out << "if (" << accessor << " & 0x1u)" << endl;
01589 out.more();
01590 out << "return " << accessor << ";" << endl;
01591 out.less();
01592 out << "else" << endl;
01593 out.more();
01594 out << "return 0;" << endl;
01595 out.less();
01596 }
01597 else {
01598 out << "return " << accessor << ";" << endl;
01599 }
01600 out.less();
01601 out << "}"
01602 << endl;
01603
01604 out << "/*** Constructors: ***/" << endl;
01605 std::string pre;
01606 stringstream udecl;
01607 if (ident->symType->getBareType()->typeTag == ty_unionv) {
01608 udecl << toCtype(ident->symType) << " val;" << endl;
01609 pre = "val.";
01610 }
01611 else {
01612 udecl << toCtype(ident->symType)
01613 << " val = "
01614 << "(" << toCtype(ident->symType) << ") "
01615 << "GC_ALLOC(sizeof(" << TY_PFX << CMangle(ident) << "));"
01616 << endl;
01617 pre = "val->";
01618 }
01619
01620 for (size_t c = 0; c < ctrs->children.size(); c++) {
01621 shared_ptr<AST> ctr = ctrs->child(c);
01622 shared_ptr<AST> ctrID = ctr->child(0);
01623 out << "INLINE " << toCtype(ident->symType) << endl
01624 << CTOR_PFX << CMangle(ctrID) << " ";
01625
01626 emit_ct_args(out, ctr, 1);
01627
01628 out << "{" << endl;
01629 out.more();
01630 out << udecl.str();
01631 out << TY_PFX << CMangle(ctrID) << " leg;" << endl;
01632
01633 if (!repr)
01634 if ((ident->flags & SINGLE_LEG_UN) == 0)
01635 if (((ident->flags & CARDELLI_UN) == 0) ||
01636 (ctr->children.size() == 1)) {
01637 out << "leg.tag = " << ENUM_PFX << CMangle(ctrID)
01638 << ";" << endl;
01639 }
01640
01641 emit_ct_inits(out, ctr, "leg.", 1);
01642
01643 out << pre << "leg_" << CMangle(ctrID) << " = leg;" << endl;
01644 out << "return val;" << endl;
01645 out.less();
01646 out << "}" << endl;
01647 out << endl;
01648 }
01649
01650 break;
01651 }
01652
01653 case at_constructors:
01654 case at_constructor:
01655 {
01656 assert(false);
01657 break;
01658 }
01659
01660 case at_defrepr:
01661
01662
01663
01664
01665
01666 case at_reprctrs:
01667 case at_reprctr:
01668 case at_reprrepr:
01669 {
01670 assert(false);
01671 break;
01672 }
01673
01674 case at_defexception:
01675 {
01676 shared_ptr<AST> ident = ast->child(0);
01677
01678 if (flags & TOC_HEADER_MODE) {
01679 out << "extern const char " << TAG_PFX << CMangle(ident) << "[]; "
01680 << endl;
01681 }
01682 else {
01683 out << "const char " << TAG_PFX << CMangle(ident) << "[] = "
01684 << "\"" << ident->fqn.ident << "\"" << ";" << endl;
01685 }
01686
01687 shared_ptr<AST> fields = ast->child(4);
01688
01689 if (fields->children.size() > 1) {
01690 out << "typedef struct {" << endl;
01691 out.more();
01692 out << "const char *__fileName;" << endl;
01693 out << "int __line;" << endl;
01694
01695 out << "const char* __name;" << endl;
01696
01697 TOC(errStream, uoc, fields, out, IDname, decls, ast, 4, flags);
01698
01699 #if 0
01700 for (size_t c = 0; c < ast->children.size(); c++) {
01701 shared_ptr<AST> field = ast->child(c);
01702 if (field->astType == at_fill)
01703 continue;
01704
01705 out << decl(field->child(1)->symType,
01706 field->child(0)->s, true)
01707 << ";" << endl;
01708 }
01709 #endif
01710
01711 out.less();
01712 out << "} " << TY_PFX << CMangle(ident) << ";" << endl << endl;
01713
01714 out << "/* Exception Constructor */" << endl;
01715 out << "INLINE " << TY_PFX << CMangle(ident) << "*" << endl
01716 << CTOR_PFX << CMangle(ident) << " ";
01717
01718 emit_ct_args(out, fields);
01719 out << "{" << endl;
01720 out.more();
01721 out << TY_PFX << CMangle(ident) << "* val = (" << TY_PFX << CMangle(ident) << "*)"
01722 << "GC_ALLOC(sizeof(" << TY_PFX << CMangle(ident) << "));" << endl;
01723 out << "val->__name = " << TAG_PFX << CMangle(ident) << ";" << endl;
01724
01725 emit_ct_inits(out, fields, "val->", 1);
01726
01727 out << "return val;" << endl;
01728 out.less();
01729 out << "}" << endl << endl;
01730 }
01731 else {
01732
01733 out << "typedef bitc_exception_t " << TY_PFX << CMangle(ident)
01734 << ";" << endl;
01735
01736 if (flags & TOC_HEADER_MODE) {
01737 out << "extern bitc_exception_t " << CVAL_PFX << CMangle(ident)
01738 << ";" << endl;
01739 }
01740 else {
01741 out << "bitc_exception_t " << CVAL_PFX << CMangle(ident)
01742 << " = { " << endl;
01743 out.more();
01744 out << ".__name = " << TAG_PFX << CMangle(ident) << endl;
01745 out.less();
01746 out << "};" << endl << endl;
01747 }
01748 }
01749 break;
01750 }
01751
01752 case at_declunion:
01753 case at_declstruct:
01754 case at_declrepr:
01755 {
01756 shared_ptr<AST> ident = ast->child(0);
01757 if (ident->defn)
01758 ident = ident->defn;
01759
01760 string nm = TY_PFX + CMangle(ident);
01761 if (decls.find(nm) != decls.end())
01762 break;
01763
01764 decls.insert(nm);
01765
01766 out << "typedef ";
01767 if (ast->astType == at_declunion || ast->astType == at_declrepr)
01768 out << "union ";
01769 else
01770 out << "struct ";
01771 out << nm << " " << nm << ";" << endl;
01772 break;
01773 }
01774
01775 case at_proclaim:
01776 {
01777 shared_ptr<AST> id = ast->getID();
01778 bool hasDefn = false;
01779
01780 if (id->defn) {
01781 id = id->defn;
01782 hasDefn = true;
01783 }
01784
01785 out << "extern ";
01786
01787 decls.insert(CMangle(id));
01788
01789
01790
01791
01792
01793 if (id->symType->isFnxn() && !id->symType->isMutable()) {
01794 std::string name = (id->externalName.size())?id->externalName:id->s;
01795 emit_fnxn_type(out, name, id->symType);
01796 out << ";" << endl;
01797 }
01798 else {
01799 declare(out, id, "");
01800 }
01801
01802
01803
01804
01805 if (id->symType->isFnxn() && id->externalName.size()) {
01806 shared_ptr<Type> fnType = id->symType->getBareType();
01807 shared_ptr<Type> ret = fnType->Ret();
01808 shared_ptr<Type> args = fnType->Args();
01809
01810 if (!typeIsUnmangled(ret)) {
01811 out << "typedef "
01812 << decl(ret, RET_PFX + id->externalName)
01813 << ";" << endl;
01814 }
01815
01816 for (size_t i=0; i < args->components.size(); i++) {
01817 shared_ptr<Type> arg = args->CompType(i);
01818
01819 if (!typeIsUnmangled(arg)) {
01820 stringstream as;
01821 as << ARG_PFX << i << "_" << id->externalName;
01822
01823 out << "typedef "
01824 << decl(arg, as.str())
01825 << ";" << endl;
01826 }
01827 }
01828 }
01829
01830 break;
01831 }
01832
01833 case at_recdef:
01834 case at_define:
01835 {
01836 shared_ptr<AST> id = ast->child(0)->child(0);
01837
01838
01839
01840
01841
01842
01843 if (decls.find(CMangle(id)) == decls.end())
01844 if (id->flags & ID_IS_PRIVATE)
01845 out << "static ";
01846
01847 if (ast->child(1)->astType == at_lambda) {
01848
01849
01850
01851
01852 CHKERR(errorFree, emit_fnxn_label(errStream, uoc, ast, out,
01853 decls, parent, chno, flags));
01854 }
01855 else if (flags & TOC_HEADER_MODE) {
01856
01857
01858
01859
01860
01861 out << "extern ";
01862 out << decl(id) << ";"
01863 << endl;
01864 }
01865 else {
01866
01867 shared_ptr<AST> e = ast->child(1);
01868 shared_ptr<AST> p = ast;
01869 size_t c = 1;
01870
01871 while (e->astType == at_typeAnnotation) {
01872 p = e;
01873 c = 0;
01874 e = e->child(0);
01875 }
01876
01877
01878
01879
01880 out << decl(id) << " = ";
01881 TOC(errStream, uoc, e, out, IDname, decls, p, c, flags);
01882 out << ";" << endl;
01883 }
01884 break;
01885 }
01886
01887 case at_container:
01888 {
01889 if (ast->child(0)->children.size() != 0) {
01890
01891 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
01892 ast, 0, flags);
01893 out << "_" << IDname << ":" << endl;
01894 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
01895 ast, 1, flags);
01896
01897 }
01898 else {
01899 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
01900 ast, 1, flags);
01901 }
01902 break;
01903 }
01904
01905 case at_identList:
01906 {
01907 for (size_t c=0; c < ast->children.size(); c++)
01908 declare(out, ast->child(c));
01909 break;
01910 }
01911
01912 case at_suspend:
01913 {
01914 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
01915 ast, 1, flags);
01916
01917 break;
01918 }
01919
01920 case at_typeAnnotation:
01921 {
01922
01923 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
01924 ast, 0, flags);
01925
01926 break;
01927 }
01928
01929 case at_loop:
01930 {
01931 shared_ptr<AST> lbs = ast->child(0);
01932
01933 for (size_t c = 0; c < lbs->children.size(); c++) {
01934 shared_ptr<AST> lb = lbs->child(c);
01935 shared_ptr<AST> init = lb->child(1);
01936 TOC(errStream, uoc, init, out, IDname, decls, lb, 1, flags);
01937 }
01938
01939 out << "loop_" << ast->ID << ":" << endl;
01940 out.indent(2);
01941
01942 shared_ptr<AST> dotest = ast->child(1);
01943 shared_ptr<AST> cond = dotest->child(0);
01944 shared_ptr<AST> res = dotest->child(1);
01945 shared_ptr<AST> body = ast->child(2);
01946 shared_ptr<AST> theCond;
01947
01948 if (cond->astType == at_letStar) {
01949 TOC(errStream, uoc, cond, out, IDname, decls,
01950 dotest, 0, flags);
01951 theCond = FEXPR(cond);
01952 }
01953 else {
01954 theCond = cond;
01955 }
01956
01957 out << "if (";
01958 TOC(errStream, uoc, theCond, out, IDname, decls,
01959 GC_NULL, 0, flags);
01960 out << ") {" << endl;
01961 out.more();
01962 TOC(errStream, uoc, res, out, IDname, decls,
01963 dotest, 1, flags);
01964 out << endl;
01965 out.less();
01966 out << "}" << endl;
01967
01968 out << "else {" << endl;
01969 out.more();
01970 TOC(errStream, uoc, body, out, IDname, decls,
01971 ast, 1, flags);
01972
01973 if (body->astType != at_letStar)
01974 out << ";" << endl;
01975
01976 for (size_t c = 0; c < lbs->children.size(); c++) {
01977 shared_ptr<AST> lb = lbs->child(c);
01978 shared_ptr<AST> step = lb->child(2);
01979 TOC(errStream, uoc, step, out, IDname, decls, lb, 2, flags);
01980 }
01981
01982 out << "goto " << "loop_" << ast->ID << ";" << endl;
01983 out << endl;
01984 out.less();
01985 out << "}" << endl;
01986 out.indent(-2);
01987 break;
01988 }
01989
01990 case at_labeledBlock:
01991 {
01992
01993 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
01994 ast, 1, flags);
01995 out << ";" << endl;
01996
01997 shared_ptr<AST> labelDef = ast->child(0);
01998 std::stringstream ss;
01999 ss << LBL_PFX << CMangle(labelDef->s) << labelDef->ID;
02000
02001 out.indent(-1);
02002 out << ss.str() << ":" << endl;
02003 out.indent(1);
02004
02005 break;
02006 }
02007
02008 case at_return_from:
02009 {
02010
02011
02012 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
02013 ast, 1, flags);
02014 out << ";" << endl;
02015
02016 shared_ptr<AST> labelDef = ast->child(0)->symbolDef;
02017 std::stringstream ss;
02018 ss << LBL_PFX << CMangle(labelDef->s) << labelDef->ID;
02019
02020 out << "goto " << ss.str() << ";" << endl;
02021
02022 break;
02023 }
02024
02025 case at_begin:
02026 {
02027 if (ast->children.size()) {
02028
02029 for (size_t c = 0; c < ast->children.size(); c++) {
02030 TOC(errStream, uoc, ast->child(c), out, IDname, decls,
02031 ast, c, flags);
02032
02033 out << ";" << endl;
02034 }
02035 }
02036 else {
02037
02038 out << 0;
02039 }
02040
02041
02042 break;
02043 }
02044
02045 case at_apply:
02046 {
02047
02048
02049
02050
02051
02052
02053
02054
02055 if (ast->child(0)->astType == at_ident) {
02056 shared_ptr<AST> id = ast->child(0);
02057 assert(id->symbolDef);
02058
02059 if (id->flags & SELF_TAIL) {
02060 shared_ptr<AST> lbps = id->symbolDef->defbps;
02061 assert(lbps);
02062 assert(ast->children.size() == lbps->children.size() + 1);
02063 out << "/* Tail recursive application: */ " << endl;
02064 for (size_t c = 0; c < lbps->children.size(); c++) {
02065 shared_ptr<AST> ident = lbps->child(c)->child(0);
02066 TOC(errStream, uoc, ident, out, IDname, decls,
02067 lbps->child(c), 0, flags);
02068 out << " = ";
02069 TOC(errStream, uoc, ast->child(c+1), out, IDname, decls,
02070 ast, c+1, flags);
02071 out << ";" << endl;
02072 }
02073 out << "goto " << "_" << CMangle(id) << ";" << endl;
02074 break;
02075 }
02076 }
02077
02078 shared_ptr<Type> clType = ast->child(0)->symType->getBareType();
02079 assert(clType->typeTag == ty_fn);
02080 shared_ptr<Type> retType = clType->Ret()->getType();
02081 shared_ptr<Type> argsType = clType->Args()->getType();
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092 if (isUnitType(retType))
02093 out << "(";
02094
02095 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02096 ast, 0, flags);
02097
02098 out << "(";
02099 size_t count = 0;
02100 for (size_t c=1; c < ast->children.size(); c++) {
02101
02102
02103
02104
02105
02106
02107 if (isUnitType(ast->child(c)))
02108 continue;
02109
02110 if (count > 0)
02111 out << ", ";
02112
02113 if (argsType->CompFlags(c-1) & COMP_BYREF)
02114 out << "&";
02115
02116 TOC(errStream, uoc, ast->child(c), out, IDname, decls,
02117 ast, c, flags);
02118 count++;
02119 }
02120 out << ")";
02121
02122 if (isUnitType(retType))
02123 out << ",0)";
02124
02125 break;
02126 }
02127
02128 case at_mkArrayRef:
02129 {
02130 assert(IDname.size());
02131 shared_ptr<Type> arrType = ast->child(0)->symType->getType();
02132 assert(arrType->arrLen->len != 0);
02133 out << IDname << ".length = " << arrType->arrLen->len << ";" << endl;
02134 out << IDname << ".elem = ";
02135 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02136 ast, 0, flags);
02137 out << ".elem;" << endl;
02138 break;
02139 }
02140
02141 case at_array:
02142 {
02143 assert(IDname.size());
02144 for (size_t c = 0; c < ast->children.size(); c++) {
02145 out << IDname << ".elem[" << c << "] = ";
02146 TOC(errStream, uoc, ast->child(c), out, IDname, decls,
02147 ast, c, flags);
02148 out << ";" << endl;
02149 }
02150 out << endl;
02151 break;
02152 }
02153
02154 case at_vector:
02155 {
02156 if (IDname.size() == 0) {
02157 assert(1);
02158 }
02159 assert(IDname.size());
02160 shared_ptr<Type> t = ast->symType->getBareType();
02161 out << IDname << " = (" << toCtype(t) << ") "
02162 << "GC_ALLOC(sizeof("
02163 << CMangle(t->mangledString(true)) << ") + "
02164 << "(" << ast->children.size() << " * sizeof("
02165 << toCtype(t->Base()) << ")));"
02166 << endl;
02167
02168 out << IDname << "->length = " << ast->children.size()
02169 << ";" << endl;
02170 out << IDname << "->elem = (("
02171 << toCtype(t->Base())
02172 << " *) (((char *) " << IDname << ") + "
02173 << "sizeof(" << CMangle(t->mangledString(true)) << ")));"
02174 << endl;
02175 for (size_t c = 0; c < ast->children.size(); c++) {
02176 out << IDname << "->elem[" << c << "] = ";
02177 TOC(errStream, uoc, ast->child(c), out, IDname, decls,
02178 ast, c, flags);
02179 out << ";" << endl;
02180 }
02181 out << endl;
02182 break;
02183 }
02184
02185 case at_MakeVector:
02186 {
02187 assert(IDname.size());
02188 shared_ptr<Type> t = ast->symType->getBareType();
02189 out << IDname << " = (" << toCtype(ast->symType) << ") "
02190 << "GC_ALLOC(sizeof("
02191 << CMangle(t->mangledString(true)) << ") + "
02192 << "(";
02193 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02194 ast, 0, flags);
02195 out << " * sizeof("
02196 << toCtype(t->Base()) << ")));"
02197 << endl;
02198
02199 out << IDname << "->length = ";
02200 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02201 ast, 0, flags);
02202 out << ";" << endl;
02203
02204 out << IDname << "->elem = (("
02205 << toCtype(t->Base())
02206 << " *) (((char *) " << IDname << ") + "
02207 << "sizeof(" << CMangle(t->mangledString(true)) << ")));"
02208 << endl;
02209
02210 out << "{" << endl;
02211 out.more();
02212 out << "bitc_word_t __bitc_temp_mvec;" << endl;
02213 out << "for (__bitc_temp_mvec = 0; __bitc_temp_mvec < ";
02214 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02215 ast, 0, flags);
02216 out << "; __bitc_temp_mvec++)" << endl;
02217 out.more();
02218 out << IDname << "->elem[__bitc_temp_mvec] = ";
02219
02220
02221 shared_ptr<AST> hackIdent = AST::make(at_ident, ast->loc);
02222 hackIdent->s = "__bitc_temp_mvec";
02223 hackIdent->flags |= ID_IS_GENSYM;
02224 hackIdent->symType = Type::make(ty_word);
02225 shared_ptr<AST> apply = AST::make(at_apply, ast->loc,
02226 ast->child(1), hackIdent);
02227 TOC(errStream, uoc, apply, out, IDname, decls, ast, 1, flags);
02228 out << ";" << endl;
02229 out.less();
02230 out.less();
02231 out << "}" << endl;
02232 out << endl;
02233 break;
02234 }
02235
02236 #ifdef HAVE_INDEXABLE_LENGTH_OPS
02237 case at_array_length:
02238 {
02239 shared_ptr<Type> arrType =
02240 ast->child(0)->symType->getBareType();
02241 out << arrType->arrLen->len;
02242 break;
02243 }
02244
02245 case at_array_ref_length:
02246 {
02247 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02248 ast, 0, flags);
02249 out << ".length";
02250 break;
02251 }
02252
02253 case at_vector_length:
02254 {
02255 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02256 ast, 0, flags);
02257 out << "->length";
02258 break;
02259 }
02260 #endif
02261
02262 case at_nth:
02263
02264 assert(false);
02265 break;
02266 case at_array_nth:
02267 case at_array_ref_nth:
02268 case at_vector_nth:
02269 {
02270 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02271 ast, 0, flags);
02272
02273 if (ast->astType == at_vector_nth)
02274 out << "->";
02275 else
02276 out << ".";
02277
02278 out << "elem[";
02279 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
02280 ast, 1, flags);
02281 out << "]";
02282 break;
02283 }
02284
02285 case at_uswitch:
02286 {
02287 shared_ptr<AST> topExp = ast->child(1);
02288 shared_ptr<AST> cases = ast->child(2);
02289 shared_ptr<AST> ow = ast->child(3);
02290
02291 shared_ptr<Type> t = topExp->symType->getBareType();
02292
02293 out << "switch(";
02294
02295 assert(t->typeTag == ty_uvalv || t->typeTag == ty_unionv ||
02296 t->typeTag == ty_uvalr || t->typeTag == ty_unionr ||
02297 t->typeTag == ty_uconr || t->typeTag == ty_uconv);
02298
02299 out << "TAG_" << CMangle(t->myContainer) << "(";
02300 if (!topExp->symType->isRefType())
02301 out << "&";
02302 TOC(errStream, uoc, topExp, out, IDname, decls, ast, 0, flags);
02303 out << ")";
02304 out << ") {" << endl;;
02305 out.more();
02306
02307 for (size_t c=0; c < cases->children.size(); c++) {
02308
02309 shared_ptr<AST> theCase = cases->child(c);
02310 shared_ptr<AST> expr = theCase->child(1);
02311 shared_ptr<AST> legIdent = theCase->child(0);
02312
02313 for (size_t n=2; n < theCase->children.size(); n++) {
02314 shared_ptr<AST> ctr = theCase->child(n)->getCtr();
02315
02316 std::string leg = CMangle(ctr);
02317 out << "case " << ENUM_PFX << leg << " :" << endl;
02318 }
02319
02320 out.more();
02321 out << "{" << endl;
02322 out.more();
02323
02324 TOC(errStream, uoc, legIdent, out, IDname, decls, theCase, 0, flags);
02325 out << " = ";
02326
02327 if (t->isRefType())
02328 out << "&";
02329 TOC(errStream, uoc, topExp, out, IDname, decls, ast, 0, flags);
02330 if (t->isValType())
02331 out << ".";
02332 else
02333 out << "->";
02334
02335 out << "leg_" << CMangle(theCase->child(2)->getCtr());
02336 out << ";" << endl;
02337
02338 TOC(errStream, uoc, expr, out, IDname, decls, theCase, 1, flags);
02339 out << "break;";
02340 out << endl;
02341 out.less();
02342 out << "}" << endl;
02343 out.less();
02344 out << endl;
02345 }
02346
02347 if (ow->astType != at_Null) {
02348 shared_ptr<AST> legIdent = ow->child(0);
02349
02350 out << "default:" << endl;
02351 out.more();
02352 out << "{" << endl;
02353 out.more();
02354
02355 TOC(errStream, uoc, legIdent, out, IDname, decls, ow, 0, flags);
02356 out << " = ";
02357
02358 TOC(errStream, uoc, topExp, out, IDname, decls, ast, 0, flags);
02359 out << ";" << endl;
02360
02361 TOC(errStream, uoc, ow->child(1), out, IDname, decls, ow, 1, flags);
02362 out << "break;";
02363 out << endl;
02364 out.less();
02365 out << "}" << endl;
02366 out.less();
02367 out << endl;
02368 }
02369 out.less();
02370 out << "}" << endl;
02371
02372 break;
02373 }
02374
02375 case at_usw_legs:
02376 case at_usw_leg:
02377 case at_otherwise:
02378 case at_condelse:
02379 {
02380 assert(false);
02381 break;
02382 }
02383
02384 case at_try:
02385 {
02386 shared_ptr<AST> topExpr = ast->child(0);
02387 shared_ptr<AST> cases = ast->child(2);
02388 shared_ptr<AST> ow = ast->child(3);
02389 out << "{" << endl;
02390 out.more();
02391 out << "jmp_buf jb;" << endl;
02392 out << "jmp_buf *lastJB = curCatchBlock;" << endl;
02393 out << "curCatchBlock = &jb;" << endl;
02394 out << endl;
02395 out << "int result = setjmp(jb);" << endl;
02396 out << "if (!result) {" << endl;
02397 out.more();
02398 TOC(errStream, uoc, topExpr, out, IDname, decls,
02399 ast, 0, flags);
02400 out << "curCatchBlock = lastJB;" << endl;
02401 out.less();
02402 out << "}" << endl;
02403 out << "else {" << endl;
02404 out.more();
02405 out << "curCatchBlock = lastJB;" << endl;
02406
02407
02408 for (size_t c = 0; c < cases->children.size(); c++) {
02409 shared_ptr<AST> theCase = cases->child(c);
02410 shared_ptr<AST> expr = theCase->child(1);
02411 shared_ptr<AST> legIdent = theCase->child(0);
02412
02413 if (c > 0)
02414 out << "else " << endl;
02415
02416 out << "if (";
02417 for (size_t n=2; n < theCase->children.size(); n++) {
02418 shared_ptr<AST> exn = theCase->child(n);
02419
02420 if (n > 2)
02421 out << " || ";
02422 out << "(curException->__name == "
02423 << TAG_PFX << CMangle(exn) << ")";
02424 }
02425 out << ") {" << endl;
02426 out.more();
02427 TOC(errStream, uoc, legIdent, out, IDname, decls, ow, 0, flags);
02428 out << " = "
02429 << "((" << toCtype(legIdent->symType, legIdent->s) << ") "
02430 << "curException);" << endl;
02431
02432 TOC(errStream, uoc, expr, out, IDname, decls, theCase, 1, flags);
02433 out.less();
02434 out << "}" << endl;
02435 }
02436
02437 if (ow->astType != at_Null) {
02438
02439 if (cases->children.size())
02440 out << "else ";
02441
02442 out << "{" << endl;
02443 out.more();
02444
02445 shared_ptr<AST> legIdent = ow->child(0);
02446
02447
02448
02449 TOC(errStream, uoc, legIdent, out, IDname, decls, ow, 0, flags);
02450 out << " = curException;" << endl;
02451
02452 TOC(errStream, uoc, ow->child(1), out, IDname, decls, ow, 1, flags);
02453 out.less();
02454 out << "}" << endl;
02455 out << endl;
02456 }
02457 else {
02458 out << "else {" << endl;
02459 out.more();
02460 out << "longjmp(*curCatchBlock, 1);" << endl;
02461 out.less();
02462 out << "}" << endl;
02463 }
02464 out.less();
02465 out << "}" << endl;
02466 out.less();
02467 out << "}" << endl;
02468
02469 break;
02470 }
02471
02472 case at_throw:
02473 {
02474
02475
02476
02477
02478 out << "bitc_throw(\""
02479 << ast->loc.origin << "\", "
02480 << ast->loc.line << ", "
02481 << "(bitc_exception_t *) ";
02482 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02483 ast, 0, flags);
02484 out <<");" << endl;
02485 break;
02486 }
02487
02488 case at_setbang:
02489 {
02490 assert(IDname.size());
02491
02492 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02493 ast, 0, flags);
02494 out << " = ";
02495 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
02496 ast, 1, flags);
02497 out << ";" << endl;
02498
02499 out << IDname << " = (bitc_unit_t) 0;" << endl;
02500 break;
02501 }
02502
02503 case at_sizeof:
02504 {
02505 shared_ptr<Type> ty = ast->child(0)->getType();
02506 out << " sizeof(" << toCtype(ty) << ") ";
02507 break;
02508 }
02509
02510 case at_bitsizeof:
02511 {
02512 shared_ptr<Type> ty = ast->child(0)->getType();
02513 out << " (8*sizeof(" << toCtype(ty) << ")) ";
02514 break;
02515 }
02516
02517 case at_dup:
02518 {
02519 assert(IDname.size());
02520 shared_ptr<AST> arg = ast->child(0);
02521 out << IDname << " = "
02522 << "(("
02523 << toCtype(ast->symType)
02524 << ") GC_ALLOC(sizeof("
02525 << toCtype(arg->symType)
02526 << ")));" << endl;
02527 out << "*" << IDname << " = ";
02528 TOC(errStream, uoc, arg, out, IDname, decls, ast, 0, flags);
02529 out << ";" << endl;
02530 break;
02531 }
02532
02533 case at_deref:
02534 {
02535 out << "(* ";
02536 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02537 ast, 0, flags);
02538 out << ")";
02539 break;
02540 }
02541
02542 case at_inner_ref:
02543 {
02544 out << "&";
02545 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02546 ast, 0, flags);
02547 out << "->";
02548
02549 if (ast->flags & INNER_REF_NDX) {
02550 out << "elem[";
02551 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
02552 ast, 1, flags);
02553 out << "]";
02554 }
02555 else {
02556 out << CMangle(ast->child(1), CMGL_ID_FLD);
02557 }
02558 break;
02559 }
02560
02561 case at_if:
02562 {
02563 shared_ptr<AST> testAst = ast->child(0);
02564 shared_ptr<AST> thenAst = ast->child(1);
02565 shared_ptr<AST> elseAst = ast->child(2);
02566 out << "if (";
02567 TOC(errStream, uoc, testAst, out, IDname, decls,
02568 ast, 0, flags);
02569 out << ") {" << endl;
02570 out.more();
02571 TOC(errStream, uoc, thenAst, out, IDname, decls,
02572 ast, 1, flags);
02573 if (thenAst->astType != at_letStar)
02574 out << ";";
02575 out << endl;
02576 out.less();
02577 out << "}" << endl;
02578 out << "else {" << endl;
02579 out.more();
02580 TOC(errStream, uoc, elseAst, out, IDname, decls,
02581 ast, 2, flags);
02582 if (elseAst->astType != at_letStar)
02583 out << ";";
02584 out << endl;
02585 out.less();
02586 out << "}" << endl;
02587 break;
02588 }
02589
02590 case at_when:
02591 case at_unless:
02592 {
02593 shared_ptr<AST> testAst = ast->child(0);
02594 shared_ptr<AST> thenAst = ast->child(1);
02595
02596 out << "if (";
02597 if (ast->astType == at_unless) out << "!(";
02598 TOC(errStream, uoc, testAst, out, IDname, decls,
02599 ast, 0, flags);
02600 if (ast->astType == at_unless) out << ")";
02601 out << ") {" << endl;
02602 out.more();
02603 TOC(errStream, uoc, thenAst, out, IDname, decls,
02604 ast, 1, flags);
02605 if (thenAst->astType != at_letStar)
02606 out << ";";
02607 out << endl;
02608 out.less();
02609 out << "}" << endl;
02610 break;
02611 }
02612
02613 case at_letStar:
02614 case at_letrec:
02615 case at_let:
02616 {
02617
02618 TOC(errStream, uoc, ast->child(0), out, IDname, decls,
02619 ast, 0, flags);
02620
02621 shared_ptr<AST> lExpr = ast->child(1);
02622 if (lExpr->astType == at_typeAnnotation)
02623 lExpr = lExpr->child(0);
02624
02625 switch(lExpr->astType) {
02626 case at_ident:
02627 case at_boolLiteral:
02628 case at_charLiteral:
02629 case at_intLiteral:
02630 case at_floatLiteral:
02631 case at_stringLiteral:
02632 break;
02633
02634 default:
02635
02636 TOC(errStream, uoc, ast->child(1), out, IDname, decls,
02637 ast, 1, flags);
02638 out << ";" << endl;
02639 break;
02640 }
02641
02642 break;
02643 }
02644
02645 case at_letbindings:
02646 {
02647 for (size_t i=0; i < ast->children.size(); i++)
02648 TOC(errStream, uoc, ast->child(i), out, IDname, decls,
02649 ast, i, flags);
02650 break;
02651 }
02652
02653 case at_letbinding:
02654 {
02655 assert(ast->child(0)->astType == at_identPattern);
02656 shared_ptr<AST> ident = ast->child(0)->child(0);
02657 if ((ast->flags & LB_IS_DUMMY) == 0) {
02658 if ((ast->flags & LB_POSTPONED) == 0)
02659 out << CMangle(ident) << " = ";
02660 }
02661
02662 TOC(errStream, uoc, ast->child(1), out, CMangle(ident),
02663 decls, ast, 1, flags);
02664 if (((ast->flags & LB_IS_DUMMY) == 0) &&
02665 ((ast->flags & LB_POSTPONED) == 0))
02666 out << ";" << endl;
02667 break;
02668 }
02669 }
02670 return errorFree;
02671 }
02672
02673 static bool
02674 alreadyEmitted(shared_ptr<Type> t,
02675 const set<string>& theSet)
02676 {
02677 std::string nm = CMangle(t->mangledString(true));
02678 return (theSet.find(nm) != theSet.end());
02679 }
02680
02681 static void
02682 emit_arr_vec_fn_types(shared_ptr<Type> candidate,
02683 INOstream &out,
02684 set<string>& arrSet,
02685 set<string>& arrByrefSet,
02686 set<string>& vecSet,
02687 set<string>& fnSet)
02688 {
02689 shared_ptr<Type> t = candidate->getBareType();
02690 if (t->mark & MARK_EMIT_ARR_VEC_FN_TYPES)
02691 return;
02692
02693 t->mark |= MARK_EMIT_ARR_VEC_FN_TYPES;
02694
02695 for (size_t i=0; i<t->typeArgs.size(); i++)
02696 emit_arr_vec_fn_types(t->TypeArg(i), out,
02697 arrSet, arrByrefSet, vecSet, fnSet);
02698
02699 for (size_t i=0; i<t->components.size(); i++)
02700 emit_arr_vec_fn_types(t->CompType(i), out,
02701 arrSet, arrByrefSet, vecSet, fnSet);
02702
02703 switch(t->typeTag) {
02704 case ty_array:
02705 {
02706 if (alreadyEmitted(t, arrSet))
02707 break;
02708
02709 assert(t->arrLen->len != 0);
02710
02711 arrSet.insert(CMangle(t->mangledString(true)));
02712
02713
02714
02715
02716
02717 shared_ptr<Type> et = t->Base()->getBareType();
02718 out << "/* Typedef in anticipation of the array type:"
02719 << endl
02720 << " * Sexpr: " << t->asSexprString() << endl
02721 << " * Block: " << t->asBlockString() << endl
02722 << " */" << endl;
02723
02724 out << "typedef struct {" << endl;
02725 out.more();
02726
02727 out << toCtype(et) << " elem[" << t->arrLen->len << "];" << endl;
02728 out.less();
02729 out << "} " << CMangle(t->mangledString(true))
02730 << ";" << endl << endl;
02731 break;
02732 }
02733
02734 case ty_array_ref:
02735 {
02736 if (alreadyEmitted(t, arrByrefSet))
02737 break;
02738
02739 arrByrefSet.insert(CMangle(t->mangledString(true)));
02740
02741
02742
02743
02744
02745 shared_ptr<Type> et = t->Base()->getBareType();
02746 out << "/* Typedef in anticipation of the arrayByRef type:"
02747 << endl
02748 << " * Sexpr: " << t->asSexprString() << endl
02749 << " * Block: " << t->asBlockString() << endl
02750 << " */" << endl;
02751
02752 out << "typedef struct {" << endl;
02753 out.more();
02754
02755 out << "bitc_word_t length;" << endl;
02756 out << toCtype(et) << " *elem;" << endl;
02757 out.less();
02758 out << "} " << CMangle(t->mangledString(true))
02759 << ";" << endl << endl;
02760 break;
02761 }
02762
02763 case ty_vector:
02764 {
02765 if (alreadyEmitted(t, vecSet))
02766 break;
02767
02768 vecSet.insert(CMangle(t->mangledString(true)));
02769
02770 shared_ptr<Type> et = t->Base()->getBareType();
02771 out << "/* Typedef in anticipation of the vector type:"
02772 << endl
02773 << " * Sexpr: " << t->asSexprString() << endl
02774 << " * Block: " << t->asBlockString() << endl
02775 << " */" << endl;
02776
02777 out << "typedef struct {" << endl;
02778 out.more();
02779
02780 out << "bitc_word_t length;" << endl;
02781 out << toCtype(et) << " *elem;" << endl;
02782 out.less();
02783 out << "} " << CMangle(t->mangledString(true))
02784 << ";" << endl << endl;
02785 break;
02786 }
02787
02788 case ty_fn:
02789 {
02790 if (alreadyEmitted(t, fnSet))
02791 break;
02792
02793 std::string fnName = t->mangledString(true);
02794 fnSet.insert(CMangle(fnName));
02795 out << "/* Typedef in anticipation of the function (pointer) type:"
02796 << endl
02797 << " * Sexpr: " << t->asSexprString() << endl
02798 << " * Block: " << t->asBlockString() << endl
02799 << " */" << endl;
02800 out << "typedef ";
02801 emit_fnxn_type(out, fnName, t, true);
02802 out << ";" << endl << endl;
02803 break;
02804 }
02805
02806 default:
02807 {
02808 break;
02809 }
02810 }
02811
02812 t->mark &= ~MARK_EMIT_ARR_VEC_FN_TYPES;
02813 }
02814
02815
02816 static void
02817 emit_arr_vec_fn_types(shared_ptr<AST> ast,
02818 INOstream &out,
02819 set<string>& arrSet,
02820 set<string>& arrByrefSet,
02821 set<string>& vecSet,
02822 set<string>& fnSet)
02823 {
02824 if (ast->symType)
02825 emit_arr_vec_fn_types(ast->symType, out,
02826 arrSet, arrByrefSet, vecSet, fnSet);
02827
02828
02829 for (size_t c = 0; c < ast->children.size(); c++)
02830 emit_arr_vec_fn_types(ast->child(c), out,
02831 arrSet, arrByrefSet, vecSet, fnSet);
02832 }
02833
02834
02835 static bool
02836 TypesTOC(std::ostream& errStream,
02837 shared_ptr<UocInfo> uoc,
02838 INOstream &out,
02839 set<string> &decls,
02840 unsigned long flags)
02841 {
02842 bool errFree = true;
02843 shared_ptr<AST> mod = uoc->uocAst;
02844 set<string> arrSet;
02845 set<string> arrByrefSet;
02846 set<string> vecSet;
02847 set<string> fnSet;
02848
02849 for (size_t c=0; (c < mod->children.size()); c++) {
02850 shared_ptr<AST> ast = mod->child(c);
02851
02852 switch(ast->astType) {
02853 case at_declstruct:
02854 case at_declunion:
02855 {
02856
02857
02858
02859
02860
02861 out << "////////////////////////////////////////" << endl;
02862 out.setPostindent("// ");
02863 out << ast->loc << endl
02864 << ast->asString(pp_Raw) << endl;
02865 out.setPostindent("");
02866 out << "////////////////////////////////////////" << endl;
02867
02868 CHKERR(errFree, toc(errStream, uoc, ast, out, "", decls,
02869 mod, c, flags));
02870 out << endl;
02871 break;
02872 }
02873
02874 case at_defstruct:
02875 case at_defunion:
02876 {
02877
02878
02879
02880
02881
02882 emit_arr_vec_fn_types(ast, out, arrSet, arrByrefSet,
02883 vecSet, fnSet);
02884
02885 out << "////////////////////////////////////////" << endl;
02886 out.setPostindent("// ");
02887 out << ast->loc << endl
02888 << ast->asString(pp_Raw) << endl;
02889 out.setPostindent("");
02890 out << "////////////////////////////////////////" << endl;
02891
02892 shared_ptr<AST> ident = ast->child(0);
02893 if (decls.find(CMangle(ident)) == decls.end()) {
02894 decls.insert(CMangle(ident));
02895
02896 out << "/* Forward declaration */" << endl;
02897 out << "typedef ";
02898 out << ((ast->astType == at_defstruct) ? "struct " : "union ");
02899 out << TY_PFX << CMangle(ident) << " "
02900 << TY_PFX << CMangle(ident) << ";" << endl;
02901 out << endl;
02902 }
02903
02904 CHKERR(errFree, toc(errStream, uoc, ast, out, "", decls,
02905 mod, c, flags));
02906 out << endl << endl;
02907 break;
02908 }
02909
02910 case at_defexception:
02911 {
02912
02913
02914
02915
02916
02917 emit_arr_vec_fn_types(ast, out, arrSet, arrByrefSet,
02918 vecSet, fnSet);
02919
02920 out << "////////////////////////////////////////" << endl;
02921 out.setPostindent("// ");
02922 out << ast->loc << endl
02923 << ast->asString(pp_Raw) << endl;
02924 out.setPostindent("");
02925 out << "////////////////////////////////////////" << endl;
02926
02927 CHKERR(errFree, toc(errStream, uoc, ast, out, "", decls,
02928 mod, c, flags));
02929 out << endl << endl;
02930
02931 break;
02932 }
02933
02934 case at_proclaim:
02935 case at_recdef:
02936 case at_define:
02937 {
02938 emit_arr_vec_fn_types(ast, out, arrSet, arrByrefSet,
02939 vecSet, fnSet);
02940 break;
02941 }
02942
02943 default:
02944 {
02945 break;
02946 }
02947 }
02948 }
02949
02950 return errFree;
02951 }
02952
02953 static bool
02954 emitInitProc(std::ostream& errStream, shared_ptr<AST> ast,
02955 shared_ptr<UocInfo> uoc,
02956 INOstream &out, INOstream &initStream,
02957 set<string> &decls,
02958 unsigned long flags)
02959 {
02960 bool answer = true;
02961 bool errorFree = true;
02962 assert(ast->astType == at_define || ast->astType == at_recdef);
02963 out << "static "
02964 << toCtype(ast->getID()->symType)
02965 << endl
02966 << "__init" << ast->ID << "()" << endl
02967 << "{" << endl;
02968 out.more();
02969
02970 shared_ptr<AST> id = ast->child(0)->child(0);
02971 shared_ptr<AST> body = ast->child(1);
02972 shared_ptr<AST> ret;
02973 assert(body->astType == at_container);
02974 if (body->child(1)->astType == at_letStar) {
02975 TOC(errStream, uoc, body, out, CMangle(id), decls, ast, 1, flags);
02976 out << ";" << endl;
02977
02978 ret = FEXPR(body->child(1));
02979 }
02980 else {
02981 ret = body->child(1);
02982 }
02983 assert(ret);
02984 out << "return ";
02985 TOC(errStream, uoc, ret, out, CMangle(id), decls, ast, 1, flags);
02986 out << ";" << endl;
02987 out.less();
02988 out << "}" << endl;
02989
02990 initStream << CMangle(ast->getID()) << " = ";
02991 initStream << "__init" << ast->ID << "();" << endl;
02992 return errorFree;
02993 }
02994
02995 static bool
02996 EmitGlobalInitializers(std::ostream& errStream,
02997 shared_ptr<UocInfo> uoc,
02998 INOstream &out,
02999 set<string> &decls,
03000 unsigned long flags)
03001 {
03002 bool errFree = true;
03003 stringstream is;
03004 INOstream initStream(is);
03005
03006 initStream.more();
03007
03008 shared_ptr<AST> mod = uoc->uocAst;
03009 for (size_t c = 0; c < mod->children.size(); c++) {
03010 shared_ptr<AST> ast = mod->child(c);
03011
03012 switch(ast->astType) {
03013 case at_define:
03014 case at_recdef:
03015 {
03016
03017
03018
03019
03020
03021 out << "////////////////////////////////////////" << endl;
03022 out.setPostindent("// ");
03023 out << ast->loc << endl
03024 << ast->asString(pp_Raw) << endl;
03025 out.setPostindent("");
03026 out << "////////////////////////////////////////" << endl;
03027
03028 shared_ptr<AST> id = ast->getID();
03029 shared_ptr<AST> label = GC_NULL;
03030 bool wrapperNeeded = false;
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041 if ((id->symType->isFnxn()) && (!id->symType->isMutable()) &&
03042 (ast->child(1)->astType != at_lambda)) {
03043 wrapperNeeded = true;
03044 label = AST::make(id);
03045 ast->rename(id, WFN_PFX + id->s);
03046 }
03047
03048 if (ast->flags & DEF_IS_TRIVIAL_INIT) {
03049
03050
03051
03052
03053 CHKERR(errFree, toc(errStream, uoc, ast, out, "", decls,
03054 mod, c, flags));
03055 }
03056 else if (ast->child(1)->astType == at_lambda) {
03057 assert(!id->symType->isMutable());
03058
03059
03060
03061
03062
03063
03064
03065 shared_ptr<AST> ptr = AST::make(id);
03066 id->s = MFN_PFX + id->s;
03067 out << "extern " << decl(ptr) << ";" << endl;
03068 CHKERR(errFree, toc(errStream, uoc, ast, out, "", decls,
03069 mod, c, flags));
03070 out << decl(ptr) << " = " << CMangle(id)
03071 << ";" << endl << endl;
03072 id->s = ptr->s;
03073 }
03074 else {
03075
03076
03077
03078
03079
03080 declare(out, ast->getID());
03081
03082
03083 CHKERR(errFree, emitInitProc(errStream, ast, uoc, out,
03084 initStream, decls, flags));
03085 }
03086
03087 if (wrapperNeeded) {
03088 shared_ptr<Type> fnType = id->symType->getBareType();
03089 shared_ptr<Type> ret = fnType->Ret();
03090 shared_ptr<Type> args = fnType->Args()->getBareType();
03091
03092 emit_fnxn_type(out, label->s, id->symType);
03093 out << endl;
03094 out << "{" << endl;
03095 out.more();
03096
03097 if (!isUnitType(ret))
03098 out << "return ";
03099
03100 out << CMangle(id);
03101 out << "(";
03102 for (size_t i=0; i < args->components.size(); i++) {
03103 shared_ptr<Type> arg = args->CompType(i);
03104 if (isUnitType(arg))
03105 continue;
03106
03107 if (i > 0)
03108 out << ", ";
03109
03110 out << "arg" << i;
03111 }
03112 out << ");" << endl;
03113
03114 out.less();
03115 out << "}" << endl << endl;
03116 } else {
03117 }
03118
03119 break;
03120 }
03121
03122 case at_proclaim:
03123 {
03124
03125
03126
03127
03128 out << "////////////////////////////////////////" << endl;
03129 out.setPostindent("// ");
03130 out << ast->loc << endl
03131 << ast->asString(pp_Raw) << endl;
03132 out.setPostindent("");
03133 out << "////////////////////////////////////////" << endl;
03134
03135 CHKERR(errFree, toc(errStream, uoc, ast, out, "", decls,
03136 mod, c, flags));
03137 break;
03138 }
03139
03140 default:
03141 {
03142 break;
03143 }
03144 }
03145 out << endl << endl;
03146 }
03147
03148 initStream.less();
03149
03150
03151
03152 out << "////////////////////////////////////////" << endl;
03153 out.setPostindent("// ");
03154 out << "The Initializer";
03155 out.setPostindent("");
03156 out << "////////////////////////////////////////" << endl;
03157 if (UocInfo::mainIsDefined)
03158 out << "static " ;
03159 out << "void" << endl
03160 << "bitc_init_globals()" << endl
03161 << "{" << endl;
03162 out << is.str();
03163 out << "}" << endl;
03164 out << endl;
03165
03166
03167 return errFree;
03168 }
03169
03170 static bool
03171 EmitMain(INOstream &out)
03172 {
03173 bool errFree = true;
03174
03175 out << "////////////////////////////////////////" << endl;
03176 out.setPostindent("// ");
03177 out << "The main procedure";
03178 out.setPostindent("");
03179 out << "////////////////////////////////////////" << endl;
03180
03181 out << "int" << endl
03182 << "main(int argc, char*argv[])" << endl
03183 << "{" << endl;
03184 out.more();
03185 out << "int result;" << endl;
03186 out << "int i;" << endl << endl;
03187
03188 out.less();
03189 out << "#if defined(__linux__)" << endl;
03190 out.more();
03191 out << "int my_personality = personality(-1);" << endl;
03192 out << "my_personality |= 0x0400000; /* READ_IMPLIES_EXEC */" << endl;
03193 out << "personality(my_personality);" << endl;
03194 out.less();
03195 out << "#endif" << endl;
03196 out.more();
03197
03198 out << "GC_INIT();" << endl;
03199 out << endl;
03200 out << "result = setjmp(firstJB);" << endl
03201 << "if (!result) {" << endl;
03202 out.more();
03203
03204 out << "bitc_init_globals();" << endl;
03205
03206 out << "TY_VECTOR_OF_STRINGS *argVec = " << endl;
03207 out.more();
03208 out << "(TY_VECTOR_OF_STRINGS*) GC_ALLOC(sizeof(TY_VECTOR_OF_STRINGS));"
03209 << endl;
03210 out.less();
03211
03212 out << "argVec->length = argc;" << endl
03213 << "argVec->elem = " << endl;
03214 out.more();
03215 out << "(bitc_string_t **) GC_ALLOC(sizeof(bitc_string_t *) * argc);"
03216 << endl;
03217 out.less();
03218 out << "for (i = 0; i < argc; i++)" << endl;
03219 out.more();
03220 out << "argVec->elem[i] = mkStringLiteral(argv[i]);" << endl;
03221 out.less();
03222 out << endl;
03223
03224 out << "return bitc_main(argVec)"
03225 << ";" << endl;
03226
03227 out.less();
03228 out << "}" << endl;
03229 out << "else {" << endl;
03230 out.more();
03231 out << "printf(\"Uncaught %s exception raised at %s:%d\\n\", "
03232 << "curException->__name, curException->__fileName, curException->__line);" << endl
03233 << "exit(1);" << endl;
03234 out.less();
03235 out << "}" << endl;
03236 out.less();
03237 out << "}" << endl;
03238
03239 return errFree;
03240 }
03241
03242 static bool
03243 ValuesTOH(std::ostream& errStream,
03244 shared_ptr<UocInfo> uoc,
03245 INOstream &out,
03246 set<string> &decls,
03247 unsigned long flags)
03248 {
03249 bool errFree = true;
03250
03251 shared_ptr<AST> mod = uoc->uocAst;
03252 for (size_t c = 0; c < mod->children.size(); c++) {
03253 shared_ptr<AST> ast = mod->child(c);
03254 switch(ast->astType) {
03255 case at_proclaim:
03256 {
03257 if (ast->getID()->flags & DEF_IS_EXTERNAL) {
03258 out << "////////////////////////////////////////" << endl;
03259 out.setPostindent("// ");
03260 out << ast->loc << endl
03261 << ast->asString(pp_Raw) << endl;
03262 out.setPostindent("");
03263 out << "////////////////////////////////////////" << endl;
03264
03265 CHKERR(errFree, toc(errStream, uoc, ast, out, "", decls,
03266 mod, c, flags));
03267 out << endl;
03268 }
03269 break;
03270 }
03271 default:
03272 {
03273 break;
03274 }
03275 }
03276 }
03277 return errFree;
03278 }
03279
03280 bool
03281 GenerateCoutput(std::ostream &errStream, INOstream &out,
03282 unsigned long flags, shared_ptr<UocInfo> uoc)
03283 {
03284 bool errFree = true;
03285
03286 assert(uoc);
03287 set<string> decls;
03288
03289 out << "/////////////////////////////////////////////" << endl;
03290 out.setPostindent("// ");
03291 out << " This code was automatically generated by " << endl
03292 << " BitC compiler version " << Version() << endl
03293 << endl
03294 << " !!! DO NOT EDIT !!! " << endl
03295 << " !! uness you are sure !! " << endl;
03296 out.setPostindent("");
03297 out << "/////////////////////////////////////////////" << endl;
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314 out << "#include <bitc/runtime.h>" << endl << endl;
03315
03316 out << "#if defined(__linux__)" << endl;
03317 out << "#include <sys/personality.h>" << endl;
03318 out << "#endif" << endl << endl;
03319
03320 if ((flags & TOC_HEADER_MODE) == 0) {
03321 out << "jmp_buf firstJB;" << endl << endl;
03322 out << "jmp_buf *curCatchBlock = &firstJB;" << endl;
03323 out << "bitc_exception_t *curException;" << endl << endl;
03324 }
03325
03326 CHKERR(errFree, TypesTOC(errStream, uoc, out, decls, flags));
03327
03328 if (flags & TOC_HEADER_MODE) {
03329 CHKERR(errFree, ValuesTOH(errStream, uoc, out, decls, flags));
03330 }
03331 else {
03332
03333
03334 if (!Options::entryPts.empty())
03335 CHKERR(errFree, EmitGlobalInitializers(errStream, uoc, out,
03336 decls, flags));
03337
03338
03339
03340
03341 if (UocInfo::mainIsDefined)
03342 EmitMain(out);
03343 }
03344
03345 return errFree;
03346 }
03347
03348 bool
03349 EmitHeader(std::ostream &optStream, std::ostream &errStream,
03350 shared_ptr<UocInfo> uoc)
03351 {
03352 std::ofstream out(Options::outputFileName.c_str(),
03353 std::ios_base::out|std::ios_base::trunc);
03354
03355 if (!out.is_open())
03356 errStream << "Couldn't open output file \""
03357 << Options::outputFileName
03358 << "\" -- "
03359 << strerror(errno)
03360 << endl;
03361
03362 INOstream ino_out(out);
03363 bool result = GenerateCoutput(errStream, ino_out,
03364 TOC_HEADER_MODE, uoc);
03365 out.close();
03366 return result;
03367 }
03368
03369 bool
03370 EmitC(std::ostream &optStream, std::ostream &errStream,
03371 shared_ptr<UocInfo> uoc)
03372 {
03373 std::ofstream out(Options::outputFileName.c_str(),
03374 std::ios_base::out|std::ios_base::trunc);
03375 if (!out.is_open())
03376 errStream << "Couldn't open output file \""
03377 << Options::outputFileName
03378 << "\" -- "
03379 << strerror(errno)
03380 << endl;
03381
03382 INOstream ino_out(out);
03383 bool result = GenerateCoutput(errStream, ino_out, 0, uoc);
03384 out.close();
03385 return result;
03386 }
03387
03388 bool
03389 EmitExe(std::ostream &optStream, std::ostream &errStream,
03390 shared_ptr<UocInfo> uoc)
03391 {
03392 std::ofstream csrc("bitc.out.c",
03393 std::ios_base::out|std::ios_base::trunc);
03394
03395 if (!csrc.is_open()) {
03396 errStream << "Couldn't open auxiliary file \""
03397 << "bitc.out.c"
03398 << "\" -- "
03399 << strerror(errno)
03400 << "\n";
03401 return false;
03402 }
03403
03404 INOstream out(csrc);
03405 bool result = GenerateCoutput(errStream, out, 0, uoc);
03406 csrc.close();
03407
03408 if (!result)
03409 return false;
03410
03411 int status;
03412
03413
03414 {
03415 stringstream opt;
03416 opt << STD_CC_CMD << " -c ";
03417
03418 for (size_t i = 0; i < Options::CompilePreOptionsGCC.size(); i++)
03419 opt << " " << Options::CompilePreOptionsGCC[i];
03420
03421 opt << " -o bitc.out.o";
03422 opt << " bitc.out.c";
03423
03424 if (Options::verbose)
03425 std::cerr << opt.str() << std::endl;
03426
03427 status = ::system(opt.str().c_str());
03428 if (WEXITSTATUS(status))
03429 goto done;
03430 }
03431
03432 {
03433 stringstream opt;
03434 opt << "gcc";
03435
03436 for (size_t i = 0; i < Options::LinkPreOptionsGCC.size(); i++)
03437 opt << " " << Options::LinkPreOptionsGCC[i];
03438
03439 opt << " bitc.out.o";
03440
03441 for (size_t i = 0; i < Options::LinkPostOptionsGCC.size(); i++)
03442 opt << " " << Options::LinkPostOptionsGCC[i];
03443
03444 if (Options::useStdLib)
03445 opt << " -lbitc";
03446
03447 if (Options::noGC)
03448 opt << " -lbitc-no-gc";
03449 else
03450 opt << " -lgc";
03451
03452 if (Options::verbose)
03453 std::cerr << opt.str() << std::endl;
03454
03455 status = ::system(opt.str().c_str());
03456 }
03457
03458 done:
03459 filesystem::remove("bitc.out.c");
03460 filesystem::remove("bitc.out.o");
03461
03462 return WEXITSTATUS(status) ? false : true;
03463 }
03464