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