Keywords.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text.RegularExpressions;
  7. using NTERA.Core.Interop;
  8. namespace NTERA.Interpreter
  9. {
  10. public partial class Interpreter
  11. {
  12. private void GenerateKeywordDictionary()
  13. {
  14. KeywordMethods = new Dictionary<Token, Action>();
  15. foreach (var method in typeof(Interpreter).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
  16. {
  17. var attribute = method.GetCustomAttributes(typeof(KeywordMethodAttribute), true).FirstOrDefault() as KeywordMethodAttribute;
  18. if (attribute == null)
  19. continue;
  20. KeywordMethods[attribute.Token] = () => method.Invoke(this, null);
  21. }
  22. }
  23. #region Printing
  24. [KeywordMethod(Token.Print)]
  25. private void Print()
  26. {
  27. console.Write(RealExpression().ToString());
  28. }
  29. [KeywordMethod(Token.PrintL)]
  30. private void PrintL()
  31. {
  32. console.PrintSingleLine(ParseFormat(StringExpression(new Lexer(Lexer.Value, LexerType.String))));
  33. GetNextToken();
  34. }
  35. [KeywordMethod(Token.PrintHtml)]
  36. private void PrintHtml()
  37. {
  38. AssertToken(Token.Value, false);
  39. console.PrintHtml(ParseFormat(StringExpression(new Lexer(Lexer.Value, LexerType.String))), true);
  40. GetNextToken();
  41. }
  42. [KeywordMethod(Token.PrintImg)]
  43. private void PrintImg()
  44. {
  45. console.PrintImg(RealExpression().ToString().Trim().Trim('"'));
  46. }
  47. [KeywordMethod(Token.PrintButton)]
  48. private void PrintButton()
  49. {
  50. string text = Lexer.Value;
  51. AssertToken(Token.Comma);
  52. GetNextToken();
  53. var value = RealExpression();
  54. console.PrintButton(text, (long)value.Real);
  55. }
  56. private static readonly Regex RealFormatRegex = new Regex("{(.*?)}");
  57. private static readonly Regex StringFormatRegex = new Regex("%(.*?)%");
  58. private string ParseFormat(string rawInput)
  59. {
  60. var realEvaluator = new MatchEvaluator(match => RealExpression(new Lexer(match.Groups[1].Value)).ToString());
  61. string reals = RealFormatRegex.Replace(rawInput, realEvaluator);
  62. return StringFormatRegex.Replace(reals, realEvaluator);
  63. }
  64. [KeywordMethod(Token.PrintForm)]
  65. private void PrintForm()
  66. {
  67. AssertToken(Token.Value, false);
  68. console.Write(ParseFormat(Lexer.Value));
  69. GetNextToken();
  70. }
  71. [KeywordMethod(Token.PrintFormL)]
  72. private void PrintFormL()
  73. {
  74. AssertToken(Token.Value, false);
  75. console.PrintSingleLine(ParseFormat(Lexer.Value));
  76. GetNextToken();
  77. }
  78. [KeywordMethod(Token.DrawLine)]
  79. private void DrawLine()
  80. {
  81. console.PrintBar();
  82. }
  83. [KeywordMethod(Token.DrawLineForm)]
  84. private void DrawLineForm()
  85. {
  86. console.printCustomBar(RealExpression().ToString().Trim());
  87. }
  88. [KeywordMethod(Token.CustomDrawLine)]
  89. private void CustomDrawLine()
  90. {
  91. console.printCustomBar(RealExpression().ToString().Trim());
  92. }
  93. [KeywordMethod(Token.Alignment)]
  94. private void Alignment()
  95. {
  96. AssertToken(Token.Value, false);
  97. console.Alignment = (DisplayLineAlignment)Enum.Parse(typeof(DisplayLineAlignment), Lexer.Value);
  98. GetNextToken();
  99. }
  100. [KeywordMethod(Token.SetColor)]
  101. private void SetColor()
  102. {
  103. if (TryAssertToken(Token.Identifer, false))
  104. {
  105. int argb = (int)((int)RealExpression().Real | 0xFF000000);
  106. Color c = Color.FromArgb(argb);
  107. console.SetStringStyle(c);
  108. return;
  109. }
  110. AssertToken(Token.Value, false);
  111. if (TryAssertToken(Token.Comma))
  112. {
  113. int r = (int)Lexer.Value.Real;
  114. AssertToken(Token.Value);
  115. int g = (int)Lexer.Value;
  116. AssertToken(Token.Comma);
  117. AssertToken(Token.Value);
  118. int b = (int)Lexer.Value;
  119. console.SetStringStyle(Color.FromArgb(r, g, b));
  120. GetNextToken();
  121. }
  122. else
  123. {
  124. int argb = (int)((int)Lexer.Value.Real | 0xFF000000);
  125. Color c = Color.FromArgb(argb);
  126. console.SetStringStyle(c);
  127. }
  128. }
  129. [KeywordMethod(Token.ResetColor)]
  130. private void ResetColor()
  131. {
  132. console.ResetStyle();
  133. GetNextToken();
  134. }
  135. #endregion
  136. #region Control
  137. [KeywordMethod(Token.If)]
  138. private void If()
  139. {
  140. bool result = RealExpression().Real == 1;
  141. AssertToken(Token.Then, false);
  142. GetNextToken();
  143. if (result)
  144. {
  145. int i = ifcounter;
  146. while (true)
  147. {
  148. if (CurrentToken == Token.If)
  149. {
  150. i++;
  151. }
  152. else if (CurrentToken == Token.Else)
  153. {
  154. if (i == ifcounter)
  155. {
  156. GetNextToken();
  157. return;
  158. }
  159. }
  160. else if (CurrentToken == Token.EndIf)
  161. {
  162. if (i == ifcounter)
  163. {
  164. GetNextToken();
  165. return;
  166. }
  167. i--;
  168. }
  169. GetNextToken();
  170. }
  171. }
  172. }
  173. [KeywordMethod(Token.Else)]
  174. private void Else()
  175. {
  176. int i = ifcounter;
  177. while (true)
  178. {
  179. if (CurrentToken == Token.If)
  180. {
  181. i++;
  182. }
  183. else if (CurrentToken == Token.EndIf)
  184. {
  185. if (i == ifcounter)
  186. {
  187. GetNextToken();
  188. return;
  189. }
  190. i--;
  191. }
  192. GetNextToken();
  193. }
  194. }
  195. [KeywordMethod(Token.EndIf)]
  196. private void EndIf()
  197. {
  198. }
  199. [KeywordMethod(Token.End)]
  200. private void End()
  201. {
  202. exit = true;
  203. }
  204. [KeywordMethod(Token.Let)]
  205. private void Let()
  206. {
  207. int arrayIndex = 0;
  208. bool appending = false;
  209. if (CurrentToken == Token.Colon)
  210. {
  211. GetNextToken();
  212. if (CurrentToken == Token.Value)
  213. arrayIndex = (int)Lexer.Value.Real;
  214. else
  215. {
  216. arrayIndex = (int)RealExpression(Lexer.Identifer).Real;
  217. }
  218. GetNextToken();
  219. }
  220. if (CurrentToken == Token.Append)
  221. {
  222. appending = true;
  223. }
  224. else
  225. {
  226. AssertToken(Token.Equal, false);
  227. }
  228. string id = Lexer.Identifer;
  229. var typeHint = Variables[id].Type;
  230. Value value;
  231. if (typeHint == ValueType.Real)
  232. {
  233. GetNextToken();
  234. value = RealExpression();
  235. }
  236. else
  237. value = StringExpression();
  238. if (appending)
  239. Variables[id, arrayIndex] += value;
  240. else
  241. Variables[id, arrayIndex] = value;
  242. }
  243. [KeywordMethod(Token.For)]
  244. private void For()
  245. {
  246. AssertToken(Token.Identifer, false);
  247. string var = Lexer.Identifer;
  248. AssertToken(Token.Equal);
  249. GetNextToken();
  250. Value v = RealExpression();
  251. if (Loops.ContainsKey(var))
  252. {
  253. Loops[var] = lineMarker;
  254. }
  255. else
  256. {
  257. Variables[var] = v;
  258. Loops.Add(var, lineMarker);
  259. }
  260. AssertToken(Token.To, false);
  261. GetNextToken();
  262. v = RealExpression();
  263. if (Variables[var].Operate(v, Token.More).Real == 1)
  264. {
  265. while (true)
  266. {
  267. while (!(GetNextToken() == Token.Identifer && prevToken == Token.Next)) { }
  268. if (Lexer.Identifer == var)
  269. {
  270. Loops.Remove(var);
  271. AssertToken(Token.NewLine);
  272. break;
  273. }
  274. }
  275. }
  276. }
  277. [KeywordMethod(Token.Next)]
  278. private void Next()
  279. {
  280. AssertToken(Token.Identifer, false);
  281. string var = Lexer.Identifer;
  282. Variables[var] = Variables[var].Operate(new Value(1), Token.Plus);
  283. Lexer.GoTo(new Marker(Loops[var].Pointer - 1, Loops[var].Line, Loops[var].Column - 1));
  284. }
  285. [KeywordMethod(Token.Times)]
  286. private void Times()
  287. {
  288. AssertToken(Token.Identifer, false);
  289. string var = Lexer.Identifer;
  290. AssertToken(Token.Comma);
  291. GetNextToken();
  292. var arg2 = RealExpression();
  293. Variables[var] = Variables[var].Operate(arg2, Token.Asterisk);
  294. }
  295. #endregion
  296. #region Global
  297. [KeywordMethod(Token.Global)]
  298. void Global()
  299. {
  300. if (TryAssertToken(Token.Dim, false))
  301. {
  302. if (TryAssertToken(Token.Const))
  303. {
  304. GetNextToken();
  305. }
  306. AssertToken(Token.Identifer, false);
  307. string identifier = Lexer.Identifer;
  308. AssertToken(Token.Equal);
  309. GetNextToken();
  310. Variables[identifier] = Lexer.Value;
  311. GetNextToken();
  312. return;
  313. }
  314. throw new Exception("Unknown global evalution");
  315. }
  316. #endregion
  317. }
  318. }