static bool driver (config conf) { bool fail = false; compilerCtx comp; compilerInit(&comp, &conf.arch, &conf.includeSearchPaths); /*Compile each of the inputs to assembly*/ for (int i = 0; i < conf.inputs.length; i++) { compiler(&comp, vectorGet(&conf.inputs, i), vectorGet(&conf.intermediates, i)); } compilerEnd(&comp); if (comp.errors != 0 || comp.warnings != 0) printf("Compilation complete with %d error%s and %d warning%s\n", comp.errors, plural(comp.errors), comp.warnings, plural(comp.warnings)); else if (internalErrors) printf("Compilation complete with %d internal error%s\n", internalErrors, plural(internalErrors)); /*Assemble/link*/ else if (conf.mode != modeNoAssemble) { /*Produce a string list of all the intermediates*/ char* intermediates = strjoinwith((char**) conf.intermediates.buffer, conf.intermediates.length, " ", malloc); if (conf.mode == modeNoLink) fail |= systemf("gcc %s -c %s", conf.arch.asflags, intermediates) != 0; else { fail |= systemf("gcc %s %s -o %s", conf.arch.ldflags, intermediates, conf.output) != 0; if (conf.deleteAsm && !fail) systemf("rm %s", intermediates); } free(intermediates); } return fail || comp.errors != 0 || internalErrors != 0; }
char* typeToStrEmbed (const type* DT, const char* embedded) { /*TODO: Jump through typedefs and offer akas Three modes: print as normal, print jumping through typedefs, print both forms with akas at the correct positions Even when directed to, it is to the discretion of this function as to whether it is sensible to reprint types*/ /*Basic type or invalid*/ if (DT->tag == typeInvalid || DT->tag == typeBasic) { char* basicStr = typeIsInvalid(DT) ? "<invalid>" : (DT->basic->ident && DT->basic->ident[0]) ? DT->basic->ident : DT->basic->tag == symStruct ? "<unnamed struct>" : DT->basic->tag == symUnion ? "<unnamed union>" : DT->basic->tag == symEnum ? "<unnamed enum>" : "<unnamed type>"; char* qualified = typeQualifiersToStr(DT->qual, basicStr); if (embedded[0] == (char) 0) return qualified; else { char* ret = malloc( strlen(embedded) + strlen(basicStr) + 2 + (DT->qual.isConst ? 6 : 0)); sprintf(ret, "%s %s", qualified, embedded); free(qualified); return ret; } /*Function*/ } else if (DT->tag == typeFunction) { /*Get the param string that goes inside the parens*/ char* params = 0; if (DT->params == 0) params = strdup("void"); else { vector/*<char*>*/ paramStrs; vectorInit(¶mStrs, DT->params+1); vectorPushFromArray(¶mStrs, (void**) DT->paramTypes, DT->params, sizeof(type*)); vectorMap(¶mStrs, (vectorMapper) typeToStr, ¶mStrs); if (DT->variadic) vectorPush(¶mStrs, "..."); params = strjoinwith((char**) paramStrs.buffer, paramStrs.length, ", ", malloc); if (DT->variadic) paramStrs.length--; vectorFreeObjs(¶mStrs, free); } /* */ char* format = malloc( strlen(embedded) + 2 + strlen(params) + 3); if (!embedded[0]) sprintf(format, "()(%s)", params); else sprintf(format, "%s(%s)", embedded, params); free(params); char* ret = typeToStrEmbed(DT->returnType, format); free(format); return ret; /*Array or Ptr*/ } else { char* format; if (typeIsPtr(DT)) { format = malloc(strlen(embedded) + 4 + (DT->qual.isConst ? 7 : 0)); char* qualified = typeQualifiersToStr(DT->qual, embedded); if (DT->base->tag == typeFunction) sprintf(format, "(*%s)", qualified); else sprintf(format, "*%s", qualified); free(qualified); } else { assert(typeIsArray(DT)); format = malloc( strlen(embedded) + (DT->array < 0 ? 0 : logi(DT->array, 10)) + 4); if (DT->array < 0) sprintf(format, "%s[]", embedded); else sprintf(format, "%s[%d]", embedded, DT->array); } char* ret = typeToStrEmbed(DT->base, format); free(format); return ret; } }