compiler/libec Improvements to conversion from AST->Type class, and to outputting...
[sdk] / compiler / ecc / ecc.ec
1 #ifdef ECERE_STATIC
2 import static "ecere"
3 import static "ec"
4 #else
5 import "ecere"
6 import "ec"
7 #endif
8
9
10 //#include <stdarg.h>
11
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
18 {
19    classes.CompareKey = (void *)BinaryTree::CompareString;
20    defines.CompareKey = (void *)BinaryTree::CompareString;
21    functions.CompareKey = (void *)BinaryTree::CompareString;
22    nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
23 };
24 static OldList _precompDefines;
25
26 static void OutputImports(char * fileName)
27 {
28    File f = FileOpen(fileName, write);
29    if(f)
30    {
31       if(imports.first)
32       {
33          ModuleImport module;
34          f.Printf("[Imported Modules]\n");
35          for(module = imports.first; module; module = module.next)
36          {
37             ClassImport _class;
38             FunctionImport function;
39
40             if(module.name)
41                f.Printf("   %s\n", module.name);
42             else
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");
48
49             if(module.importAccess == privateAccess)
50                f.Printf("      [Private]\n");
51             else
52                f.Printf("      [Public]\n");
53
54             if(module.classes.first)
55             {
56                f.Printf("      [Imported Classes]\n");
57                for(_class = module.classes.first; _class; _class = _class.next)
58                {
59                   f.Printf("         %s\n", _class.name);
60                   if(_class.itself)
61                   {
62                      f.Printf("            [Instantiated]\n");
63                   }
64                   if(_class.isRemote)
65                   {
66                      f.Printf("            [Remote]\n");
67                   }
68
69                   if(_class.methods.first)
70                   {
71                      MethodImport method;
72                      f.Printf("            [Imported Methods]\n");
73                      for(method = _class.methods.first; method; method = method.next)
74                      {
75                         f.Printf("               %s\n", method.name);
76                         if(method.isVirtual)
77                            f.Printf("                  [Virtual]\n");
78
79                      }
80                      f.Printf("               .\n");
81                   }
82
83                   if(_class.properties.first)
84                   {
85                      PropertyImport prop;
86                      f.Printf("            [Imported Properties]\n");
87                      for(prop = _class.properties.first; prop; prop = prop.next)
88                      {
89                         f.Printf("               %s\n", prop.name);
90                         if(prop.isVirtual)
91                            f.Printf("                  [Virtual]\n");
92                         if(prop.hasSet)
93                            f.Printf("                  [Set]\n");
94                         if(prop.hasGet)
95                            f.Printf("                  [Get]\n");
96                      }
97                      f.Printf("               .\n");
98                   }
99                }
100                f.Printf("        .\n");
101             }
102             if(module.functions.first)
103             {
104                f.Printf("      [Imported Functions]\n");
105                for(function = module.functions.first; function; function = function.next)
106                {
107                   f.Printf("         %s\n", function.name);
108                }
109                f.Printf("        .\n");
110             }
111          }
112          f.Printf("   .\n");
113       }
114    }
115    delete f;
116 }
117
118 bool TestType(String string, String expected)
119 {
120    bool result = true;
121    char typeString[1024] = { 0 };
122    Type type = ProcessTypeString(string, false);
123    PrintType(type, typeString, true, true);
124    if(strcmp(typeString, expected ? expected : string))
125    {
126       PrintLn("FAILED: ", string, " -> ", typeString);
127       result = false;
128    }
129    return result;
130 }
131
132 void TestTypes()
133 {
134    int succeeded = 0, count = 0;
135    
136    //count++, succeeded += TestType("int (* f[8])[10]", null);
137    count++, succeeded += TestType("void (* signal(int, void (*)(int)))(int)", null);
138    count++, succeeded += TestType("void (* signal(double))()", null);
139    count++, succeeded += TestType("void (* bla)(int)", null);
140    count++, succeeded += TestType("int f(void (*[10])())", null);
141    count++, succeeded += TestType("void (*[10])()", null);
142    count++, succeeded += TestType("void (* converters_table[10])()", null);
143    count++, succeeded += TestType("int (* f[8])[10]", null);
144    
145    count++, succeeded += TestType("int f[8][10]", null);
146    count++, succeeded += TestType("int f[10]", null);
147    count++, succeeded += TestType("void *", null);
148    count++, succeeded += TestType("char * x", "char * x");
149    count++, succeeded += TestType("char * x", null);
150    count++, succeeded += TestType("char (* x[3])()", null);
151    count++, succeeded += TestType("char (*(* x[3])())", "char * (* x[3])()");
152    count++, succeeded += TestType("char (* x())", "char * x()");
153    count++, succeeded += TestType("char (* (* x[3])())[5]", null);
154    count++, succeeded += TestType("char (* f())[5]", null);
155    count++, succeeded += TestType("char * (* f())[5]", null);
156    count++, succeeded += TestType("char * (* * f())[5][2][3]", null);
157    count++, succeeded += TestType("char * (* * (* f)())[5][2][3]", null);
158    count++, succeeded += TestType("char * (* (* * (* f)())[5][2])[3]", null);
159    count++, succeeded += TestType("void (* (* bar)[5])()", null);
160    count++, succeeded += TestType("const int * (* const f)(char[10])", null);
161    count++, succeeded += TestType("const int", null);
162    count++, succeeded += TestType("int * const *", null);
163    count++, succeeded += TestType("int * const", null);
164    count++, succeeded += TestType("const int *", null);
165    
166    count++, succeeded += TestType("char * const (* (* const bar)[5])(int)", null);
167    count++, succeeded += TestType("char * const (* (* (* const bar)[5][6])(int))[2]", null);
168    count++, succeeded += TestType("int * * a", null);
169
170    count++, succeeded += TestType("char * const (* bar)()", null);
171
172    count++, succeeded += TestType("char * const (* const (* const bar)[5])(int)", null);
173    
174    count++, succeeded += TestType("char * (* const (* bar)[5])(int)", null);
175    count++, succeeded += TestType("void (* * const bar[5])()", null);
176    count++, succeeded += TestType("void (* * const bar)()", null);
177    count++, succeeded += TestType("void (* const * bar)()", null);
178    count++, succeeded += TestType("const int * * foo", null); // this prevents you from doing: **foo = 0;
179    count++, succeeded += TestType("int * const * bar", null); // this prevents you from doing: *bar = 0;
180    count++, succeeded += TestType("int * * const two", null); // this prevents you from doing: two = 0;
181
182    count++, succeeded += TestType("dllexport int TestFunction()", null); // this prevents you from doing: two = 0;
183    count++, succeeded += TestType("any_object TestFunction(any_object, typed_object & param)", null); // this prevents you from doing: two = 0;
184
185    count++, succeeded += TestType("void typed_object::OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)", null);
186    count++, succeeded += TestType("int typed_object::OnCompare(any_object object)", null);
187    count++, succeeded += TestType("void typed_object&::OnCopy(any_object newData)", null);
188    count++, succeeded += TestType("void typed_object::OnFree(void)", null);
189    count++, succeeded += TestType("char * typed_object::OnGetString(char * tempString, void * fieldData, bool * needClass)", null);
190    count++, succeeded += TestType("bool typed_object&::OnGetDataFromString(char * string)", null);
191    count++, succeeded += TestType("Window typed_object::OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)", null);
192    count++, succeeded += TestType("void typed_object::OnSerialize(IOChannel channel)", null);
193    count++, succeeded += TestType("void typed_object&::OnUnserialize(IOChannel channel)", null);
194    count++, succeeded += TestType("bool typed_object&::OnSaveEdit(Window window, void * object)", null);
195
196    count++, succeeded += TestType("void PrintLn(typed_object object, ...)", null);
197    count++, succeeded += TestType("void PrintLn(typed_object object, ...)", null);
198    count++, succeeded += TestType("thisclass RemoveSwapRight()", null);
199    count++, succeeded += TestType("LinkElement<thisclass> link", null);
200    count++, succeeded += TestType("struct { thisclass prev; thisclass next; }", null);
201
202    PrintLn("\n", succeeded, " / ", count, " tests succeeded.");
203 }
204
205 class CompilerApp : Application
206 {
207    void Main()
208    {
209       char * cppCommand = null;
210       char * cppOptions = null;
211       int cppOptionsLen = 0;
212       /*char ** argv = null;
213       int argc = 0;*/
214       int c;
215       bool valid = true;
216       char defaultOutputFile[MAX_LOCATION];
217       bool buildingBootStrap = false;
218
219       Platform targetPlatform = GetRuntimePlatform();
220       int targetBits = GetHostBits();
221
222       SetSymbolsDir("");
223
224       /*for(c = 0; c<this.argc; c++)
225       {
226          char * arg = this.argv[c];
227          int argLen = strlen(arg);
228
229          argv = renew argv char *[argc + 1];
230          argv[argc] = new char[argLen+1];
231          strcpy(argv[argc], arg);
232
233          while(argv[argc][argLen-1] == '\\' && c < this.argc-1)
234          {
235             int len;
236
237             c++;
238             arg = this.argv[c];
239             len = strlen(arg);
240             argv[argc] = renew argv[argc] char[argLen + len + 1];
241
242             argv[argc][argLen-1] = ' ';
243             strcpy(argv[argc] + argLen, arg);
244             argLen += len;
245          }
246          argc++;
247       }*/
248
249       for(c = 1; c<argc; c++)
250       {
251          char * arg = argv[c];
252          if(arg[0] == '-')
253          {
254             if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
255             {
256                int argLen = strlen(arg);
257                int newLen = cppOptionsLen + 1 + argLen;
258                cppOptions = renew cppOptions char[newLen + 1];
259                cppOptions[cppOptionsLen] = ' ';
260                strcpy(cppOptions + cppOptionsLen + 1, arg);
261                cppOptionsLen = newLen;
262                targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
263             }
264             else if(arg[1] == 'D')
265             {
266                int argLen = strlen(arg);
267                int newLen = cppOptionsLen + 1 + argLen;
268                cppOptions = renew cppOptions char[newLen + 1];
269                cppOptions[cppOptionsLen] = ' ';
270                strcpy(cppOptions + cppOptionsLen + 1, arg); 
271                cppOptionsLen = newLen;
272                if(!strcmp(arg, "-DBUILDING_ECERE_COM"))
273                   SetBuildingEcereCom(true);
274                else if(!strcmp(arg, "-DECERE_COM_MODULE"))
275                   SetBuildingEcereComModule(true);
276                else if(!strcmp(arg, "-DECERE_BOOTSTRAP"))
277                   buildingBootStrap = true;
278             }
279             else if(arg[1] == 'I')
280             {
281                int argLen = strlen(arg);
282                int newLen = cppOptionsLen + argLen + 3;
283                cppOptions = renew cppOptions char[newLen + 1];
284                cppOptions[cppOptionsLen] = ' ';
285                cppOptions[cppOptionsLen+1] = '-';
286                cppOptions[cppOptionsLen+2] = 'I';
287                cppOptions[cppOptionsLen+3] = '"';
288                strcpy(cppOptions + cppOptionsLen + 4, arg+2); 
289                cppOptions[newLen-1] = '\"';
290                cppOptions[newLen] = '\0';
291                cppOptionsLen = newLen;
292             }
293             else if(!strcmp(arg+1, "t"))
294             {
295                if(++c < argc)
296                   targetPlatform = argv[c];
297                else
298                   valid = false;
299             }
300             else if(!strcmp(arg+1, "cpp"))
301             {
302                if(++c < argc)
303                   cppCommand = CopyString(argv[c]);
304                else
305                   valid = false;
306             }
307             else if(!strcmp(arg+1, "o"))
308             {
309                if(!GetOutputFile() && c + 1 < argc)
310                {
311                   SetOutputFile(argv[c+1]);
312                   c++;
313                }
314                else
315                   valid = false;
316             }
317             else if(!strcmp(arg+1, "c"))
318             {
319                if(!GetSourceFile() && c + 1 < argc)
320                {
321                   SetSourceFile(argv[c+1]);
322                   c++;
323                }
324                else
325                   valid = false;
326             }
327             else if(!strcmp(arg+1, "isystem") || !strcmp(arg+1, "isysroot"))
328             {
329                if(c + 1 < argc)
330                {
331                   int argLen = strlen(arg);
332                   int arg1Len = strlen(argv[c+1]);
333                   int newLen = cppOptionsLen + argLen + arg1Len + 4;
334                   cppOptions = renew cppOptions char[newLen + 1];
335                   cppOptions[cppOptionsLen] = ' ';
336                   strcpy(cppOptions + cppOptionsLen + 1, arg); 
337                   cppOptions[cppOptionsLen+argLen+1] = ' ';
338                   cppOptions[cppOptionsLen+argLen+2] = '"';
339                   arg = argv[++c];
340                   strcpy(cppOptions + cppOptionsLen + argLen + 3, arg); 
341                   cppOptions[newLen-1] = '\"';
342                   cppOptions[newLen] = '\0';
343                   cppOptionsLen = newLen;
344                }
345                else
346                   valid = false;
347             }
348             else if(!strcmp(arg+1, "symbols"))
349             {
350                if(c + 1 < argc)
351                {
352                   SetSymbolsDir(argv[c+1]);
353                   c++;
354                }
355                else
356                   valid = false;
357             }
358             else if(!strcmp(arg+1, "memguard"))
359             {
360                SetMemoryGuard(true);
361             }
362             else if(!strcmp(arg+1, "defaultns"))
363             {
364                if(c + 1 < argc)
365                {
366                   SetDefaultNameSpace(argv[c+1]);
367                   //defaultNameSpaceLen = strlen(defaultNameSpace);
368                   c++;
369                }
370                else
371                   valid = false;
372             }
373             else if(!strcmp(arg+1, "strictns"))
374             {
375                SetStrictNameSpaces(true);
376             }
377             else if(!strcmp(arg+1, "nolinenumbers"))
378             {
379                SetOutputLineNumbers(false);
380             }
381          }
382          else
383             valid = false;
384       }
385       if(valid)
386       {
387          if(!cppCommand)
388             cppCommand = CopyString("gcc");
389          if(!GetSourceFile())
390             valid = false;
391          else if(!GetOutputFile())
392          {
393             strcpy(defaultOutputFile, "");
394             PathCat(defaultOutputFile, GetSourceFile());
395             ChangeExtension(defaultOutputFile, "c", defaultOutputFile);
396             SetOutputFile(defaultOutputFile);
397          }
398       }
399
400       if(!valid)
401          printf($"Syntax:\n   ecc [-t <target platform>] [-cpp <c preprocessor>] [-o <output>] [-symbols <outputdir>] [-I<includedir>]* [-isystem <sysincludedir>]* [-D<definition>]* -c <input>\n");
402       else
403       {
404          DualPipe cppOutput;
405          // TODO: Improve this
406          char command[MAX_F_STRING*3];
407          SetGlobalData(&globalData);
408          SetExcludedSymbols(&_excludedSymbols);
409          SetGlobalContext(globalContext);
410          SetCurrentContext(globalContext);
411          SetTopContext(globalContext);
412          SetDefines(&::defines);
413          SetImports(&imports);
414          SetInCompiler(true);
415          SetTargetPlatform(targetPlatform);
416          SetTargetBits(targetBits);
417          SetEchoOn(false);
418
419 #ifdef _DEBUG
420          TestTypes();
421 #endif
422
423          privateModule = (Module)__ecere_COM_Initialize(true | (targetBits == sizeof(uintptr)*8 ? 0 : targetBits == 64 ? 2 : targetBits==32 ? 4 : 0) | 8, 1, null);
424          SetPrivateModule(privateModule);
425
426          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint"), type = ProcessTypeString("unsigned int", false) });
427          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint64"), type = ProcessTypeString("unsigned int64", false) });
428          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint32"), type = ProcessTypeString("unsigned int", false) });
429          globalContext.types.Add((BTNode)Symbol { string = CopyString("uint16"), type = ProcessTypeString("unsigned short", false) });
430          globalContext.types.Add((BTNode)Symbol { string = CopyString("byte"), type = ProcessTypeString("unsigned char", false) });
431          if(buildingBootStrap)
432          {
433             // 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)
434             globalContext.types.Add((BTNode)Symbol { string = CopyString("intptr_t"), type = ProcessTypeString("intptr", false) });
435             globalContext.types.Add((BTNode)Symbol { string = CopyString("uintptr_t"), type = ProcessTypeString("uintptr", false) });
436             globalContext.types.Add((BTNode)Symbol { string = CopyString("ssize_t"), type = ProcessTypeString("intsize", false) });
437             globalContext.types.Add((BTNode)Symbol { string = CopyString("size_t"), type = ProcessTypeString("uintsize", false) });
438          }
439
440          {
441             GlobalData data { fullName = CopyString("__thisModule"), dataTypeString = CopyString("Module"), module = privateModule };
442             data.key = (uintptr)data.fullName;
443             globalData.functions.Add((BTNode)data);
444          }
445
446          snprintf(command, sizeof(command), "%s%s -x c -E %s\"%s\"", cppCommand, cppOptions ? cppOptions : "", buildingBootStrap ? "" : "-include stdint.h -include sys/types.h ", GetSourceFile());
447          command[sizeof(command)-1] = 0;
448          if((cppOutput = DualPipeOpen({ output = true }, command)))
449          {
450             char impFile[MAX_LOCATION];
451             ImportedModule module;
452             char mainModuleName[MAX_FILENAME];
453             int exitCode;
454             OldList * ast;
455
456             TempFile fileInput { };
457             SetFileInput(fileInput);
458
459             imports.Add((mainModule = ModuleImport { }));
460             SetMainModule(mainModule);
461
462             GetLastDirectory(GetSourceFile(), mainModuleName);
463
464 #if 0
465             // TEMP: UNTIL WE CAN HAVE PER SOURCE FILE PREPROCESSOR DEFINITIONS...
466             if(GetBuildingEcereCom() && 
467                !(strcmpi(mainModuleName, "instance.ec") && strcmpi(mainModuleName, "BinaryTree.ec") &&
468                strcmpi(mainModuleName, "dataTypes.ec") && strcmpi(mainModuleName, "OldList.ec") &&
469                strcmpi(mainModuleName, "String.ec") && strcmpi(mainModuleName, "BTNode.ec") &&
470                strcmpi(mainModuleName, "Array.ec") && strcmpi(mainModuleName, "AVLTree.ec") &&
471                strcmpi(mainModuleName, "BuiltInContainer.ec") && strcmpi(mainModuleName, "Container.ec") &&
472                strcmpi(mainModuleName, "CustomAVLTree.ec") && strcmpi(mainModuleName, "LinkList.ec") &&
473                strcmpi(mainModuleName, "List.ec") && strcmpi(mainModuleName, "Map.ec") &&
474                strcmpi(mainModuleName, "Mutex.ec")))
475                SetBuildingEcereComModule(true);
476             if(GetBuildingEcereCom() && 
477                !(strcmpi(mainModuleName, "instance.ec") && strcmpi(mainModuleName, "BinaryTree.ec") &&
478                /*strcmpi(mainModuleName, "dataTypes.ec") && strcmpi(mainModuleName, "OldList.ec") &&*/
479                /*strcmpi(mainModuleName, "String.ec") && */strcmpi(mainModuleName, "BTNode.ec") &&
480                strcmpi(mainModuleName, "Mutex.ec") && strcmpi(mainModuleName, "Thread.ec")))
481             //if(GetBuildingEcereCom() && !strcmpi(mainModuleName, "instance.ec"))
482                SetMemoryGuard(false);
483 #endif            
484
485             StripExtension(mainModuleName);
486             module = ImportedModule { name = CopyString(mainModuleName), type = moduleDefinition };
487             ::defines.AddName(module);
488
489             resetScanner();
490             while(!cppOutput.Eof())
491             {
492                char junk[4096];
493                int count = cppOutput.Read(junk, 1, 4096);
494                fileInput.Write(junk, 1, count);
495             }
496             exitCode = cppOutput.GetExitCode();
497             delete cppOutput;
498
499             fileInput.Seek(0, start);
500
501    #ifdef _DEBUG
502             // SetYydebug(true);
503    #endif
504
505             // Predeclare all classes
506             {
507                char symFile[MAX_FILENAME];
508                char symLocation[MAX_LOCATION];
509                ImportedModule module, next;
510
511                GetLastDirectory(GetSourceFile(), symFile);
512                ChangeExtension(symFile, "sym", symFile);
513
514                strcpy(symLocation, GetSymbolsDir());
515                PathCat(symLocation, symFile);
516                
517                // LoadSymbols(symLocation, normalImport, true);
518                LoadSymbols(symLocation, preDeclImport, false);
519                
520                for(module = ::defines.first; module; module = next)
521                {
522                   next = module.next;
523                   if(module.type == moduleDefinition && strcmpi(module.name, mainModuleName))
524                   {
525                      delete module.name;
526                      ::defines.Delete(module);
527                   }
528                }
529
530                if(!GetEcereImported() && !GetBuildingEcereCom())
531                   eModule_LoadStrict(privateModule, "ecereCOM", publicAccess /*privateAccess*/);
532             }
533
534             ParseEc();
535
536             CheckDataRedefinitions();
537
538             SetYydebug(false);
539             SetCurrentNameSpace(null);
540             SetDefaultNameSpace(null);
541             SetDeclMode(privateAccess);
542
543             delete fileInput;
544             SetFileInput(null);
545
546             ast = GetAST();
547
548             if(/*ast /*&& !parseError*/ /*&& */!exitCode)
549             {
550                ProcessDBTableDefinitions();
551
552                // *** PASS 0 - Register all classes, methods, properties and members ***
553                // ***          Build the constructors, destructors, properties as    ***
554                // ***          class functions                                       ***
555                PrePreProcessClassDefinitions();
556                ComputeModuleClasses(privateModule);
557                PreProcessClassDefinitions();
558
559                // For classes defined in this module...
560                ComputeModuleClasses(privateModule);
561
562                
563                // *** PASS 1 - Turn the class functions into functions               ***
564                // *** Write the RegisterModule (Register classes)                    ***
565                ProcessClassDefinitions();
566
567                // *** PASS 1.5 - Replace members by this.member, figure out types, do type checking / conversions
568                ComputeDataTypes();
569
570                // *** PASS 1.6 - Replace instantiations
571                ProcessInstantiations();
572
573                // *** PASS 2 - Replace Member Access ***
574                ProcessMemberAccess();
575
576                // *** PASS 3 - Replace pointers to objects by "Instance *" ***
577                ProcessInstanceDeclarations();
578
579                strcpy(impFile, GetSymbolsDir());
580                {
581                   char fileName[MAX_FILENAME];
582                   GetLastDirectory(GetSourceFile(), fileName);
583                   PathCat(impFile, fileName);
584                   ChangeExtension(impFile, "imp", impFile);
585                }
586                if(imports.first)
587                   OutputImports(impFile);
588                // For now use precomp to generate sym file only...
589
590                if(/*!strcmp(targetExt, "c") && */!this.exitCode)
591                {
592                   File output = FileOpen(GetOutputFile(), write);
593                   if(output)
594                   {
595                      output.Printf("#if defined(__GNUC__)\n");
596                         output.Printf("typedef long long int64;\n");
597                         output.Printf("typedef unsigned long long uint64;\n");
598                         output.Printf("#ifndef _WIN32\n");
599                            output.Printf("#define __declspec(x)\n");
600                         output.Printf("#endif\n");
601                      output.Printf("#elif defined(__TINYC__)\n");
602                         output.Printf("#include <stdarg.h>\n");
603                         output.Printf("#define __builtin_va_list va_list\n");
604                         output.Printf("#define __builtin_va_start va_start\n");
605                         output.Printf("#define __builtin_va_end va_end\n");
606                         output.Printf("#ifdef _WIN32\n");
607                            output.Printf("#define strcasecmp stricmp\n");
608                            output.Printf("#define strncasecmp strnicmp\n");
609                            output.Printf("#define __declspec(x) __attribute__((x))\n");
610                         output.Printf("#else\n");
611                            output.Printf("#define __declspec(x)\n");
612                         output.Printf("#endif\n");
613                         output.Printf("typedef long long int64;\n");
614                         output.Printf("typedef unsigned long long uint64;\n");
615                      output.Printf("#else\n");
616                         output.Printf("typedef __int64 int64;\n");
617                         output.Printf("typedef unsigned __int64 uint64;\n");
618                      output.Printf("#endif\n");
619                      output.Printf("#ifdef __BIG_ENDIAN__\n");
620                         output.Printf("#define __ENDIAN_PAD(x) (8 - (x))\n");
621                      output.Printf("#else\n");
622                         output.Printf("#define __ENDIAN_PAD(x) 0\n");
623                      output.Printf("#endif\n");
624                      if(buildingBootStrap)
625                      {
626                         //output.Printf("#ifdef __MINGW32__\n");
627                         //output.Printf("#ifdef _WIN64\n");
628                         /*
629                         output.Printf("#if defined(_WIN64) || WORDSIZE == 64\n");
630                         output.Printf("typedef unsigned long long int uintptr_t;\n");
631                         output.Printf("typedef long long int intptr_t;\n");
632                         output.Printf("#else\n");
633                         output.Printf("typedef unsigned int uintptr_t;\n");
634                         output.Printf("typedef int intptr_t;\n");
635                         output.Printf("#endif\n");
636                         */
637                         //output.Printf("#else\n");
638                         output.Printf("#include <stdint.h>\n");
639                         output.Printf("#include <sys/types.h>\n");
640                         //output.Printf("#endif\n");
641                      }
642
643                      // NOTE: If anything is changed up there, the start outputLine must be updated in libec's output.c or Debugging lines will be wrong
644
645                      if(ast)
646                         OutputTree(ast, output);
647                      delete output;
648                   }
649                }
650                /*
651                else if(!strcmp(targetExt, "o"))
652                {
653                   // Compile right away
654                   File output = FileOpen(GetOutputFile(), Write);
655                   output.Printf("#include <ecereCOM.h>\n\n");
656                   OutputTree(ast, output);
657                   delete output;
658                }*/
659             }
660             else
661                this.exitCode = exitCode;
662
663             if(ast)
664             {
665                FreeASTTree(ast);
666             }
667          }
668
669          FreeContext(globalContext);
670          FreeExcludedSymbols(_excludedSymbols);
671
672          ::defines.Free(FreeModuleDefine);
673          imports.Free(FreeModuleImport);
674
675          FreeTypeData(privateModule);
676          FreeIncludeFiles();
677          FreeGlobalData(globalData);
678
679          delete privateModule;
680       }
681
682       delete cppCommand;
683       delete cppOptions;
684
685       /*for(c = 0; c<argc; c++)
686          delete argv[c];
687       delete argv;
688       */
689       SetSymbolsDir(null); // Free symbols dir
690
691       OutputIntlStrings();
692
693 #if defined(_DEBUG) && defined(__WIN32__)
694       if(exitCode || GetNumWarnings())
695          getch();
696 #endif
697    }
698 }