12 static Context globalContext { };
13 static Module privateModule;
14 static ModuleImport mainModule;
15 static OldList _excludedSymbols { offset = (uint)&((Symbol)0).left };
16 static OldList defines, imports;
17 static NameSpace globalData
19 classes.CompareKey = (void *)BinaryTree::CompareString;
20 defines.CompareKey = (void *)BinaryTree::CompareString;
21 functions.CompareKey = (void *)BinaryTree::CompareString;
22 nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
24 static OldList _precompDefines;
26 static void OutputImports(char * fileName)
28 File f = FileOpen(fileName, write);
34 f.Printf("[Imported Modules]\n");
35 for(module = imports.first; module; module = module.next)
38 FunctionImport function;
41 f.Printf(" %s\n", module.name);
43 f.Printf(" [This]\n");
44 if(module.importType == staticImport)
45 f.Printf(" [Static]\n");
46 else if(module.importType == remoteImport)
47 f.Printf(" [Remote]\n");
49 if(module.importAccess == privateAccess)
50 f.Printf(" [Private]\n");
52 f.Printf(" [Public]\n");
54 if(module.classes.first)
56 f.Printf(" [Imported Classes]\n");
57 for(_class = module.classes.first; _class; _class = _class.next)
59 f.Printf(" %s\n", _class.name);
62 f.Printf(" [Instantiated]\n");
66 f.Printf(" [Remote]\n");
69 if(_class.methods.first)
72 f.Printf(" [Imported Methods]\n");
73 for(method = _class.methods.first; method; method = method.next)
75 f.Printf(" %s\n", method.name);
77 f.Printf(" [Virtual]\n");
83 if(_class.properties.first)
86 f.Printf(" [Imported Properties]\n");
87 for(prop = _class.properties.first; prop; prop = prop.next)
89 f.Printf(" %s\n", prop.name);
91 f.Printf(" [Virtual]\n");
102 if(module.functions.first)
104 f.Printf(" [Imported Functions]\n");
105 for(function = module.functions.first; function; function = function.next)
107 f.Printf(" %s\n", function.name);
118 class CompilerApp : Application
122 char * cppCommand = null;
123 char * cppOptions = null;
124 int cppOptionsLen = 0;
125 /*char ** argv = null;
129 char defaultOutputFile[MAX_LOCATION];
130 bool buildingBootStrap = false;
132 Platform targetPlatform = GetRuntimePlatform();
133 int targetBits = GetHostBits();
137 /*for(c = 0; c<this.argc; c++)
139 char * arg = this.argv[c];
140 int argLen = strlen(arg);
142 argv = renew argv char *[argc + 1];
143 argv[argc] = new char[argLen+1];
144 strcpy(argv[argc], arg);
146 while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
153 argv[argc] = renew argv[argc] char[argLen + len + 1];
155 argv[argc][argLen-1] = ' ';
156 strcpy(argv[argc] + argLen, arg);
162 for(c = 1; c<argc; c++)
164 char * arg = argv[c];
167 if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
169 int argLen = strlen(arg);
170 int newLen = cppOptionsLen + 1 + argLen;
171 cppOptions = renew cppOptions char[newLen + 1];
172 cppOptions[cppOptionsLen] = ' ';
173 strcpy(cppOptions + cppOptionsLen + 1, arg);
174 cppOptionsLen = newLen;
175 targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
177 else if(arg[1] == 'D')
179 int argLen = strlen(arg);
180 int newLen = cppOptionsLen + 1 + argLen;
181 cppOptions = renew cppOptions char[newLen + 1];
182 cppOptions[cppOptionsLen] = ' ';
183 strcpy(cppOptions + cppOptionsLen + 1, arg);
184 cppOptionsLen = newLen;
185 if(!strcmp(arg, "-DBUILDING_ECERE_COM"))
186 SetBuildingEcereCom(true);
187 else if(!strcmp(arg, "-DECERE_COM_MODULE"))
188 SetBuildingEcereComModule(true);
189 else if(!strcmp(arg, "-DECERE_BOOTSTRAP"))
190 buildingBootStrap = true;
192 else if(arg[1] == 'I')
194 int argLen = strlen(arg);
195 int newLen = cppOptionsLen + argLen + 3;
196 cppOptions = renew cppOptions char[newLen + 1];
197 cppOptions[cppOptionsLen] = ' ';
198 cppOptions[cppOptionsLen+1] = '-';
199 cppOptions[cppOptionsLen+2] = 'I';
200 cppOptions[cppOptionsLen+3] = '"';
201 strcpy(cppOptions + cppOptionsLen + 4, arg+2);
202 cppOptions[newLen-1] = '\"';
203 cppOptions[newLen] = '\0';
204 cppOptionsLen = newLen;
206 else if(!strcmp(arg+1, "t"))
209 targetPlatform = argv[c];
213 else if(!strcmp(arg+1, "cpp"))
216 cppCommand = CopyString(argv[c]);
220 else if(!strcmp(arg+1, "o"))
222 if(!GetOutputFile() && c + 1 < argc)
224 SetOutputFile(argv[c+1]);
230 else if(!strcmp(arg+1, "c"))
232 if(!GetSourceFile() && c + 1 < argc)
234 SetSourceFile(argv[c+1]);
240 else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot"))
244 int argLen = strlen(arg);
245 int arg1Len = strlen(argv[c+1]);
246 int newLen = cppOptionsLen + argLen + arg1Len + 4;
247 cppOptions = renew cppOptions char[newLen + 1];
248 cppOptions[cppOptionsLen] = ' ';
249 strcpy(cppOptions + cppOptionsLen + 1, arg);
250 cppOptions[cppOptionsLen+argLen+1] = ' ';
251 cppOptions[cppOptionsLen+argLen+2] = '"';
253 strcpy(cppOptions + cppOptionsLen + argLen + 3, arg);
254 cppOptions[newLen-1] = '\"';
255 cppOptions[newLen] = '\0';
256 cppOptionsLen = newLen;
261 else if(!strcmp(arg+1, "symbols"))
265 SetSymbolsDir(argv[c+1]);
271 else if(!strcmp(arg+1, "memguard"))
273 SetMemoryGuard(true);
275 else if(!strcmp(arg+1, "defaultns"))
279 SetDefaultNameSpace(argv[c+1]);
280 //defaultNameSpaceLen = strlen(defaultNameSpace);
286 else if(!strcmp(arg+1, "strictns"))
288 SetStrictNameSpaces(true);
290 else if(!strcmp(arg+1, "nolinenumbers"))
292 SetOutputLineNumbers(false);
301 cppCommand = CopyString("gcc");
304 else if(!GetOutputFile())
306 strcpy(defaultOutputFile, "");
307 PathCat(defaultOutputFile, GetSourceFile());
308 ChangeExtension(defaultOutputFile, "c", defaultOutputFile);
309 SetOutputFile(defaultOutputFile);
314 printf($"Syntax:\n ecc [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
318 // TODO: Improve this
319 char command[MAX_F_STRING*3];
320 SetGlobalData(&globalData);
321 SetExcludedSymbols(&_excludedSymbols);
322 SetGlobalContext(globalContext);
323 SetCurrentContext(globalContext);
324 SetTopContext(globalContext);
325 SetDefines(&::defines);
326 SetImports(&imports);
328 SetTargetPlatform(targetPlatform);
329 SetTargetBits(targetBits);
332 privateModule = (Module)__ecere_COM_Initialize(true | (targetBits == sizeof(uintptr)*8 ? 0 : targetBits == 64 ? 2 : targetBits==32 ? 4 : 0) | 8, 1, null);
333 SetPrivateModule(privateModule);
335 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
336 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
337 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
338 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
339 globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
340 if(buildingBootStrap)
342 // Do not define this when we pre-include stdint.h or the eC compiler will be confused when parsing these types (External prioritization in pass15.ec will fail)
343 globalContext.types.Add((BTNode)Symbol { string = CopyString("intptr_t"), type = ProcessTypeString("intptr", false) });
344 globalContext.types.Add((BTNode)Symbol { string = CopyString("uintptr_t"), type = ProcessTypeString("uintptr", false) });
345 globalContext.types.Add((BTNode)Symbol { string = CopyString("ssize_t"), type = ProcessTypeString("intsize", false) });
346 globalContext.types.Add((BTNode)Symbol { string = CopyString("size_t"), type = ProcessTypeString("uintsize", false) });
350 GlobalData data { fullName = CopyString("__thisModule"), dataTypeString = CopyString("Module"), module = privateModule };
351 data.key = (uintptr)data.fullName;
352 globalData.functions.Add((BTNode)data);
355 snprintf(command, sizeof(command), "%s%s -x c -E %s\"%s\"", cppCommand, cppOptions ? cppOptions : "", buildingBootStrap ? "" : "-include stdint.h -include sys/types.h ", GetSourceFile());
356 command[sizeof(command)-1] = 0;
357 if((cppOutput = DualPipeOpen({ output = true }, command)))
359 char impFile[MAX_LOCATION];
360 ImportedModule module;
361 char mainModuleName[MAX_FILENAME];
365 TempFile fileInput { };
366 SetFileInput(fileInput);
368 imports.Add((mainModule = ModuleImport { }));
369 SetMainModule(mainModule);
371 GetLastDirectory(GetSourceFile(), mainModuleName);
374 // TEMP: UNTIL WE CAN HAVE PER SOURCE FILE PREPROCESSOR DEFINITIONS...
375 if(GetBuildingEcereCom() &&
376 !(strcmpi(mainModuleName, "instance.ec") && strcmpi(mainModuleName, "BinaryTree.ec") &&
377 strcmpi(mainModuleName, "dataTypes.ec") && strcmpi(mainModuleName, "OldList.ec") &&
378 strcmpi(mainModuleName, "String.ec") && strcmpi(mainModuleName, "BTNode.ec") &&
379 strcmpi(mainModuleName, "Array.ec") && strcmpi(mainModuleName, "AVLTree.ec") &&
380 strcmpi(mainModuleName, "BuiltInContainer.ec") && strcmpi(mainModuleName, "Container.ec") &&
381 strcmpi(mainModuleName, "CustomAVLTree.ec") && strcmpi(mainModuleName, "LinkList.ec") &&
382 strcmpi(mainModuleName, "List.ec") && strcmpi(mainModuleName, "Map.ec") &&
383 strcmpi(mainModuleName, "Mutex.ec")))
384 SetBuildingEcereComModule(true);
385 if(GetBuildingEcereCom() &&
386 !(strcmpi(mainModuleName, "instance.ec") && strcmpi(mainModuleName, "BinaryTree.ec") &&
387 /*strcmpi(mainModuleName, "dataTypes.ec") && strcmpi(mainModuleName, "OldList.ec") &&*/
388 /*strcmpi(mainModuleName, "String.ec") && */strcmpi(mainModuleName, "BTNode.ec") &&
389 strcmpi(mainModuleName, "Mutex.ec") && strcmpi(mainModuleName, "Thread.ec")))
390 //if(GetBuildingEcereCom() && !strcmpi(mainModuleName, "instance.ec"))
391 SetMemoryGuard(false);
394 StripExtension(mainModuleName);
395 module = ImportedModule { name = CopyString(mainModuleName), type = moduleDefinition };
396 ::defines.AddName(module);
399 while(!cppOutput.Eof())
402 int count = cppOutput.Read(junk, 1, 4096);
403 fileInput.Write(junk, 1, count);
405 exitCode = cppOutput.GetExitCode();
408 fileInput.Seek(0, start);
414 // Predeclare all classes
416 char symFile[MAX_FILENAME];
417 char symLocation[MAX_LOCATION];
418 ImportedModule module, next;
420 GetLastDirectory(GetSourceFile(), symFile);
421 ChangeExtension(symFile, "sym", symFile);
423 strcpy(symLocation, GetSymbolsDir());
424 PathCat(symLocation, symFile);
426 // LoadSymbols(symLocation, normalImport, true);
427 LoadSymbols(symLocation, preDeclImport, false);
429 for(module = ::defines.first; module; module = next)
432 if(module.type == moduleDefinition && strcmpi(module.name, mainModuleName))
435 ::defines.Delete(module);
439 if(!GetEcereImported() && !GetBuildingEcereCom())
440 eModule_LoadStrict(privateModule, "ecereCOM", publicAccess /*privateAccess*/);
445 CheckDataRedefinitions();
448 SetCurrentNameSpace(null);
449 SetDefaultNameSpace(null);
450 SetDeclMode(privateAccess);
457 if(/*ast /*&& !parseError*/ /*&& */!exitCode)
459 ProcessDBTableDefinitions();
461 // *** PASS 0 - Register all classes, methods, properties and members ***
462 // *** Build the constructors, destructors, properties as ***
463 // *** class functions ***
464 PrePreProcessClassDefinitions();
465 ComputeModuleClasses(privateModule);
466 PreProcessClassDefinitions();
468 // For classes defined in this module...
469 ComputeModuleClasses(privateModule);
472 // *** PASS 1 - Turn the class functions into functions ***
473 // *** Write the RegisterModule (Register classes) ***
474 ProcessClassDefinitions();
476 // *** PASS 1.5 - Replace members by this.member, figure out types, do type checking / conversions
479 // *** PASS 1.6 - Replace instantiations
480 ProcessInstantiations();
482 // *** PASS 2 - Replace Member Access ***
483 ProcessMemberAccess();
485 // *** PASS 3 - Replace pointers to objects by "Instance *" ***
486 ProcessInstanceDeclarations();
488 strcpy(impFile, GetSymbolsDir());
490 char fileName[MAX_FILENAME];
491 GetLastDirectory(GetSourceFile(), fileName);
492 PathCat(impFile, fileName);
493 ChangeExtension(impFile, "imp", impFile);
496 OutputImports(impFile);
497 // For now use precomp to generate sym file only...
499 if(/*!strcmp(targetExt, "c") && */!this.exitCode)
501 File output = FileOpen(GetOutputFile(), write);
504 output.Printf("#if defined(__GNUC__)\n");
505 output.Printf("typedef long long int64;\n");
506 output.Printf("typedef unsigned long long uint64;\n");
507 output.Printf("#ifndef _WIN32\n");
508 output.Printf("#define __declspec(x)\n");
509 output.Printf("#endif\n");
510 output.Printf("#elif defined(__TINYC__)\n");
511 output.Printf("#include <stdarg.h>\n");
512 output.Printf("#define __builtin_va_list va_list\n");
513 output.Printf("#define __builtin_va_start va_start\n");
514 output.Printf("#define __builtin_va_end va_end\n");
515 output.Printf("#ifdef _WIN32\n");
516 output.Printf("#define strcasecmp stricmp\n");
517 output.Printf("#define strncasecmp strnicmp\n");
518 output.Printf("#define __declspec(x) __attribute__((x))\n");
519 output.Printf("#else\n");
520 output.Printf("#define __declspec(x)\n");
521 output.Printf("#endif\n");
522 output.Printf("typedef long long int64;\n");
523 output.Printf("typedef unsigned long long uint64;\n");
524 output.Printf("#else\n");
525 output.Printf("typedef __int64 int64;\n");
526 output.Printf("typedef unsigned __int64 uint64;\n");
527 output.Printf("#endif\n");
528 output.Printf("#ifdef __BIG_ENDIAN__\n");
529 output.Printf("#define __ENDIAN_PAD(x) (8 - (x))\n");
530 output.Printf("#else\n");
531 output.Printf("#define __ENDIAN_PAD(x) 0\n");
532 output.Printf("#endif\n");
533 if(buildingBootStrap)
535 //output.Printf("#ifdef __MINGW32__\n");
536 //output.Printf("#ifdef _WIN64\n");
538 output.Printf("#if defined(_WIN64) || WORDSIZE == 64\n");
539 output.Printf("typedef unsigned long long int uintptr_t;\n");
540 output.Printf("typedef long long int intptr_t;\n");
541 output.Printf("#else\n");
542 output.Printf("typedef unsigned int uintptr_t;\n");
543 output.Printf("typedef int intptr_t;\n");
544 output.Printf("#endif\n");
546 //output.Printf("#else\n");
547 output.Printf("#include <stdint.h>\n");
548 output.Printf("#include <sys/types.h>\n");
549 //output.Printf("#endif\n");
552 // NOTE: If anything is changed up there, the start outputLine must be updated in libec's output.c or Debugging lines will be wrong
555 OutputTree(ast, output);
560 else if(!strcmp(targetExt, "o"))
562 // Compile right away
563 File output = FileOpen(GetOutputFile(), Write);
564 output.Printf("#include <ecereCOM.h>\n\n");
565 OutputTree(ast, output);
570 this.exitCode = exitCode;
578 FreeContext(globalContext);
579 FreeExcludedSymbols(_excludedSymbols);
581 ::defines.Free(FreeModuleDefine);
582 imports.Free(FreeModuleImport);
584 FreeTypeData(privateModule);
586 FreeGlobalData(globalData);
588 delete privateModule;
594 /*for(c = 0; c<argc; c++)
598 SetSymbolsDir(null); // Free symbols dir
602 #if defined(_DEBUG) && defined(__WIN32__)
603 if(exitCode || GetNumWarnings())