Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
6.5 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  2. //
  3. // Declaration of a script's control structures.
  4. //
  5. #pragma once
  6. #include "englookup.h"
  7. #include "englex.h"
  8. //////////////////////////////////////////////////////////////////////
  9. // Statement structures
  10. // forward decls and collections
  11. class Routine;
  12. typedef Slots<Routine> Routines;
  13. class Variable;
  14. typedef Slots<Variable> Variables;
  15. class ReferenceName;
  16. typedef Slots<ReferenceName> ReferenceNames;
  17. class VariableReference;
  18. typedef Slots<VariableReference> VariableReferences;
  19. class Statement;
  20. typedef Slots<Statement> Statements;
  21. class Value;
  22. typedef Slots<Value> Values;
  23. class Call;
  24. typedef Slots<Call> Calls;
  25. class ExprBlock;
  26. typedef Slots<ExprBlock> ExprBlocks;
  27. class IfBlock;
  28. typedef Slots<IfBlock> IfBlocks;
  29. class Assignment;
  30. typedef Slots<Assignment> Assignments;
  31. class Variable
  32. {
  33. public:
  34. Variable(Strings::index _istrIdentifier, DISPID _dispid = DISPID_UNKNOWN) : istrIdentifier(_istrIdentifier), dispid(_dispid) {}
  35. Strings::index istrIdentifier;
  36. DISPID dispid; // this is set to a value other than DISPID_UNKNOWN if the variable is a member of the global dispatch instead of an item in the script itself
  37. private:
  38. friend class SmartRef::Vector<Variable>;
  39. Variable() {}
  40. };
  41. // Names used in a sequence for dereferencing attributes or function calls.
  42. // For example, a and b in "a.b" or x and y in "x.y(3)".
  43. class ReferenceName
  44. {
  45. public:
  46. ReferenceName(Strings::index _istrIdentifier) : istrIdentifier(_istrIdentifier) {}
  47. Strings::index istrIdentifier; // -1 is used to end a sequence of names
  48. private:
  49. friend class SmartRef::Vector<ReferenceName>;
  50. ReferenceName() {}
  51. };
  52. class VariableReference
  53. {
  54. public:
  55. enum kind { _global, _local };
  56. VariableReference(kind _k, ReferenceNames::index _irname, Variables::index _ivar)
  57. : k(_k), irname(_irname), ivar(_ivar) {}
  58. kind k;
  59. ReferenceNames::index irname;
  60. Variables::index ivar; // slot of the first name within (global/local/temporary) variables
  61. private:
  62. friend class SmartRef::Vector<VariableReference>;
  63. VariableReference() {}
  64. };
  65. class Value
  66. {
  67. public:
  68. // dummy types to differentiate constructors
  69. enum cons_numvalue {};
  70. enum cons_strvalue {};
  71. enum cons_varref {};
  72. enum kind { _numvalue, _strvalue, _varref };
  73. Value(cons_numvalue e, int iVal) : k(_numvalue) { inumvalue = iVal; }
  74. Value(cons_strvalue e, Strings::index iStr) : k(_strvalue) { istrvalue = iStr; }
  75. Value(cons_varref e, VariableReferences::index _ivarref) : k(_varref) { ivarref = _ivarref; }
  76. kind k;
  77. union
  78. {
  79. int inumvalue;
  80. Strings::index istrvalue;
  81. VariableReferences::index ivarref;
  82. };
  83. private:
  84. friend class SmartRef::Vector<Value>;
  85. Value() {}
  86. };
  87. class Call
  88. {
  89. public:
  90. // dummy types to differentiate constructors
  91. enum cons_global {};
  92. enum cons_dereferenced {};
  93. enum kind { _global, _dereferenced };
  94. Call() {} // all fields are set after creation
  95. kind k;
  96. union
  97. {
  98. Strings::index istrname; // _global
  99. VariableReferences::index ivarref; // _dereferenced
  100. };
  101. ExprBlocks::index iexprParams; // doubly-terminated list of lists. each parameter is terminated with an _end block and the final parameter is also terminated with a second _end block.
  102. };
  103. class ExprBlock
  104. {
  105. public:
  106. // dummy types to differentiate constructors
  107. enum cons_end {};
  108. enum cons_op {};
  109. enum cons_val {};
  110. enum cons_call {};
  111. enum cons_omitted {}; // used only in a routine call, stands for an omitted parameter
  112. enum kind { _end = 0, _op, _val, _call, _omitted };
  113. // Note: For unary - (negation), TOKEN_sub is used instead of TOKEN_op_minus.
  114. ExprBlock(cons_end e) : k(_end) {}
  115. ExprBlock(cons_op e, Token __op) : k(_op) { op = __op; assert(CheckOperatorType(op, true, true, true, false) || op == TOKEN_sub); }
  116. ExprBlock(cons_val e, Values::index _ival) : k(_val) { ival = _ival; }
  117. ExprBlock(cons_call e, Calls::index _icall) : k(_call) { icall = _icall; }
  118. ExprBlock(cons_omitted e) : k(_omitted) {}
  119. operator bool() { return k != _end; }
  120. kind k;
  121. union
  122. {
  123. Token op;
  124. Values::index ival;
  125. Calls::index icall;
  126. };
  127. private:
  128. friend class SmartRef::Vector<ExprBlock>;
  129. friend class SmartRef::Stack<ExprBlock>;
  130. ExprBlock() {}
  131. };
  132. class Assignment
  133. {
  134. public:
  135. Assignment(bool _fSet, VariableReferences::index _ivarrefLHS, ExprBlocks::index _iexprRHS) : fSet(_fSet), ivarrefLHS(_ivarrefLHS), iexprRHS(_iexprRHS) {}
  136. bool fSet;
  137. VariableReferences::index ivarrefLHS;
  138. ExprBlocks::index iexprRHS;
  139. private:
  140. friend class SmartRef::Vector<Assignment>;
  141. Assignment() {}
  142. };
  143. class IfBlock
  144. {
  145. public:
  146. // _end: end of blocks without an 'else'
  147. // _else: end of blocks with an 'else'
  148. // _cond: a conditional block, from 'if' (first one) or 'elseif' (later ones)
  149. enum kind { _end = 0, _else, _cond };
  150. IfBlock() : k(_end) {}
  151. IfBlock(Statements::index _istmtBlock) : k(_else), istmtBlock(_istmtBlock) {}
  152. IfBlock(ExprBlocks::index _iexprCondition, Statements::index _istmtBlock) : k(_cond), iexprCondition(_iexprCondition), istmtBlock(_istmtBlock) {}
  153. kind k;
  154. ExprBlocks::index iexprCondition; // only used by cond kind
  155. Statements::index istmtBlock; // not used by end kind
  156. };
  157. class Statement
  158. {
  159. public:
  160. typedef int index;
  161. // dummy types to differentiate constructors
  162. enum cons_end {};
  163. enum cons_asgn {};
  164. enum cons_if {};
  165. enum cons_call {};
  166. enum kind { _end = 0, _if, _asgn, _call }; // _end is used as a terminator for a block of statements
  167. Statement(cons_end e, int _iLine) : k(_end), iLine(_iLine) {}
  168. Statement(cons_asgn e, Assignments::index _iasgn, int _iLine) : k(_asgn), iLine(_iLine) { iasgn = _iasgn; }
  169. Statement(cons_if e, int _iLine) : k(_if), iLine(_iLine) { iif = 0; istmtIfTail = 0; }
  170. Statement(cons_call e, Calls::index _icall, int _iLine) : k(_call), iLine(_iLine) { icall = _icall; }
  171. operator bool() { return k != _end; }
  172. kind k;
  173. int iLine;
  174. union
  175. {
  176. Assignments::index iasgn;
  177. struct
  178. {
  179. IfBlocks::index iif;
  180. Statements::index istmtIfTail;
  181. };
  182. Calls::index icall;
  183. };
  184. private:
  185. friend class SmartRef::Vector<Statement>;
  186. Statement() {}
  187. };
  188. class Routine
  189. {
  190. public:
  191. Routine(Strings::index _istrIdentifier) : istrIdentifier(_istrIdentifier), istmtBody(0), ivarNextLocal(0) {}
  192. Strings::index istrIdentifier;
  193. Statements::index istmtBody;
  194. Variables::index ivarNextLocal; // while parsing, this is the next local slot to use. by runtime, this as the total number of local slots needed by the routine.
  195. private:
  196. friend class SmartRef::Vector<Routine>;
  197. Routine() {}
  198. };
  199. class Script
  200. {
  201. public:
  202. Script() {}
  203. Routines routines;
  204. Variables globals;
  205. Strings strings;
  206. Statements statements;
  207. ReferenceNames rnames;
  208. VariableReferences varrefs;
  209. Values vals;
  210. Calls calls;
  211. ExprBlocks exprs;
  212. IfBlocks ifs;
  213. Assignments asgns;
  214. };