27abca2986981cec3b849a97c695587757e322bf
[sdk] / compiler / libec / src / ecdefs.ec
1 #ifdef ECERE_STATIC
2 public import static "ecere"
3 #else
4 public import "ecere"
5 #endif
6
7 import "ast"
8 import "freeAst"
9 import "firstPass"
10 import "pass0"
11 import "pass1"
12 import "pass15"
13 import "pass16"
14 import "pass2"
15 import "pass3"
16 import "loadSymbols"
17 import "copy"
18 import "shortcuts"
19 import "output"
20 import "dbpass"
21
22 #include <stdio.h>
23
24 enum Order { ascending, descending };
25
26 public class DBTableDef : struct
27 {
28 public:
29    char * name;
30    Symbol symbol;
31    OldList * definitions;
32    AccessMode declMode;
33 }
34
35 enum DBTableEntryType { fieldEntry, indexEntry };
36
37 class DBTableEntry : struct
38 {
39    DBTableEntry prev, next;
40    DBTableEntryType type;
41    Identifier id;
42    union
43    {
44       struct
45       {
46          TypeName dataType;
47          char * name;
48       };
49       OldList * items;
50    };
51 };
52
53 class DBIndexItem : struct
54 {
55    DBIndexItem prev, next;
56    Identifier id;
57    Order order;
58 };
59
60 bool inCompiler = false;
61 public void SetInCompiler(bool b) { inCompiler = b; }
62
63 Context curContext;
64 Context globalContext;
65 OldList * excludedSymbols;
66
67 Context topContext;
68 OldList * imports;
69 OldList * defines;
70 Module privateModule;
71 public void SetPrivateModule(Module module) { privateModule = module; }public Module GetPrivateModule() { return privateModule; }
72 ModuleImport mainModule;
73 public void SetMainModule(ModuleImport moduleImport) { mainModule = moduleImport; } public ModuleImport GetMainModule() { return mainModule; }
74 File fileInput;
75 public void SetFileInput(File file) { fileInput = file; }
76 char * symbolsDir = null;
77 public void SetSymbolsDir(char * s) {
78    delete symbolsDir;
79    symbolsDir = CopyString(s);
80 } public char * GetSymbolsDir() { return symbolsDir ? symbolsDir : ""; }
81 char * outputFile;
82 public void SetOutputFile(char * s) { outputFile = s; } public char * GetOutputFile() { return outputFile; }
83 char * sourceFile;
84 public void SetSourceFile(char * s) { sourceFile = s; } public char * GetSourceFile() { return sourceFile; }
85
86 public void SetGlobalContext(Context context) { globalContext = context; } public Context GetGlobalContext() { return globalContext; }
87 public void SetTopContext(Context context) { topContext = context; } public Context GetTopContext() { return topContext; }
88 public void SetCurrentContext(Context context) { curContext = context; } public Context GetCurrentContext() { return curContext; }
89 public void SetExcludedSymbols(OldList * list) { excludedSymbols = list; }
90 public void SetImports(OldList * list) { imports = list; }
91 public void SetDefines(OldList * list) { defines = list; }
92
93 bool outputLineNumbers = true;
94 public void SetOutputLineNumbers(bool value) { outputLineNumbers = value; }
95
96 public void FixModuleName(char *moduleName)
97 {
98    ChangeCh(moduleName, '.', '_');
99    ChangeCh(moduleName, ' ', '_');
100    ChangeCh(moduleName, '-', '_');
101    ChangeCh(moduleName, '&', '_');
102 }
103
104 // todo support %var% variables for windows and $var for linux?
105 public char * PassArg(char * output, const char * input)
106 {
107 #ifdef __WIN32__
108 //define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
109    const char * escChars = " !\"%&'()+,;=[]^`{}~"; // windowsFileNameCharsNeedEscaping;
110    const char * escCharsQuoted = "\"";
111 #else
112 //define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
113    const char * escChars = " !\"$&'()*:;<=>?[\\`{|"; // linuxFileNameCharsNeedEscaping;
114    const char * escCharsQuoted = "\"()$";
115 #endif
116    bool quoting = false;
117    char *o = output, *i = input, *l = input;
118 #ifdef __WIN32__
119    while(*l && !strchr(escChars, *l)) l++;
120    if(*l) quoting = true;
121 #else
122    if(*i == '-')
123    {
124       l++;
125       while(*l && !strchr(escChars, *l)) l++;
126       if(*l) quoting = true;
127       *o++ = *i++;
128    }
129 #endif
130    if(quoting)
131       *o++ = '\"';
132    while(*i)
133    {
134       if(strchr(quoting ? escCharsQuoted : escChars, *i))
135          *o++ = '\\';
136       *o++ = *i++;
137    }
138    if(quoting)
139       *o++ = '\"';
140    *o = '\0';
141    return o;
142 }
143 /*public Module GetPrivateModule()
144 {
145    return privateModule;
146 }*/
147
148 public class GlobalData : BTNode
149 {
150 public:
151    Module module;
152    char * dataTypeString;
153    Type dataType;
154    void * symbol;
155    char * fullName;
156 };
157
158 public class TemplatedType : BTNode
159 {
160 public:
161    TemplateParameter param;
162 };
163
164 class DataRedefinition : struct
165 {
166    DataRedefinition prev, next;
167    char name[1024];
168    char type1[1024], type2[1024];
169 };
170
171 public struct CodePosition
172 {
173 public:
174    int line, charPos, pos;
175    int included;
176
177    void AdjustDelete(BufferLocation start, BufferLocation end)
178    {
179       // Location is before, nothing to do
180       if(line - 1 < start.y || (line - 1 == start.y && charPos - 1 < start.x))
181          return;
182       // Location is inside deleted bytes, point to the start
183       if((line - 1 >= start.y && (line - 1 > start.y || charPos - 1 >= start.x)) &&
184          (line - 1 >= end.y && (line - 1 > end.y || charPos - 1 >= end.x)))
185       {
186          // Location is after
187          if(line - 1 >= end.y)
188          {
189             // Location is on another line
190             if(line - 1 > end.y)
191                line -= end.y - start.y;
192             // Location is the last touched line
193             else
194             {
195                if(charPos - 1 >= end.x)
196                {
197                   line = start.y + 1;
198                   //if(start.line == end.line)
199                      charPos -= end.x - start.x;
200                }
201             }
202          }
203       }
204       else
205       {
206          line = start.y + 1;
207          charPos = start.x + 1;
208       }
209    }
210
211    // Assuming no carriage return before first character ???? fixed?
212    void AdjustAdd(BufferLocation start, BufferLocation end)
213    {
214       int numLines = end.y - start.y;
215       if(line - 1 >= start.y)
216       {
217          if(line - 1 > start.y)
218             line += numLines;
219          else
220          {
221             if(charPos - 1 > start.x || (charPos - 1 == start.x /*&& (numLines ? true : false)*/))
222             {
223                line += numLines;
224                //charPos - 1 += numLines ? end.x : (end.x - start.x);
225                charPos += end.x - start.x;
226             }
227          }
228       }
229    }
230 };
231
232 public struct Location
233 {
234 public:
235    CodePosition start, end;
236
237    bool Inside(int line, int charPos)
238    {
239       return (start.line < line || (start.line == line && start.charPos <= charPos)) &&
240              (end.line > line || (end.line == line && end.charPos >= charPos));
241    }
242 };
243
244 public enum DefinitionType { moduleDefinition, classDefinition, defineDefinition, functionDefinition, dataDefinition };
245
246 public class Definition : struct
247 {
248 public:
249    Definition prev, next;
250    char * name;
251    DefinitionType type;
252 };
253
254 public class ImportedModule : struct
255 {
256 public:
257    ImportedModule prev, next;
258    char * name;
259    DefinitionType type;
260    ImportType importType;
261    bool globalInstance;
262    bool dllOnly;
263    AccessMode importAccess;
264 };
265
266 public class Identifier : struct
267 {
268 public:
269    Identifier prev, next;
270    Location loc;
271    // TODO: NameSpace * nameSpace;
272    Symbol classSym;
273    Specifier _class;
274    char * string;
275    Identifier badID;
276 };
277
278 public enum ExpressionType
279 {
280    identifierExp, instanceExp, constantExp, stringExp, opExp,
281    bracketsExp, indexExp, callExp, memberExp, pointerExp, typeSizeExp,
282    castExp, conditionExp, newExp, renewExp, classSizeExp,
283    dummyExp, dereferenceErrorExp, symbolErrorExp, classMemberSymbolErrorExp,
284    structMemberSymbolErrorExp, memoryErrorExp, unknownErrorExp,
285    noDebuggerErrorExp, debugStateErrorExp,
286    extensionCompoundExp, classExp, classDataExp, new0Exp, renew0Exp,
287    dbopenExp, dbfieldExp, dbtableExp, dbindexExp, extensionExpressionExp, extensionInitializerExp,
288    vaArgExp, arrayExp, typeAlignExp
289 };
290
291 public enum MemberType
292 {
293    unresolvedMember, propertyMember, methodMember, dataMember, reverseConversionMember, classPropertyMember
294 };
295
296 public class ExpUsage
297 {
298 public:
299    bool usageGet:1, usageSet:1, usageArg:1, usageCall:1, usageMember:1, usageDeepGet:1, usageRef:1, usageDelete:1;
300 };
301
302 public class TemplateParameter : struct
303 {
304 public:
305    TemplateParameter prev, next;
306    Location loc;
307
308    TemplateParameterType type;
309    Identifier identifier;
310    union
311    {
312       TemplateDatatype dataType; // For both base datatype (type) and data type (expression)
313       TemplateMemberType memberType;   // For identifier
314    };
315    TemplateArgument defaultArgument;
316
317    // For type parameters
318    char * dataTypeString;
319    Type baseType;
320 }
321
322 public class TemplateDatatype : struct
323 {
324 public:
325    OldList * specifiers;
326    Declarator decl;
327 }
328
329 public class TemplateArgument : struct
330 {
331 public:
332    TemplateArgument prev, next;
333    Location loc;
334
335    Identifier name;
336    TemplateParameterType type;
337    union
338    {
339       Expression expression;
340       Identifier identifier;
341       TemplateDatatype templateDatatype;
342    };
343 }
344
345 public enum SpecifierType
346 {
347    baseSpecifier, nameSpecifier, enumSpecifier, structSpecifier, unionSpecifier, /*classSpecifier,*/
348    extendedSpecifier, typeOfSpecifier, subClassSpecifier, templateTypeSpecifier
349 };
350
351 public class Specifier : struct
352 {
353 public:
354    Specifier prev, next;
355    Location loc;
356    SpecifierType type;
357    union
358    {
359       int specifier;
360       struct
361       {
362          ExtDecl extDecl;
363          char * name;
364          Symbol symbol;
365          OldList * templateArgs;
366       };
367       struct
368       {
369          Identifier id;
370          OldList * list;
371          OldList * baseSpecs;
372          OldList * definitions;
373          bool addNameSpace;
374          Context ctx;
375          ExtDecl extDeclStruct;
376       };
377       Expression expression;
378       Specifier _class;
379       TemplateParameter templateParameter;
380    };
381 };
382
383 public class Attribute : struct
384 {
385 public:
386    Attribute prev, next;
387    Location loc;
388    String attr;
389    Expression exp;
390 }
391
392 public class Attrib : struct
393 {
394 public:
395    Location loc;
396    int type;
397    OldList * attribs;
398 }
399
400 public class ExtDecl : struct
401 {
402 public:
403    Location loc;
404    ExtDeclType type;
405    union
406    {
407       String s;
408       Attrib attr;
409    };
410 }
411
412 public enum ExtDeclType
413 {
414    extDeclString, extDeclAttrib
415 };
416
417 public class Expression : struct
418 {
419 public:
420    Expression prev, next;
421    Location loc;
422    ExpressionType type;
423    union
424    {
425       struct
426       {
427          char * constant;
428          Identifier identifier;
429       };
430       Statement compound;
431       Instantiation instance;
432       char * string;
433       OldList * list;
434       struct
435       {
436          OldList * specifiers;
437          Declarator decl;
438       } _classExp;
439       struct
440       {
441          Identifier id;
442       } classData;
443       struct
444       {
445          Expression exp;
446          OldList * arguments;
447          Location argLoc;
448       } call;
449       struct
450       {
451          Expression exp;
452          OldList * index;
453       } index;
454       struct
455       {
456          Expression exp;
457          Identifier member;
458
459          MemberType memberType;
460          bool thisPtr;
461       } member;
462       struct
463       {
464          int op;
465          Expression exp1, exp2;
466       } op;
467       TypeName typeName;
468       Specifier _class;
469       struct
470       {
471          TypeName typeName;
472          Expression exp;
473       } cast;
474       struct
475       {
476          Expression cond;
477          OldList * exp;
478          Expression elseExp;
479       } cond;
480       struct
481       {
482          TypeName typeName;
483          Expression size;
484       } _new;
485       struct
486       {
487          TypeName typeName;
488          Expression size;
489          Expression exp;
490       } _renew;
491       struct
492       {
493          char * table;
494          Identifier id;
495       } db;
496       struct
497       {
498          Expression ds;
499          Expression name;
500       } dbopen;
501       struct
502       {
503          TypeName typeName;
504          Initializer initializer;
505       } initializer;
506       struct
507       {
508          Expression exp;
509          TypeName typeName;
510       } vaArg;
511    };
512
513    bool debugValue;
514
515    DataValue val;
516
517    uint64 address;
518    bool hasAddress;
519
520    // *** COMPILING DATA ***
521    Type expType;
522    Type destType;
523
524    ExpUsage usage;
525    int tempCount;
526    bool byReference;
527    bool isConstant;
528    bool addedThis;
529    bool needCast;
530    bool thisPtr;
531
532    void Clear()
533    {
534       debugValue = false;
535       val = { 0 };
536       address = 0;
537       hasAddress = false;
538
539       expType = null;
540       destType = null;
541
542       usage = 0;
543       tempCount = 0;
544       byReference = false;
545       isConstant = false;
546       addedThis = false;
547       needCast = false;
548       thisPtr = false;
549    }
550 };
551
552 public class Enumerator : struct
553 {
554 public:
555    Enumerator prev, next;
556    Location loc;
557    Identifier id;
558    Expression exp;
559 };
560
561 class Pointer : struct
562 {
563    Pointer prev, next;
564    Location loc;
565    OldList * qualifiers;
566    Pointer pointer;
567 };
568
569 public enum DeclaratorType
570 {
571    structDeclarator, identifierDeclarator, bracketsDeclarator, arrayDeclarator,
572    functionDeclarator, pointerDeclarator, extendedDeclarator, extendedDeclaratorEnd
573 };
574
575 public class Declarator : struct
576 {
577 public:
578    Declarator prev, next;
579    Location loc;
580    DeclaratorType type;
581    Symbol symbol;//, propSymbol;
582    Declarator declarator;
583    union
584    {
585       Identifier identifier;
586       struct
587       {
588          Expression exp;
589          Expression posExp;
590          Attrib attrib;
591       } structDecl;
592       struct
593       {
594          Expression exp;
595          Specifier enumClass;
596       } array;
597       struct
598       {
599          OldList * parameters;
600       } function;
601       struct
602       {
603          Pointer pointer;
604       } pointer;
605       struct
606       {
607          ExtDecl extended;
608       } extended;
609    };
610 };
611
612 public enum InitializerType { expInitializer, listInitializer };
613
614 public class Initializer : struct
615 {
616 public:
617    Initializer prev, next;
618    Location loc;
619    InitializerType type;
620    union
621    {
622       Expression exp;
623       OldList * list;
624    };
625    bool isConstant;
626 };
627
628 public class InitDeclarator : struct
629 {
630 public:
631    InitDeclarator prev, next;
632    Location loc;
633    Declarator declarator;
634    Initializer initializer;
635 };
636
637 public enum ClassObjectType
638 {
639    none,
640    classPointer,
641    typedObject,
642    anyObject
643 };
644
645 public class TypeName : struct
646 {
647 public:
648    TypeName prev, next;
649    Location loc;
650    OldList * qualifiers;
651    Declarator declarator;
652    //bool /*typedObject, */byReference;
653    //bool anyObject;
654    ClassObjectType classObjectType;
655    Expression bitCount;
656 };
657
658 class AsmField : struct
659 {
660    AsmField prev, next;
661    Location loc;
662    char * command;
663    Expression expression;
664    Identifier symbolic;
665 };
666
667 public enum StmtType { labeledStmt, caseStmt, compoundStmt,
668                expressionStmt, ifStmt, switchStmt, whileStmt, doWhileStmt,
669                forStmt, gotoStmt, continueStmt, breakStmt, returnStmt, asmStmt, badDeclarationStmt,
670                fireWatchersStmt, stopWatchingStmt, watchStmt, forEachStmt
671              };
672
673 public class Statement : struct
674 {
675 public:
676    Statement prev, next;
677    Location loc;
678    StmtType type;
679    union
680    {
681       OldList * expressions;
682       struct
683       {
684          Identifier id;
685          Statement stmt;
686       } labeled;
687       struct
688       {
689          Expression exp;
690          Statement stmt;
691       } caseStmt;
692       struct
693       {
694          OldList * declarations;
695          OldList * statements;
696          Context context;
697          bool isSwitch;
698       } compound;
699       struct
700       {
701          OldList * exp;
702          Statement stmt;
703          Statement elseStmt;
704       } ifStmt;
705       struct
706       {
707          OldList * exp;
708          Statement stmt;
709       } switchStmt;
710       struct
711       {
712          OldList * exp;
713          Statement stmt;
714       } whileStmt;
715       struct
716       {
717          OldList * exp;
718          Statement stmt;
719       } doWhile;
720       struct
721       {
722          Statement init;
723          Statement check;
724          OldList * increment;
725          Statement stmt;
726       } forStmt;
727       struct
728       {
729          Identifier id;
730       } gotoStmt;
731       struct
732       {
733          Specifier spec;
734          char * statements;
735          OldList * inputFields;
736          OldList * outputFields;
737          OldList * clobberedFields;
738       } asmStmt;
739       struct
740       {
741          Expression watcher, object;
742          OldList * watches;   // OldList of PropertyWatch for a StmtWatch, list of property identifiers for firewatches, stopwatching
743       } _watch;
744       struct
745       {
746          Identifier id;
747          OldList * exp;
748          OldList * filter;
749          Statement stmt;
750       } forEachStmt;
751       Declaration decl;
752    };
753 };
754
755 public enum DeclarationType { structDeclaration, initDeclaration, instDeclaration, defineDeclaration };
756
757 public class Declaration : struct
758 {
759 public:
760    Declaration prev, next;
761    Location loc;
762    DeclarationType type;
763    union
764    {
765       struct
766       {
767          OldList * specifiers;
768          OldList * declarators;
769       };
770       Instantiation inst;
771       struct
772       {
773          Identifier id;
774          Expression exp;
775       };
776    };
777    Specifier extStorage;
778    Symbol symbol;
779    AccessMode declMode;
780 };
781
782 public class Instantiation : struct
783 {
784 public:
785    Instantiation prev, next;
786    Location loc;
787    Specifier _class;
788    Expression exp;
789    OldList * members;
790    Symbol symbol;
791    bool fullSet;
792    bool isConstant;
793    byte * data;
794    Location nameLoc, insideLoc;
795    bool built;
796 };
797
798 public enum MembersInitType { dataMembersInit, methodMembersInit };
799
800 public class FunctionDefinition : struct
801 {
802 public:
803    FunctionDefinition prev, next;
804    Location loc;
805    OldList * specifiers;
806    Declarator declarator;
807    OldList * declarations;
808    Statement body;
809    Class _class;
810    OldList attached;    // For IDE
811    AccessMode declMode;
812
813    Type type;
814    Symbol propSet;
815
816    int tempCount;
817    bool propertyNoThis; // Not used yet; might use to support both this = and return syntax for conversion properties
818 };
819
820 public class ClassFunction : struct
821 {
822 public:
823    ClassFunction prev, next;
824    Location loc;
825    OldList * specifiers;
826    Declarator declarator;
827    OldList * declarations;
828    Statement body;
829    Class _class;
830    OldList attached;    // For IDE
831    AccessMode declMode;
832
833    // COMPILING DATA
834    Type type;
835    Symbol propSet;
836
837    bool isVirtual;
838    bool isConstructor, isDestructor;
839    bool dontMangle;
840    int id, idCode;
841 };
842
843 public class MembersInit : struct
844 {
845 public:
846    MembersInit prev, next;
847    Location loc;
848    MembersInitType type;
849    union
850    {
851       OldList * dataMembers;
852       ClassFunction function;
853    };
854    //bool coloned;
855 };
856
857 public class MemberInit : struct
858 {
859 public:
860    MemberInit prev, next;
861    Location loc;
862    Location realLoc;
863    OldList * identifiers;
864    // Expression exp;
865    Initializer initializer;
866
867    // COMPILE DATA
868    bool used;
869    bool variable;
870    bool takeOutExp;
871 };
872
873 public class ClassDefinition : struct
874 {
875 public:
876    ClassDefinition prev, next;
877    Location loc;
878    Specifier _class;
879    // Specifier base;
880    OldList * baseSpecs;
881    OldList * definitions;
882    Symbol symbol;
883    Location blockStart;
884    Location nameLoc;
885    int endid;
886    AccessMode declMode;
887    bool deleteWatchable;
888 };
889
890 public class PropertyWatch : struct
891 {
892 public:
893    PropertyWatch prev, next;
894    Location loc;
895    Statement compound;
896    OldList * properties;
897    bool deleteWatch;
898 };
899
900 public enum ClassDefType
901 {
902    functionClassDef, defaultPropertiesClassDef, declarationClassDef, propertyClassDef,
903    propertyWatchClassDef, classDesignerClassDef, classNoExpansionClassDef, classFixedClassDef,
904    designerDefaultPropertyClassDef, classDataClassDef, classPropertyClassDef, classPropertyValueClassDef,
905    memberAccessClassDef, accessOverrideClassDef
906 };
907
908 public class PropertyDef : struct
909 {
910 public:
911    PropertyDef prev, next;
912    Location loc;
913    OldList * specifiers;
914    Declarator declarator;
915    Identifier id;
916    Statement getStmt;
917    Statement setStmt;
918    Statement issetStmt;
919    Symbol symbol;
920    bool conversion;
921    bool isWatchable;
922    Expression category;
923 };
924
925 public class ClassDef : struct
926 {
927 public:
928    ClassDef prev, next;
929    Location loc;
930    ClassDefType type;
931    union
932    {
933       Declaration decl;
934       ClassFunction function;
935       OldList * defProperties;
936       PropertyDef propertyDef;
937       PropertyWatch propertyWatch;
938       char * designer;
939       Identifier defaultProperty;
940       struct
941       {
942          Identifier id;
943          Initializer initializer;
944       };
945    };
946    AccessMode memberAccess;
947
948    // IDE
949    void * object;
950 };
951
952 public enum ExternalType { functionExternal, declarationExternal, classExternal, importExternal, nameSpaceExternal, dbtableExternal };
953
954 public class External : struct
955 {
956 public:
957    External prev, next;
958    Location loc;
959    ExternalType type;
960    Symbol symbol;
961    union
962    {
963       FunctionDefinition function;
964       ClassDefinition _class;
965       Declaration declaration;
966       char * importString;
967       Identifier id;
968       DBTableDef table;
969    };
970    ImportType importType;
971 };
972
973 public class Context : struct
974 {
975 public:
976    Context parent;
977    BinaryTree types { CompareKey = (void *)BinaryTree::CompareString };
978    BinaryTree classes { CompareKey = (void *)BinaryTree::CompareString };
979    BinaryTree symbols { CompareKey = (void *)BinaryTree::CompareString };
980    BinaryTree structSymbols { CompareKey = (void *)BinaryTree::CompareString };
981    int nextID;
982    int simpleID;
983    BinaryTree templateTypes { CompareKey = (void *)BinaryTree::CompareString };
984    ClassDefinition classDef;
985    bool templateTypesOnly;
986    bool hasNameSpace;
987 };
988
989 /*************** Compiling passes symbols ***************/
990
991 public class Symbol : struct
992 {
993 public:
994    char * string;
995    Symbol parent, left, right;   // Reusing left, right as prev, next when in excludedSymbols
996    int depth;
997
998    Type type;
999    union
1000    {
1001       Method method;
1002       Property _property;
1003       Class registered;
1004    };
1005    int id, idCode;
1006    union
1007    {
1008       struct
1009       {
1010          External pointerExternal;  // external declaration for the pointer to the Class:    e.g. __ecereClass___ecereNameSpace__ecere__com__Class
1011          External structExternal;   // external declaration for the actual class members structure: e.g. __ecereNameSpace__ecere__com__Class
1012       };
1013       struct
1014       {
1015          External externalGet;
1016          External externalSet;
1017          External externalPtr;    // Property pointer for watchers
1018          External externalIsSet;
1019       };
1020       struct
1021       {
1022          External methodExternal;
1023          External methodCodeExternal;
1024       };
1025    };
1026    bool imported, declaredStructSym;
1027    Class _class; // for properties only...
1028
1029    // Only used for classes right now...
1030    bool declaredStruct;
1031    bool needConstructor, needDestructor;
1032    char * constructorName, * structName, * className, * destructorName;
1033
1034    ModuleImport module;
1035    ClassImport _import;
1036    Location nameLoc;
1037    bool isParam;
1038    bool isRemote;
1039    bool isStruct;
1040    bool fireWatchersDone;
1041    int declaring;
1042    bool classData;
1043    bool isStatic;
1044    char * shortName;
1045    OldList * templateParams;     // Review the necessity for this
1046    OldList templatedClasses;
1047    Context ctx;
1048    int isIterator;
1049    Expression propCategory;
1050 };
1051
1052 // For the .imp file:
1053 public class ClassImport : struct
1054 {
1055 public:
1056    ClassImport prev, next;
1057    char * name;
1058    OldList methods;
1059    OldList properties;
1060    bool itself;
1061    bool isRemote;
1062 };
1063
1064 public class FunctionImport : struct
1065 {
1066 public:
1067    FunctionImport prev, next;
1068    char * name;
1069 };
1070
1071 public class ModuleImport : struct
1072 {
1073 public:
1074    ModuleImport prev, next;
1075    char * name;
1076    OldList classes;
1077    OldList functions;
1078    ImportType importType;
1079    AccessMode importAccess;
1080 };
1081
1082 public class PropertyImport : struct
1083 {
1084 public:
1085    PropertyImport prev, next;
1086    char * name;
1087    bool isVirtual;
1088    bool hasSet, hasGet;
1089 };
1090
1091 public class MethodImport : struct
1092 {
1093 public:
1094    MethodImport prev, next;
1095    char * name;
1096    bool isVirtual;
1097 };
1098
1099 // For the .sym file:
1100 public enum TypeKind
1101 {
1102    voidType, charType, shortType, intType, int64Type, longType, floatType,
1103    doubleType, classType, structType, unionType, functionType, arrayType, pointerType,
1104    ellipsisType, enumType, methodType, vaListType, /*typedObjectType, anyObjectType, classPointerType, */ dummyType,
1105    subClassType, templateType, thisClassType, intPtrType, intSizeType, _BoolType
1106 };
1107
1108 public class Type : struct
1109 {
1110 public:
1111    Type prev, next;
1112    int refCount;
1113    union
1114    {
1115       Symbol _class;
1116       struct
1117       {
1118          OldList members;
1119          char * enumName;
1120       };
1121       // For a function:
1122       struct
1123       {
1124          Type returnType;
1125          OldList params;
1126          Symbol thisClass;
1127          bool staticMethod;
1128          TemplateParameter thisClassTemplate;
1129       };
1130       // For a method
1131       struct
1132       {
1133          Method method;
1134          Class methodClass;      // Clarify what this is!
1135          Class usedClass;
1136       };
1137
1138       // For an array:
1139       struct
1140       {
1141          Type arrayType;
1142          int arraySize;
1143          Expression arraySizeExp;
1144          bool freeExp;
1145          Symbol enumClass;
1146       };
1147       // For a pointer:
1148       Type type;
1149       TemplateParameter templateParameter;
1150    };
1151    TypeKind kind;
1152    uint size;
1153    char * name;
1154    char * typeName;
1155
1156    ClassObjectType classObjectType;
1157    int alignment;
1158    uint offset;
1159    int bitFieldCount;
1160    int count;
1161
1162    bool isSigned:1;
1163    bool constant:1;
1164    bool truth:1;
1165    bool byReference:1;
1166    bool extraParam:1;      // Clarify this... One thing it is used for is adaptive method with their own type explicitly specified
1167    bool directClassAccess:1;     // Need to clarify this if this had the same intended purpose as declaredWithStruct
1168    bool computing:1;
1169    bool keepCast:1;
1170    bool passAsTemplate:1;
1171    bool dllExport:1;
1172    bool attrStdcall:1;
1173    bool declaredWithStruct:1;
1174    bool typedByReference:1;      // Originally typed by reference, regardless of class type
1175    // TODO: Add _Complex & _Imaginary support
1176    // bool complex:1, imaginary:1;
1177
1178    char * OnGetString(char * tempString, void * fieldData, bool * needClass)
1179    {
1180       Type type = (Type)this;
1181       tempString[0] = '\0';
1182       if(type)
1183          PrintType(type, tempString, false, true);
1184       return tempString;
1185    }
1186
1187    void OnFree()
1188    {
1189
1190    }
1191 };
1192
1193 public struct Operand
1194 {
1195 public:
1196    TypeKind kind;
1197    Type type;
1198    unsigned int ptrSize;
1199    union    // Promote to using data value
1200    {
1201       char c;
1202       unsigned char uc;
1203       short s;
1204       unsigned short us;
1205       int i;
1206       unsigned int ui;
1207       float f;
1208       double d;
1209       // unsigned char * p; // Now always storing addresses in ui64
1210       int64 i64;
1211       uint64 ui64;
1212       // intptr iptr;
1213       // uintptr uiptr;
1214    };
1215    OpTable ops;
1216 };
1217
1218 public struct OpTable
1219 {
1220 public:
1221    // binary arithmetic
1222    bool (* Add)(Expression, Operand, Operand);
1223    bool (* Sub)(Expression, Operand, Operand);
1224    bool (* Mul)(Expression, Operand, Operand);
1225    bool (* Div)(Expression, Operand, Operand);
1226    bool (* Mod)(Expression, Operand, Operand);
1227
1228    // unary arithmetic
1229    bool (* Neg)(Expression, Operand);
1230
1231    // unary arithmetic increment and decrement
1232    bool (* Inc)(Expression, Operand);
1233    bool (* Dec)(Expression, Operand);
1234
1235    // binary arithmetic assignment
1236    bool (* Asign)(Expression, Operand, Operand);
1237    bool (* AddAsign)(Expression, Operand, Operand);
1238    bool (* SubAsign)(Expression, Operand, Operand);
1239    bool (* MulAsign)(Expression, Operand, Operand);
1240    bool (* DivAsign)(Expression, Operand, Operand);
1241    bool (* ModAsign)(Expression, Operand, Operand);
1242
1243    // binary bitwise
1244    bool (* BitAnd)(Expression, Operand, Operand);
1245    bool (* BitOr)(Expression, Operand, Operand);
1246    bool (* BitXor)(Expression, Operand, Operand);
1247    bool (* LShift)(Expression, Operand, Operand);
1248    bool (* RShift)(Expression, Operand, Operand);
1249    bool (* BitNot)(Expression, Operand);
1250
1251    // binary bitwise assignment
1252    bool (* AndAsign)(Expression, Operand, Operand);
1253    bool (* OrAsign)(Expression, Operand, Operand);
1254    bool (* XorAsign)(Expression, Operand, Operand);
1255    bool (* LShiftAsign)(Expression, Operand, Operand);
1256    bool (* RShiftAsign)(Expression, Operand, Operand);
1257
1258    // unary logical negation
1259    bool (* Not)(Expression, Operand);
1260
1261    // binary logical equality
1262    bool (* Equ)(Expression, Operand, Operand);
1263    bool (* Nqu)(Expression, Operand, Operand);
1264
1265    // binary logical
1266    bool (* And)(Expression, Operand, Operand);
1267    bool (* Or)(Expression, Operand, Operand);
1268
1269    // binary logical relational
1270    bool (* Grt)(Expression, Operand, Operand);
1271    bool (* Sma)(Expression, Operand, Operand);
1272    bool (* GrtEqu)(Expression, Operand, Operand);
1273    bool (* SmaEqu)(Expression, Operand, Operand);
1274
1275    bool (* Cond)(Expression, Operand, Operand, Operand);
1276 };
1277
1278 define MAX_INCLUDE_DEPTH = 30;
1279
1280 #include <stdarg.h>
1281
1282 void Compiler_Error(char * format, ...)
1283 {
1284    if(inCompiler)
1285    {
1286       if(!parsingType)
1287       {
1288          va_list args;
1289          char string[10000];
1290
1291          if(yylloc.start.included)
1292          {
1293             GetWorkingDir(string, sizeof(string));
1294             PathCat(string, GetIncludeFileFromID(yylloc.start.included));
1295          }
1296          else
1297          {
1298             GetWorkingDir(string, sizeof(string));
1299             PathCat(string, sourceFile);
1300          }
1301          printf(string);
1302
1303          /*
1304          yylloc.start.col = yylloc.end.col = 1;
1305          yylloc.start.line = yylloc.end.line = 1;
1306          yylloc.start.pos = yylloc.end.pos = 0;
1307          */
1308 #ifdef _DEBUG
1309          if(!yylloc.start.line)
1310             printf("");
1311 #endif
1312
1313          //printf("(%d, %d) : error: ", yylloc.start.line, yylloc.start.charPos);
1314          printf($":%d:%d: error: ", yylloc.start.line, yylloc.start.charPos);
1315          //printf(":%d: error: ", yylloc.start.line);
1316          va_start(args, format);
1317          vsnprintf(string, sizeof(string), format, args);
1318          string[sizeof(string)-1] = 0;
1319          va_end(args);
1320          fputs(string, stdout);
1321          __thisModule.application.exitCode = 1;
1322       }
1323       else
1324       {
1325          // Error parsing type
1326          parseTypeError = true;
1327       }
1328    }
1329 }
1330
1331 int numWarnings;
1332 public int GetNumWarnings() { return numWarnings; }
1333
1334 void Compiler_Warning(char * format, ...)
1335 {
1336    if(inCompiler)
1337    {
1338       va_list args;
1339       char string[10000];
1340       char fileName[MAX_FILENAME];
1341
1342       if(yylloc.start.included)
1343       {
1344          String include = GetIncludeFileFromID(yylloc.start.included);
1345          GetWorkingDir(string, sizeof(string));
1346          PathCat(string, include);
1347       }
1348       else
1349       {
1350          GetWorkingDir(string, sizeof(string));
1351          PathCat(string, sourceFile);
1352       }
1353
1354       // Skip these warnings from MinGW-w64 GCC 4.8 in intrin-impl.h
1355       GetLastDirectory(string, fileName);
1356       if(!strcmp(fileName, "intrin-impl.h")) return;
1357
1358       printf(string);
1359
1360       //printf("(%d, %d) : warning: ", yylloc.start.line, yylloc.start.charPos);
1361       printf($":%d:%d: warning: ", yylloc.start.line, yylloc.start.charPos);
1362       //printf(":%d: warning: ", yylloc.start.line);
1363       va_start(args, format);
1364       vsnprintf(string, sizeof(string), format, args);
1365       string[sizeof(string)-1] = 0;
1366       va_end(args);
1367       fputs(string, stdout);
1368       numWarnings++;
1369    }
1370 }
1371 bool parseError;
1372 bool skipErrors;
1373
1374 int yyerror(char * s)
1375 {
1376    if(!skipErrors)
1377    {
1378         //fflush(stdout);
1379         //printf("\n%*s\n%*s\n", column, "^", column, s);
1380       parseError = true;
1381       Compiler_Error($"syntax error\n");
1382    }
1383    return 0;
1384 }
1385
1386 Platform targetPlatform;
1387
1388 public int GetHostBits()
1389 {
1390    // Default to runtime platform in case we fail to determine host
1391    int hostBits = (sizeof(uintptr) == 8) ? 64 : 32;
1392    String hostType = getenv("HOSTTYPE");
1393    char host[256];
1394    if(!hostType)
1395    {
1396       DualPipe f = DualPipeOpen({ output = true }, "uname -m");
1397       if(f)
1398       {
1399          if(f.GetLine(host, sizeof(host)))
1400             hostType = host;
1401          delete f;
1402       }
1403    }
1404    if(hostType)
1405    {
1406       if(!strcmp(hostType, "x86_64"))
1407          hostBits = 64;
1408       else if(!strcmp(hostType, "i386") || !strcmp(hostType, "i686"))
1409          hostBits = 32;
1410    }
1411    return hostBits;
1412 }
1413
1414 public void SetTargetPlatform(Platform platform) { targetPlatform = platform; };
1415
1416 int targetBits;
1417
1418 public void SetTargetBits(int bits) { targetBits = bits; };
1419 public int GetTargetBits() { return targetBits; };