using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using NTERA.Core.Interop; namespace NTERA.Interpreter { public partial class Interpreter { private void GenerateKeywordDictionary() { KeywordMethods = new Dictionary(); foreach (var method in typeof(Interpreter).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { var attribute = method.GetCustomAttributes(typeof(KeywordMethodAttribute), true).FirstOrDefault() as KeywordMethodAttribute; if (attribute == null) continue; KeywordMethods[attribute.Token] = () => method.Invoke(this, null); } } #region Printing [KeywordMethod(Token.Print)] private void Print() { console.Write(RealExpression().ToString()); } [KeywordMethod(Token.PrintL)] private void PrintL() { console.PrintSingleLine(ParseFormat(Expression(new Lexer(Lexer.Value, LexerType.String), type: LexerType.String))); GetNextToken(); } [KeywordMethod(Token.PrintHtml)] private void PrintHtml() { AssertToken(Token.Value, false); console.PrintHtml(ParseFormat(Expression(new Lexer(Lexer.Value, LexerType.String), type: LexerType.String)), true); GetNextToken(); } [KeywordMethod(Token.PrintImg)] private void PrintImg() { console.PrintImg(RealExpression().ToString().Trim().Trim('"')); } [KeywordMethod(Token.PrintButton)] private void PrintButton() { string text = Lexer.Value; AssertToken(Token.Comma); GetNextToken(); var value = RealExpression(); console.PrintButton(text, (long)value.Real); } private static readonly Regex RealFormatRegex = new Regex("{(.*?)}"); private static readonly Regex StringFormatRegex = new Regex("%(.*?)%"); private string ParseFormat(string rawInput) { var realEvaluator = new MatchEvaluator(match => Expression(new Lexer(match.Groups[1].Value)).ToString()); string reals = RealFormatRegex.Replace(rawInput, realEvaluator); return StringFormatRegex.Replace(reals, realEvaluator); } [KeywordMethod(Token.PrintForm)] private void PrintForm() { AssertToken(Token.Value, false); console.Write(ParseFormat(Lexer.Value)); GetNextToken(); } [KeywordMethod(Token.PrintFormL)] private void PrintFormL() { AssertToken(Token.Value, false); console.PrintSingleLine(ParseFormat(Lexer.Value)); GetNextToken(); } [KeywordMethod(Token.DrawLine)] private void DrawLine() { console.PrintBar(); } [KeywordMethod(Token.DrawLineForm)] private void DrawLineForm() { console.printCustomBar(RealExpression().ToString().Trim()); } [KeywordMethod(Token.CustomDrawLine)] private void CustomDrawLine() { console.printCustomBar(RealExpression().ToString().Trim()); } [KeywordMethod(Token.Alignment)] private void Alignment() { AssertToken(Token.Value, false); console.Alignment = (DisplayLineAlignment)Enum.Parse(typeof(DisplayLineAlignment), Lexer.Value); GetNextToken(); } [KeywordMethod(Token.SetColor)] private void SetColor() { if (TryAssertToken(Token.Identifer, false)) { int argb = (int)((int)RealExpression().Real | 0xFF000000); Color c = Color.FromArgb(argb); console.SetStringStyle(c); return; } AssertToken(Token.Value, false); if (TryAssertToken(Token.Comma)) { int r = (int)Lexer.Value.Real; AssertToken(Token.Value); int g = (int)Lexer.Value; AssertToken(Token.Comma); AssertToken(Token.Value); int b = (int)Lexer.Value; console.SetStringStyle(Color.FromArgb(r, g, b)); GetNextToken(); } else { int argb = (int)((int)Lexer.Value.Real | 0xFF000000); Color c = Color.FromArgb(argb); console.SetStringStyle(c); } } [KeywordMethod(Token.ResetColor)] private void ResetColor() { console.ResetStyle(); GetNextToken(); } #endregion #region Control [KeywordMethod(Token.If)] private void If() { bool result = RealExpression(); //needs to be redone } [KeywordMethod(Token.Else)] private void Else() { //needs to be redone } [KeywordMethod(Token.EndIf)] private void EndIf() { } [KeywordMethod(Token.End)] private void End() { exit = true; } [KeywordMethod(Token.Let)] private void Let() { int arrayIndex = 0; bool appending = false; if (CurrentToken == Token.Colon) { GetNextToken(); if (CurrentToken == Token.Value) arrayIndex = (int)Lexer.Value.Real; else { arrayIndex = (int)RealExpression(Lexer.Identifer).Real; } GetNextToken(); } if (CurrentToken == Token.Append) { appending = true; } else { AssertToken(Token.Equal, false); } string id = Lexer.Identifer; var typeHint = Variables[id].Type; Value value; if (typeHint == ValueType.Real) { GetNextToken(); value = RealExpression(); } else value = StringExpression(); if (appending) Variables[id, arrayIndex] += value; else Variables[id, arrayIndex] = value; } [KeywordMethod(Token.For)] private void For() { AssertToken(Token.Identifer, false); string var = Lexer.Identifer; AssertToken(Token.Equal); GetNextToken(); Value v = RealExpression(); if (Loops.ContainsKey(var)) { Loops[var] = lineMarker; } else { Variables[var] = v; Loops.Add(var, lineMarker); } AssertToken(Token.To, false); GetNextToken(); v = RealExpression(); if (Variables[var].Operate(v, Token.More).Real == 1) { while (true) { while (!(GetNextToken() == Token.Identifer && prevToken == Token.Next)) { } if (Lexer.Identifer == var) { Loops.Remove(var); AssertToken(Token.NewLine); break; } } } } [KeywordMethod(Token.Next)] private void Next() { AssertToken(Token.Identifer, false); string var = Lexer.Identifer; Variables[var] = Variables[var].Operate(new Value(1), Token.Plus); Lexer.GoTo(new Marker(Loops[var].Pointer - 1, Loops[var].Line, Loops[var].Column - 1)); } [KeywordMethod(Token.Times)] private void Times() { AssertToken(Token.Identifer, false); string var = Lexer.Identifer; AssertToken(Token.Comma); GetNextToken(); var arg2 = RealExpression(); Variables[var] = Variables[var].Operate(arg2, Token.Asterisk); } #endregion #region Global [KeywordMethod(Token.Global)] void Global() { if (TryAssertToken(Token.Dim, false)) { if (TryAssertToken(Token.Const)) { GetNextToken(); } AssertToken(Token.Identifer, false); string identifier = Lexer.Identifer; AssertToken(Token.Equal); GetNextToken(); Variables[identifier] = Lexer.Value; GetNextToken(); return; } throw new Exception("Unknown global evalution"); } #endregion } }