CE Expression.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /******************************************************************************/
  2. #if EE_PRIVATE
  3. namespace Edit{
  4. /******************************************************************************/
  5. enum CAST_MATCH
  6. {
  7. CAST_NONE , // can't be casted
  8. CAST_CTOR_CONST, // after converting basic data using constructor parameter with different const
  9. CAST_CTOR , // after converting basic data using constructor parameter
  10. CAST_CONV_CONST, // after conversion (possibly losing precision/data) with different const
  11. CAST_CONV , // after conversion (possibly losing precision/data)
  12. CAST_MAX_CONST , // direct with different const
  13. CAST_MAX , // direct
  14. };
  15. /******************************************************************************/
  16. struct Local // function local variable
  17. {
  18. Symbol::Modif type; // final type of the variable
  19. Bool block_scope, // this variable has block scope
  20. force_heap; // force creation on the heap
  21. Int stack_offset, // offset of the variable in function stack (in bytes, -1=not yet initialized) (or offset in the heap for 'force_heap'==true)
  22. scope_start, // index of command where the local is being created
  23. scope_label; // index of label where scope of this variable ends
  24. Token *token; // token at which the variable gets created
  25. Local() {block_scope=false; force_heap=false; stack_offset=-1; scope_start=scope_label=-1; token=null;}
  26. };
  27. /******************************************************************************/
  28. STRUCT(Expr , BStr)
  29. //{
  30. enum FUNC_CALL_MASK
  31. {
  32. FC_RESULT=0x1,
  33. FC_PARENT=0x2,
  34. };
  35. struct Memory // use 64-bit values to support 64-bit compilation
  36. {
  37. enum TYPE : Byte
  38. {
  39. NONE , // memory address is not known
  40. GLOBAL, // global or static symbol
  41. LOCAL , // function local non-static variable
  42. PARAM , // function parameter
  43. THIS , // function 'this' caller/parent/object
  44. RESULT, // function result
  45. KNOWN , // the value is known at compile-time and doesn't need to be stored in the memory
  46. };
  47. TYPE type ;
  48. Symbol *symbol ; // pointer to the symbol (if it's not a temporary)
  49. Long index , // GLOBAL: raw offset in the heap, LOCAL: index of the variable in the 'locals' memory container, PARAM: raw offset in the parameter stack, THIS: unused, RESULT: unused, KNOWN: unused
  50. offset , // offset from the start of the symbol (applied for all types)
  51. offset2; // offset applied after getting the reference
  52. void clear() {type=NONE; symbol=null; index=-1; offset=offset2=0;}
  53. void setGlobal(Symbol &symbol ) {T.type=GLOBAL; T.symbol=&symbol; T.index=symbol.raw_offset;}
  54. void setParam (Symbol &symbol ) {T.type=PARAM ; T.symbol=&symbol; T.index=symbol.raw_offset;}
  55. void setLocal (Symbol &symbol ) {T.type=LOCAL ; T.symbol=&symbol; T.index=symbol.raw_offset;} // 'symbol' is already assumed to have its 'raw_offset' set to locals
  56. void setLocal (Int local_index) {T.type=LOCAL ; T.symbol= null ; T.index=local_index ;} // set layout for 'local_index' local variable
  57. void setThis ( ) {T.type=THIS ;}
  58. void setResult( ) {T.type=RESULT;}
  59. void setKnown ( ) {T.type=KNOWN ;}
  60. void addOffset(Long offset, Bool ref) {if(ref)T.offset2+=offset;else T.offset+=offset;}
  61. Memory() {clear();}
  62. };
  63. Bool instance , // if the expression contains an actual value (this can be constant bool 'false', number '2', character 'a', variable/object 'x', function pointer 'func' YES in C++ function can be casted to pointers and this is correct), this is FALSE for classes, namespaces, etc.
  64. final , // if from the whole array of expressions this is the only one that we care about calculating
  65. _operator , // if expression is an operator
  66. separator , // if expression operator is a separator '.', '->', '::'
  67. l_to_r , // operator associativity (true="left to right", false="right to left")
  68. temporary , // if the expression is a temporary, this can be constant bool 'false', number '2', character 'a', text "abc", any kind of pointer, or object returned by func/operator/ctor, this currently prevents address-of & operator only
  69. conditional ; // if this expression is not always executed (for example "a ? b : c" - 'b' and 'c' are conditionals, "a && b" - 'b' is conditional, "a || b" - 'b' is conditional)
  70. Byte func_call_mask,
  71. priority ; // operator priority
  72. Symbol::Modif symbol ;
  73. Symbol *symbol_origin ;
  74. Mems<Expr> parent, func, params;
  75. Token *origin ;
  76. Call::Func func_call ;
  77. Memory mem ;
  78. Bool possibleInstanceOrDataTypeOrNativeFunc();
  79. Bool known () {return mem.type==Memory::KNOWN;}
  80. Bool knownFinal (Bool allow_func_lists);
  81. Bool anyInstance () {return instance || instanceChild();} // if is instance or child of an instance
  82. Bool instanceChild(); // if is a child of other variable (has 'instance' parent)
  83. Bool fullTemporary(); // if is a temporary and not a child of other variable (not instanceChild)
  84. Bool basicType () {return symbol.basicType();}
  85. Expr* firstInstance();
  86. Bool asBool (Compiler &compiler);
  87. Int asInt (Compiler &compiler);
  88. UInt asUInt (Compiler &compiler);
  89. Long asLong (Compiler &compiler);
  90. ULong asULong(Compiler &compiler);
  91. Flt asFlt (Compiler &compiler);
  92. Dbl asDbl (Compiler &compiler);
  93. Char asChar (Compiler &compiler);
  94. Char8 asChar8(Compiler &compiler) {return Char16To8Fast(asChar(compiler));} // we can assume that Str was already initialized
  95. Memc<Char> asText (Compiler &compiler); // don't operate on Str to allow '\0' characters inside
  96. U64 asRaw (Compiler &compiler); // use U64 to fit all types of variables
  97. Expr& setOperator(CChar *op ); // will be set as 'borrowed'
  98. Expr& setBasic (VAR_TYPE type );
  99. Expr& setPtr ( );
  100. Expr& toSymbol (Symbol *symbol, Bool func_call=false);
  101. Bool setThis(Symbol *caller, Token *origin, Compiler &compiler);
  102. void setPriority ();
  103. void setConditional();
  104. void setBlockScope (Compiler &compiler, Bool force_heap=false);
  105. void memAuto ( Compiler &compiler); // try to set memory layout from existing symbol
  106. void memNew (Bool known , Compiler &compiler); // create new memory layout on stack or as a known constant
  107. void memFrom (Memory &mem , Compiler &compiler); // set from 'mem'
  108. void memOffset(Long offset ); // apply memory offset to 'mem'
  109. Bool castToBase (Symbol::Modif &dest);
  110. Bool castTo (Symbol::Modif &dest, Compiler &compiler);
  111. Bool castTo (Symbol *dest, Memc<Symbol::Modif> &templates, Compiler &compiler);
  112. CAST_MATCH canBeCastedTo (Symbol *dest, Memc<Symbol::Modif> &templates, Compiler &compiler);
  113. Bool castToConditional();
  114. Bool castParentToSymbolClass(Compiler &compiler);
  115. Bool addressOf (Compiler &compiler);
  116. Bool indirection (Compiler &compiler);
  117. Bool copyCtor (Compiler &compiler);
  118. void proceedToBase(Int base_index);
  119. void create (Token &src, Compiler &compiler, Bool final=false);
  120. void copyThis(Expr &dest); // copy all members except 'parent', 'func', 'params'
  121. void calculateKnown(Expr &op, Expr &a , Compiler &compiler);
  122. void calculateKnown(Expr &op, Expr &a, Expr &b, Compiler &compiler);
  123. CAST_MATCH calculate(Compiler &compiler);
  124. Expr() {instance=final=_operator=separator=l_to_r=temporary=conditional=false; func_call_mask=priority=0; symbol_origin=null; origin=null; func_call=null;}
  125. };
  126. /******************************************************************************/
  127. struct FuncMatch
  128. {
  129. Symbol *func;
  130. Int average_match,
  131. lowest_match;
  132. void create(Symbol *func, Expr *param, Int params, Memc<Symbol::Modif> &templates, Compiler &compiler, Bool extra_match=false);
  133. FuncMatch() {func=null; average_match=lowest_match=0;}
  134. };
  135. /******************************************************************************/
  136. void AddMatch (Memc<FuncMatch> &matches, Symbol *func , Bool l_to_r, Expr *param, Int params, Memc<Symbol::Modif> &templates, Compiler &compiler, Bool extra_match=false);
  137. void AddMatches(Memc<FuncMatch> &matches, Memc<SymbolPtr> &funcs, Bool l_to_r, Expr *param, Int params, Memc<Symbol::Modif> &templates, Compiler &compiler, Bool extra_match=false);
  138. /******************************************************************************/
  139. } // namespace
  140. /******************************************************************************/
  141. inline Int CompareAverage(C Edit::FuncMatch &a, C Edit::FuncMatch &b) { return Compare(b.average_match, a.average_match); } // compare in reversed order so functions with greatest match are listed first (this is the approximate compare used for visual suggestion which function should be best match)
  142. inline Int CompareLowest (C Edit::FuncMatch &a, C Edit::FuncMatch &b) {if(Int c=Compare(b. lowest_match, a. lowest_match))return c; return CompareAverage(a, b);} // compare in reversed order so functions with greatest match are listed first (this is the exact compare used for compilers), use average comparison as second alternative in case there are multiple choices for lowest match (useful for auto-complete suggestions)
  143. /******************************************************************************/
  144. #endif
  145. /******************************************************************************/