FormatHelper.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. using System;
  2. using System.Globalization;
  3. namespace OpenVIII.Fields.Scripts
  4. {
  5. public static class FormatHelper
  6. {
  7. #region Fields
  8. private static readonly string[] Separators = { "\r\n", "\n", "{Line}", "{Next}" };
  9. #endregion Fields
  10. #region Methods
  11. public static Formatter Format(this ScriptWriter sw, IScriptFormatterContext formatterContext, IServices executionContext) => new Formatter(sw, formatterContext, executionContext);
  12. public static void FormatAnswers(ScriptWriter sw, string message, IJsmExpression top, IJsmExpression bottom, IJsmExpression begin, IJsmExpression cancel)
  13. {
  14. if (!(top is IConstExpression t) || !(bottom is IConstExpression b))
  15. {
  16. FormatMonologue(sw, message);
  17. return;
  18. }
  19. if (!sw.HasWhiteLine)
  20. sw.AppendLine();
  21. // Question
  22. //☞ Answer 1
  23. // Answer 2
  24. // Answer 3
  25. //☜ Answer 4
  26. var to = t.Int32();
  27. var bo = b.Int32();
  28. var be = -1;
  29. var ca = -1;
  30. if (begin is IConstExpression beg)
  31. be = beg.Int32();
  32. if (cancel is IConstExpression can)
  33. ca = can.Int32();
  34. var lines = SplitMonologue(message);
  35. for (var i = 0; i < lines.Length; i++)
  36. {
  37. sw.Append("//");
  38. if (i >= to && i <= bo)
  39. {
  40. if (i == be)
  41. sw.Append("☞ ");
  42. else if (i == ca)
  43. sw.Append("☜ ");
  44. else
  45. sw.Append(" ");
  46. }
  47. else
  48. {
  49. sw.Append(" ");
  50. }
  51. sw.AppendLine(lines[i]);
  52. }
  53. }
  54. public static void FormatGlobalGet<T>(GlobalVariableId<T> globalVariable, int[] knownVariables, ScriptWriter sw, IScriptFormatterContext formatterContext, IServices executionContext) where T : unmanaged
  55. {
  56. if (knownVariables == null || Array.BinarySearch(knownVariables, globalVariable.VariableId) < 0)
  57. {
  58. sw.Append("(");
  59. sw.Append(GlobalVariableId<T>.TypeName);
  60. sw.Append(")");
  61. sw.Append("G");
  62. }
  63. else
  64. {
  65. sw.Append("G");
  66. sw.Append(GlobalVariableId<T>.TypeName);
  67. }
  68. sw.Append("[");
  69. sw.Append(globalVariable.VariableId.ToString(CultureInfo.InvariantCulture));
  70. sw.Append("]");
  71. }
  72. public static void FormatGlobalSet<T>(GlobalVariableId<T> globalVariable, IJsmExpression value, int[] knownVariables, ScriptWriter sw, IScriptFormatterContext formatterContext, IServices executionContext) where T : unmanaged
  73. {
  74. sw.Append("G");
  75. if (knownVariables == null || Array.BinarySearch(knownVariables, globalVariable.VariableId) < 0)
  76. {
  77. sw.Append("[");
  78. sw.Append(globalVariable.VariableId.ToString(CultureInfo.InvariantCulture));
  79. sw.Append("]");
  80. sw.Append(" = ");
  81. sw.Append("(");
  82. sw.Append(GlobalVariableId<T>.TypeName);
  83. sw.Append(")");
  84. }
  85. else
  86. {
  87. sw.Append(GlobalVariableId<T>.TypeName);
  88. sw.Append("[");
  89. sw.Append(globalVariable.VariableId.ToString(CultureInfo.InvariantCulture));
  90. sw.Append("]");
  91. sw.Append(" = ");
  92. }
  93. value.Format(sw, formatterContext, executionContext);
  94. sw.AppendLine(";");
  95. }
  96. public static void FormatMonologue(ScriptWriter sw, string message)
  97. {
  98. if (!sw.HasWhiteLine)
  99. sw.AppendLine();
  100. foreach (var str in SplitMonologue(message))
  101. {
  102. if (string.IsNullOrEmpty(str))
  103. continue;
  104. sw.Append("// ");
  105. sw.AppendLine(str);
  106. }
  107. }
  108. public static string[] SplitMonologue(string message) => message.Split(Separators, StringSplitOptions.None);
  109. #endregion Methods
  110. #region Classes
  111. public sealed class Formatter
  112. {
  113. #region Constructors
  114. public Formatter(ScriptWriter sw, IScriptFormatterContext formatterContext, IServices executionContext)
  115. {
  116. Sw = sw;
  117. FormatterContext = formatterContext;
  118. ExecutionContext = executionContext;
  119. }
  120. #endregion Constructors
  121. #region Properties
  122. public IServices ExecutionContext { get; }
  123. public IScriptFormatterContext FormatterContext { get; }
  124. public ScriptWriter Sw { get; }
  125. #endregion Properties
  126. #region Methods
  127. public Formatter Await()
  128. {
  129. Sw.Append("await ");
  130. return this;
  131. }
  132. public Formatter CommentLine(string text)
  133. {
  134. if (!Sw.HasWhiteLine)
  135. Sw.AppendLine();
  136. Sw.Append("// ");
  137. Sw.AppendLine(text);
  138. return this;
  139. }
  140. public MethodFormatter Method(string methodName)
  141. {
  142. Sw.Append("this.");
  143. Sw.Append(methodName);
  144. Sw.Append("(");
  145. return new MethodFormatter(this);
  146. }
  147. public PropertyFormatter Property(string methodName)
  148. {
  149. Sw.Append("this.");
  150. Sw.Append(methodName);
  151. return new PropertyFormatter(this);
  152. }
  153. public StaticTypeFormatter StaticType(string typeName)
  154. {
  155. Sw.Append(typeName);
  156. return new StaticTypeFormatter(this);
  157. }
  158. #endregion Methods
  159. }
  160. public sealed class MethodFormatter
  161. {
  162. #region Fields
  163. private bool _hasArguments = false;
  164. #endregion Fields
  165. #region Constructors
  166. public MethodFormatter(Formatter formatter) => Formatter = formatter;
  167. #endregion Constructors
  168. #region Properties
  169. public Formatter Formatter { get; }
  170. #endregion Properties
  171. #region Methods
  172. public MethodFormatter Argument(string argumentName, int argumentValue) => Argument(argumentName, argumentValue.ToString(CultureInfo.InvariantCulture));
  173. public MethodFormatter Argument(string argumentName, bool argumentValue) => Argument(argumentName, argumentValue ? "true" : "false");
  174. public MethodFormatter Argument(string argumentName, IJsmExpression argumentExpression)
  175. {
  176. var sw = Formatter.Sw;
  177. if (_hasArguments)
  178. sw.Append(", ");
  179. if (argumentName != null)
  180. {
  181. sw.Append(argumentName);
  182. sw.Append(": ");
  183. }
  184. argumentExpression.Format(sw, Formatter.FormatterContext, Formatter.ExecutionContext);
  185. _hasArguments = true;
  186. return this;
  187. }
  188. public MethodFormatter Argument<T>(string argumentName, IJsmExpression argumentExpression)
  189. {
  190. var sw = Formatter.Sw;
  191. if (_hasArguments)
  192. sw.Append(", ");
  193. if (argumentName != null)
  194. {
  195. sw.Append(argumentName);
  196. sw.Append(": ");
  197. }
  198. sw.Append("(");
  199. sw.Append(typeof(T).Name);
  200. sw.Append(")");
  201. argumentExpression.Format(sw, Formatter.FormatterContext, Formatter.ExecutionContext);
  202. _hasArguments = true;
  203. return this;
  204. }
  205. public MethodFormatter Argument(string argumentValue)
  206. {
  207. var sw = Formatter.Sw;
  208. if (_hasArguments)
  209. sw.Append(", ");
  210. sw.Append(argumentValue);
  211. _hasArguments = true;
  212. return this;
  213. }
  214. public MethodFormatter Argument(string argumentName, string argumentValue)
  215. {
  216. var sw = Formatter.Sw;
  217. if (_hasArguments)
  218. sw.Append(", ");
  219. sw.Append(argumentName);
  220. sw.Append(": ");
  221. sw.Append(argumentValue);
  222. _hasArguments = true;
  223. return this;
  224. }
  225. public void Comment(string nativeName)
  226. {
  227. Formatter.Sw.Append("); // ");
  228. Formatter.Sw.AppendLine(nativeName);
  229. }
  230. public MethodFormatter Enum<T>(T argumentValue) where T : struct => Argument(typeof(T).Name + '.' + argumentValue);
  231. public MethodFormatter Enum<T>(IJsmExpression argumentExpression) where T : struct
  232. {
  233. if (argumentExpression is IConstExpression expr)
  234. return Argument(typeof(T).Name + '.' + (T)(object)expr.Int32());
  235. return Argument<T>(null, argumentExpression);
  236. }
  237. #endregion Methods
  238. }
  239. public sealed class PropertyFormatter
  240. {
  241. #region Constructors
  242. public PropertyFormatter(Formatter formatter) => Formatter = formatter;
  243. #endregion Constructors
  244. #region Properties
  245. public Formatter Formatter { get; }
  246. #endregion Properties
  247. #region Methods
  248. public PropertyFormatter Assign(bool value)
  249. {
  250. var sw = Formatter.Sw;
  251. sw.Append(" = ");
  252. sw.Append(value ? "true" : "false");
  253. sw.Append(";");
  254. return this;
  255. }
  256. public PropertyFormatter Assign(long value)
  257. {
  258. var sw = Formatter.Sw;
  259. sw.Append(" = ");
  260. sw.Append(value.ToString(CultureInfo.InvariantCulture));
  261. sw.Append(";");
  262. return this;
  263. }
  264. public PropertyFormatter Assign(IJsmExpression assignExpression)
  265. {
  266. var sw = Formatter.Sw;
  267. sw.Append(" = ");
  268. assignExpression.Format(sw, Formatter.FormatterContext, Formatter.ExecutionContext);
  269. sw.Append(";");
  270. return this;
  271. }
  272. public void Comment(string nativeName)
  273. {
  274. Formatter.Sw.Append(" // ");
  275. Formatter.Sw.AppendLine(nativeName);
  276. }
  277. public MethodFormatter Method(string methodName)
  278. {
  279. var sw = Formatter.Sw;
  280. sw.Append(".");
  281. sw.Append(methodName);
  282. sw.Append("(");
  283. return new MethodFormatter(Formatter);
  284. }
  285. public PropertyFormatter Property(string propertyName)
  286. {
  287. Formatter.Sw.Append(".");
  288. Formatter.Sw.Append(propertyName);
  289. return new PropertyFormatter(Formatter);
  290. }
  291. #endregion Methods
  292. }
  293. public sealed class StaticTypeFormatter
  294. {
  295. #region Constructors
  296. public StaticTypeFormatter(Formatter formatter) => Formatter = formatter;
  297. #endregion Constructors
  298. #region Properties
  299. public Formatter Formatter { get; }
  300. #endregion Properties
  301. #region Methods
  302. public MethodFormatter Method(string methodName)
  303. {
  304. var sw = Formatter.Sw;
  305. sw.Append(".");
  306. sw.Append(methodName);
  307. sw.Append("(");
  308. return new MethodFormatter(Formatter);
  309. }
  310. public PropertyFormatter Property(string propertyName)
  311. {
  312. Formatter.Sw.Append(".");
  313. Formatter.Sw.Append(propertyName);
  314. return new PropertyFormatter(Formatter);
  315. }
  316. #endregion Methods
  317. }
  318. #endregion Classes
  319. }
  320. }