11 static Context globalContext { };
12 static Module privateModule;
13 static ModuleImport mainModule;
14 static OldList _excludedSymbols { offset = (uint)&((Symbol)0).left };
15 static OldList defines, imports;
16 static NameSpace globalData
18 classes.CompareKey = (void *)BinaryTree::CompareString;
19 defines.CompareKey = (void *)BinaryTree::CompareString;
20 functions.CompareKey = (void *)BinaryTree::CompareString;
21 nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
23 static OldList _precompDefines;
25 static void OutputImports(char * fileName)
27 File f = FileOpen(fileName, write);
33 f.Printf("[Imported Modules]\n");
34 for(module = imports.first; module; module = module.next)
37 FunctionImport function;
40 f.Printf(" %s\n", module.name);
42 f.Printf(" [This]\n");
43 if(module.importType == staticImport)
44 f.Printf(" [Static]\n");
45 else if(module.importType == remoteImport)
46 f.Printf(" [Remote]\n");
48 if(module.importAccess == privateAccess)
49 f.Printf(" [Private]\n");
51 f.Printf(" [Public]\n");
53 if(module.classes.first)
55 f.Printf(" [Imported Classes]\n");
56 for(_class = module.classes.first; _class; _class = _class.next)
58 f.Printf(" %s\n", _class.name);
61 f.Printf(" [Instantiated]\n");
65 f.Printf(" [Remote]\n");
68 if(_class.methods.first)
71 f.Printf(" [Imported Methods]\n");
72 for(method = _class.methods.first; method; method = method.next)
74 f.Printf(" %s\n", method.name);
76 f.Printf(" [Virtual]\n");
82 if(_class.properties.first)
85 f.Printf(" [Imported Properties]\n");
86 for(prop = _class.properties.first; prop; prop = prop.next)
88 f.Printf(" %s\n", prop.name);
90 f.Printf(" [Virtual]\n");
101 if(module.functions.first)
103 f.Printf(" [Imported Functions]\n");
104 for(function = module.functions.first; function; function = function.next)
106 f.Printf(" %s\n", function.name);
117 class CompilerApp : Application
121 char * cppCommand = null;
122 char * cppOptions = null;
123 int cppOptionsLen = 0;
124 /*char ** argv = null;
128 char defaultOutputFile[MAX_LOCATION];
130 Platform targetPlatform = GetRuntimePlatform();
131 int targetBits = GetHostBits();
135 /*for(c = 0; c<this.argc; c++)
137 char * arg = this.argv[c];
138 int argLen = strlen(arg);
140 argv = renew argv char *[argc + 1];
141 argv[argc] = new char[argLen+1];
142 strcpy(argv[argc], arg);
144 while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
151 argv[argc] = renew argv[argc] char[argLen + len + 1];
153 argv[argc][argLen-1] = ' ';
154 strcpy(argv[argc] + argLen, arg);
160 for(c = 1; c<argc; c++)
162 char * arg = argv[c];
165 if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
167 #if defined(__WIN32__)
168 if(strcmp(arg + 1, "m64")) // Until we set up MinGW-w64
171 int argLen = strlen(arg);
172 int newLen = cppOptionsLen + 1 + argLen;
173 cppOptions = renew cppOptions char[newLen + 1];
174 cppOptions[cppOptionsLen] = ' ';
175 strcpy(cppOptions + cppOptionsLen + 1, arg);
176 cppOptionsLen = newLen;
178 targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
180 else if(arg[1] == 'D')
182 int argLen = strlen(arg);
183 int newLen = cppOptionsLen + 1 + argLen;
184 cppOptions = renew cppOptions char[newLen + 1];
185 cppOptions[cppOptionsLen] = ' ';
186 strcpy(cppOptions + cppOptionsLen + 1, arg);
187 cppOptionsLen = newLen;
188 if(!strcmp(arg, "-DBUILDING_ECERE_COM"))
189 SetBuildingEcereCom(true);
190 else if(!strcmp(arg, "-DECERE_COM_MODULE"))
191 SetBuildingEcereComModule(true);
193 else if(arg[1] == 'I')
195 int argLen = strlen(arg);
196 int newLen = cppOptionsLen + argLen + 3;
197 cppOptions = renew cppOptions char[newLen + 1];
198 cppOptions[cppOptionsLen] = ' ';
199 cppOptions[cppOptionsLen+1] = '-';
200 cppOptions[cppOptionsLen+2] = 'I';
201 cppOptions[cppOptionsLen+3] = '"';
202 strcpy(cppOptions + cppOptionsLen + 4, arg+2);
203 cppOptions[newLen-1] = '\"';
204 cppOptions[newLen] = '\0';
205 cppOptionsLen = newLen;
207 else if(!strcmp(arg+1, "t"))
210 targetPlatform = argv[c];
214 else if(!strcmp(arg+1, "cpp"))
217 cppCommand = CopyString(argv[c]);
221 else if(!strcmp(arg+1, "o"))
223 if(!GetOutputFile() && c + 1 < argc)
225 SetOutputFile(argv[c+1]);
231 else if(!strcmp(arg+1, "c"))
233 if(!GetSourceFile() && c + 1 < argc)
235 SetSourceFile(argv[c+1]);
241 else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot"))
245 int argLen = strlen(arg);
246 int arg1Len = strlen(argv[c+1]);
247 int newLen = cppOptionsLen + argLen + arg1Len + 4;
248 cppOptions = renew cppOptions char[newLen + 1];
249 cppOptions[cppOptionsLen] = ' ';
250 strcpy(cppOptions + cppOptionsLen + 1, arg);
251 cppOptions[cppOptionsLen+argLen+1] = ' ';
252 cppOptions[cppOptionsLen+argLen+2] = '"';
254 strcpy(cppOptions + cppOptionsLen + argLen + 3, arg);
255 cppOptions[newLen-1] = '\"';
256 cppOptions[newLen] = '\0';
257 cppOptionsLen = newLen;
262 else if(!strcmp(arg+1, "symbols"))
266 SetSymbolsDir(argv[c+1]);
272 else if(!strcmp(arg+1, "memguard"))
274 SetMemoryGuard(true);
276 else if(!strcmp(arg+1, "defaultns"))
280 SetDefaultNameSpace(argv[c+1]);
281 //defaultNameSpaceLen = strlen(defaultNameSpace);
287 else if(!strcmp(arg+1, "strictns"))
289 SetStrictNameSpaces(true);
291 else if(!strcmp(arg+1, "nolinenumbers"))
293 SetOutputLineNumbers(false);
302 cppCommand = CopyString("gcc");
305 else if(!GetOutputFile())
307 strcpy(defaultOutputFile, "");
308 PathCat(defaultOutputFile, GetSourceFile());
309 ChangeExtension(defaultOutputFile, "c", defaultOutputFile);
310 SetOutputFile(defaultOutputFile);
315 printf($"Syntax:\n ecc [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
319 // TODO: Improve this
320 char command[MAX_F_STRING*3];
321 SetGlobalData(&globalData);
322 SetExcludedSymbols(&_excludedSymbols);
323 SetGlobalContext(globalContext);
324 SetCurrentContext(globalContext);
325 SetTopContext(globalContext);
326 SetDefines(&::defines);
327 SetImports(&imports);
329 SetTargetPlatform(targetPlatform);
330 SetTargetBits(targetBits);
333 privateModule = (Module)__ecere_COM_Initialize(true | ((targetBits == 64)?2:0), 1, null);
334 SetPrivateModule(privateModule);
336 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
337 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
338 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
339 globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
340 globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
343 GlobalData data { fullName = CopyString("__thisModule"), dataTypeString = CopyString("Module"), module = privateModule };
344 data.key = (uintptr)data.fullName;
345 globalData.functions.Add((BTNode)data);
348 snprintf(command, sizeof(command), "%s%s -x c -E \"%s\"", cppCommand, cppOptions ? cppOptions : "", GetSourceFile());
349 command[sizeof(command)-1] = 0;
350 if((cppOutput = DualPipeOpen({ output = true }, command)))
352 char impFile[MAX_LOCATION];
353 ImportedModule module;
354 char mainModuleName[MAX_FILENAME];
358 TempFile fileInput { };
359 SetFileInput(fileInput);
361 imports.Add((mainModule = ModuleImport { }));
362 SetMainModule(mainModule);
364 GetLastDirectory(GetSourceFile(), mainModuleName);
367 // TEMP: UNTIL WE CAN HAVE PER SOURCE FILE PREPROCESSOR DEFINITIONS...
368 if(GetBuildingEcereCom() &&
369 !(strcmpi(mainModuleName, "instance.ec") && strcmpi(mainModuleName, "BinaryTree.ec") &&
370 strcmpi(mainModuleName, "dataTypes.ec") && strcmpi(mainModuleName, "OldList.ec") &&
371 strcmpi(mainModuleName, "String.ec") && strcmpi(mainModuleName, "BTNode.ec") &&
372 strcmpi(mainModuleName, "Array.ec") && strcmpi(mainModuleName, "AVLTree.ec") &&
373 strcmpi(mainModuleName, "BuiltInContainer.ec") && strcmpi(mainModuleName, "Container.ec") &&
374 strcmpi(mainModuleName, "CustomAVLTree.ec") && strcmpi(mainModuleName, "LinkList.ec") &&
375 strcmpi(mainModuleName, "List.ec") && strcmpi(mainModuleName, "Map.ec") &&
376 strcmpi(mainModuleName, "Mutex.ec")))
377 SetBuildingEcereComModule(true);
378 if(GetBuildingEcereCom() &&
379 !(strcmpi(mainModuleName, "instance.ec") && strcmpi(mainModuleName, "BinaryTree.ec") &&
380 /*strcmpi(mainModuleName, "dataTypes.ec") && strcmpi(mainModuleName, "OldList.ec") &&*/
381 /*strcmpi(mainModuleName, "String.ec") && */strcmpi(mainModuleName, "BTNode.ec") &&
382 strcmpi(mainModuleName, "Mutex.ec") && strcmpi(mainModuleName, "Thread.ec")))
383 //if(GetBuildingEcereCom() && !strcmpi(mainModuleName, "instance.ec"))
384 SetMemoryGuard(false);
387 StripExtension(mainModuleName);
388 module = ImportedModule { name = CopyString(mainModuleName), type = moduleDefinition };
389 ::defines.AddName(module);
392 while(!cppOutput.Eof())
395 int count = cppOutput.Read(junk, 1, 4096);
396 fileInput.Write(junk, 1, count);
398 exitCode = cppOutput.GetExitCode();
401 fileInput.Seek(0, start);
407 // Predeclare all classes
409 char symFile[MAX_FILENAME];
410 char symLocation[MAX_LOCATION];
411 ImportedModule module, next;
413 GetLastDirectory(GetSourceFile(), symFile);
414 ChangeExtension(symFile, "sym", symFile);
416 strcpy(symLocation, GetSymbolsDir());
417 PathCat(symLocation, symFile);
419 // LoadSymbols(symLocation, normalImport, true);
420 LoadSymbols(symLocation, preDeclImport, false);
422 for(module = ::defines.first; module; module = next)
425 if(module.type == moduleDefinition && strcmpi(module.name, mainModuleName))
428 ::defines.Delete(module);
432 if(!GetEcereImported() && !GetBuildingEcereCom())
433 eModule_LoadStrict(privateModule, "ecereCOM", publicAccess /*privateAccess*/);
438 CheckDataRedefinitions();
441 SetCurrentNameSpace(null);
442 SetDefaultNameSpace(null);
443 SetDeclMode(privateAccess);
450 if(/*ast /*&& !parseError*/ /*&& */!exitCode)
452 ProcessDBTableDefinitions();
454 // *** PASS 0 - Register all classes, methods, properties and members ***
455 // *** Build the constructors, destructors, properties as ***
456 // *** class functions ***
457 PrePreProcessClassDefinitions();
458 ComputeModuleClasses(privateModule);
459 PreProcessClassDefinitions();
461 // For classes defined in this module...
462 ComputeModuleClasses(privateModule);
465 // *** PASS 1 - Turn the class functions into functions ***
466 // *** Write the RegisterModule (Register classes) ***
467 ProcessClassDefinitions();
469 // *** PASS 1.5 - Replace members by this.member, figure out types, do type checking / conversions
472 // *** PASS 1.6 - Replace instantiations
473 ProcessInstantiations();
475 // *** PASS 2 - Replace Member Access ***
476 ProcessMemberAccess();
478 // *** PASS 3 - Replace pointers to objects by "Instance *" ***
479 ProcessInstanceDeclarations();
481 strcpy(impFile, GetSymbolsDir());
483 char fileName[MAX_FILENAME];
484 GetLastDirectory(GetSourceFile(), fileName);
485 PathCat(impFile, fileName);
486 ChangeExtension(impFile, "imp", impFile);
489 OutputImports(impFile);
490 // For now use precomp to generate sym file only...
492 if(/*!strcmp(targetExt, "c") && */!this.exitCode)
494 File output = FileOpen(GetOutputFile(), write);
497 //output.Printf("#include <ecereCOM.h>\n\n");
499 // Temporary patch, fix with defines or something...
501 if(!strstr(GetSourceFile(), "instance.ec"))
503 output.Printf("#if defined(__GNUC__) && defined(__WIN32__)\n");
504 output.Printf("#include <x87inline.h>\n");
505 output.Printf("#endif\n");
508 /*output.Printf("#if defined(__GNUC__) \n");
509 output.Printf("typedef long long int64;\n");
510 output.Printf("typedef unsigned long long uint64;\n");
511 output.Printf("#else\n");
512 output.Printf("typedef __int64 int64;\n");
513 output.Printf("typedef unsigned __int64 uint64;\n");
514 output.Printf("#endif\n");*/
515 output.Printf("#if defined(__GNUC__)\n");
516 output.Printf("typedef long long int64;\n");
517 output.Printf("typedef unsigned long long uint64;\n");
518 output.Printf("#elif defined(__TINYC__)\n");
519 output.Printf("#include <stdarg.h>\n");
520 output.Printf("#define __builtin_va_list va_list\n");
521 output.Printf("#define __builtin_va_start va_start\n");
522 output.Printf("#define __builtin_va_end va_end\n");
523 output.Printf("#ifdef _WIN32\n");
524 output.Printf("#define strcasecmp stricmp\n");
525 output.Printf("#define strncasecmp strnicmp\n");
526 output.Printf("#define __declspec(x) __attribute__((x))\n");
527 output.Printf("#else\n");
528 output.Printf("#define __declspec(x)\n");
529 output.Printf("#endif\n");
530 output.Printf("typedef long long int64;\n");
531 output.Printf("typedef unsigned long long uint64;\n");
532 output.Printf("#else\n");
533 output.Printf("typedef __int64 int64;\n");
534 output.Printf("typedef unsigned __int64 uint64;\n");
535 output.Printf("#endif\n");
536 /*output.Printf("#if defined(__GNUC__) || defined(__TINYC__)\n");
537 output.Printf("typedef long long int64;\n");
538 output.Printf("typedef unsigned long long uint64;\n");
539 output.Printf("#elif defined(__TINYC__)\n");
540 output.Printf("#else\n");
541 output.Printf("typedef __int64 int64;\n");
542 output.Printf("typedef unsigned __int64 uint64;\n");
543 output.Printf("#endif\n");*/
544 output.Printf("#ifdef __BIG_ENDIAN__\n");
545 output.Printf("#define __ENDIAN_PAD(x) (8 - (x))\n");
546 output.Printf("#else\n");
547 output.Printf("#define __ENDIAN_PAD(x) 0\n");
548 output.Printf("#endif\n");
549 output.Printf("#include <stdint.h>\n");
551 // NOTE: If anything is changed up there, the start outputLine must be updated in libec's output.c or Debugging lines will be wrong
554 OutputTree(ast, output);
559 else if(!strcmp(targetExt, "o"))
561 // Compile right away
562 File output = FileOpen(GetOutputFile(), Write);
563 output.Printf("#include <ecereCOM.h>\n\n");
564 OutputTree(ast, output);
569 this.exitCode = exitCode;
577 FreeContext(globalContext);
578 FreeExcludedSymbols(_excludedSymbols);
580 ::defines.Free(FreeModuleDefine);
581 imports.Free(FreeModuleImport);
583 FreeTypeData(privateModule);
585 FreeGlobalData(globalData);
587 delete privateModule;
593 /*for(c = 0; c<argc; c++)
597 SetSymbolsDir(null); // Free symbols dir
601 #if defined(_DEBUG) && defined(__WIN32__)
602 if(exitCode || GetNumWarnings())