using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; 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); } } [KeywordMethod(Token.Print)] private void Print() { console.Write(Expr().ToString()); } [KeywordMethod(Token.PrintL)] private void PrintL() { console.PrintSingleLine(Expr().ToString()); } [KeywordMethod(Token.PrintImg)] private void PrintImg() { console.PrintImg(Expr().ToString().Trim().Trim('"')); } [KeywordMethod(Token.PrintButton)] private void PrintButton() { console.PrintButton(Expr().ToString(), 0); } private static readonly Regex FormRegex = new Regex("{(.*?)}"); [KeywordMethod(Token.PrintFormL)] private void PrintFormL() { string rawString = Expr().ToString(); var evaluator = new MatchEvaluator(match => Variables[match.Groups[1].Value].ToString()); console.PrintSingleLine(FormRegex.Replace(rawString, evaluator)); } [KeywordMethod(Token.DrawLine)] private void DrawLine() { console.PrintBar(); } [KeywordMethod(Token.DrawLineForm)] private void DrawLineForm() { console.printCustomBar(Expr().ToString().Trim()); } [KeywordMethod(Token.If)] private void If() { bool result = Expr().Real == 1; AssertToken(Token.Then, false); GetNextToken(); if (result) { int i = ifcounter; while (true) { if (lastToken == Token.If) { i++; } else if (lastToken == Token.Else) { if (i == ifcounter) { GetNextToken(); return; } } else if (lastToken == Token.EndIf) { if (i == ifcounter) { GetNextToken(); return; } i--; } GetNextToken(); } } } [KeywordMethod(Token.Else)] private void Else() { int i = ifcounter; while (true) { if (lastToken == Token.If) { i++; } else if (lastToken == Token.EndIf) { if (i == ifcounter) { GetNextToken(); return; } i--; } GetNextToken(); } } [KeywordMethod(Token.EndIf)] private void EndIf() { } [KeywordMethod(Token.End)] private void End() { exit = true; } [KeywordMethod(Token.Let)] private void Let() { if (lastToken != Token.Equal) { AssertToken(Token.Identifer, false); AssertToken(Token.Equal); } string id = lex.Identifer; GetNextToken(); Variables[id] = Expr(); } [KeywordMethod(Token.For)] private void For() { AssertToken(Token.Identifer, false); string var = lex.Identifer; AssertToken(Token.Equal); GetNextToken(); Value v = Expr(); if (loops.ContainsKey(var)) { loops[var] = lineMarker; } else { Variables[var] = v; loops.Add(var, lineMarker); } AssertToken(Token.To, false); GetNextToken(); v = Expr(); if (Variables[var].Operate(v, Token.More).Real == 1) { while (true) { while (!(GetNextToken() == Token.Identifer && prevToken == Token.Next)) { } if (lex.Identifer == var) { loops.Remove(var); AssertToken(Token.NewLine); break; } } } } [KeywordMethod(Token.Next)] private void Next() { AssertToken(Token.Identifer, false); string var = lex.Identifer; Variables[var] = Variables[var].Operate(new Value(1), Token.Plus); lex.GoTo(new Marker(loops[var].Pointer - 1, loops[var].Line, loops[var].Column - 1)); lastToken = Token.NewLine; } [KeywordMethod(Token.Times)] private void Times() { AssertToken(Token.Identifer, false); string var = lex.Identifer; AssertToken(Token.Comma); GetNextToken(); var arg2 = Expr(); Variables[var] = Variables[var].Operate(arg2, Token.Asterisk); AssertToken(Token.NewLine, false); } } }