using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace NTERA.Interpreter { public partial class Interpreter { private void GenerateFunctionDictionary() { FunctionDictionary = new Dictionary(StringComparer.InvariantCultureIgnoreCase); foreach (var method in typeof(Interpreter).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { var attribute = (BuiltInFunctionAttribute)method.GetCustomAttributes(typeof(BuiltInFunctionAttribute), true).FirstOrDefault(); if (attribute == null) continue; FunctionDictionary[attribute.Name] = args => (Value)method.Invoke(this, new object[] { args }); } } [BuiltInFunction("abs")] private Value Abs(List args) { if (args.Count != 1) throw new ArgumentException(); return new Value(Math.Abs(args[0].Real)); } [BuiltInFunction("min")] private Value Min(List args) { if (args.Count != 2) throw new ArgumentException(); return new Value(Math.Min(args[0].Real, args[1].Real)); } [BuiltInFunction("max")] private Value Max(List args) { if (args.Count != 2) throw new ArgumentException(); return new Value(Math.Max(args[0].Real, args[1].Real)); } [BuiltInFunction("not")] private Value Not(List args) { if (args.Count != 1) throw new ArgumentException(); return new Value(args[0].Real == 0 ? 1 : 0); } private readonly Random random = new Random(); [BuiltInFunction("rand")] private Value Rand(List args) { if (args.Count != 2) throw new ArgumentException(); return new Value(random.Next((int)args[0].Real, (int)args[1].Real - 1)); } [BuiltInFunction("tostr")] private Value ToStr(List args) { if (args.Count != 2) throw new ArgumentException(); return ((int)args[0].Real).ToString(args[1].String); } } }