using Serein.Library; using Serein.Script.Node; using Serein.Script.Node.FlowControl; using System.Reflection; namespace Serein.Script { /// /// Serein 脚本引擎 /// public class SereinScript { /// /// 类型分析 /// public SereinScriptTypeAnalysis TypeAnalysis { get; } = new SereinScriptTypeAnalysis(); /// /// 程序起始节点 /// private ProgramNode? programNode; /// /// 执行脚本(静态方法) /// /// /// /// public static Task ExecuteAsync(string script, Dictionary? argTypes = null) { SereinScriptParser parser = new SereinScriptParser(); SereinScriptTypeAnalysis analysis = new SereinScriptTypeAnalysis(); var programNode = parser.Parse(script); analysis.Reset(); if (argTypes is not null) analysis.LoadSymbol(argTypes); // 提前加载脚本节点定义的符号 analysis.Analysis(programNode); // 分析节点类型 SereinScriptInterpreter Interpreter = new SereinScriptInterpreter(analysis.NodeSymbolInfos); IScriptInvokeContext context = new ScriptInvokeContext(); var task = Interpreter.InterpreterAsync(context, programNode); return task; // 脚本返回类型 } /// /// 解析脚本 /// /// 脚本 /// 挂载的变量 /// public Type ParserScript(string script, Dictionary? argTypes = null) { SereinScriptParser parser = new SereinScriptParser(); var programNode = parser.Parse(script); TypeAnalysis.NodeSymbolInfos.Clear(); // 清空符号表 if(argTypes is not null) TypeAnalysis.LoadSymbol(argTypes); // 提前加载脚本节点定义的符号 TypeAnalysis.Analysis(programNode); // 分析节点类型 var returnType = TypeAnalysis.NodeSymbolInfos[programNode]; // 获取返回类型 this.programNode = programNode; return returnType; // 脚本返回类型 } /// /// 执行脚本 /// /// /// public async Task InterpreterAsync() { IScriptInvokeContext context = new ScriptInvokeContext(); if (programNode is null) { throw new ArgumentNullException(nameof(programNode)); } Dictionary symbolInfos = TypeAnalysis.NodeSymbolInfos.ToDictionary(); SereinScriptInterpreter Interpreter = new SereinScriptInterpreter(symbolInfos); return await Interpreter.InterpreterAsync(context, programNode); } /// /// 执行脚本 /// /// /// /// public async Task InterpreterAsync(IScriptInvokeContext context) { if(programNode is null) { throw new ArgumentNullException(nameof(programNode)); } Dictionary symbolInfos = TypeAnalysis.NodeSymbolInfos.ToDictionary(); SereinScriptInterpreter Interpreter = new SereinScriptInterpreter(symbolInfos); return await Interpreter.InterpreterAsync(context, programNode); } /// /// 转换为 C# 代码,并且附带方法信息 /// /// 脚本 /// 挂载的变量 /// public SereinScriptMethodInfo? ConvertCSharpCode(string mehtodName, Dictionary? argTypes = null) { if (string.IsNullOrWhiteSpace(mehtodName)) return null; if (programNode is null) return null; SereinScriptToCsharpScript tool = new SereinScriptToCsharpScript(TypeAnalysis); return tool.CompileToCSharp(mehtodName, programNode, argTypes); } /// /// 编译为 IL 代码 /// /// 脚本 /// 挂载的变量 /// [Obsolete("因为暂未想到如何支持异步方法,所以暂时废弃生成", true)] private Delegate CompilerIL(string dynamicMethodName, ProgramNode programNode, Dictionary? argTypes = null) { SereinScriptILCompiler compiler = new SereinScriptILCompiler(TypeAnalysis.NodeSymbolInfos); var @delegate = compiler.Compiler(dynamicMethodName, programNode, argTypes); // 编译脚本 return @delegate; } /// /// 挂载的函数 /// public static Dictionary FunctionDelegates { get; private set; } = []; /// /// 挂载方法的信息 /// public static Dictionary FunctionInfos { get; private set; } = []; /// /// 挂载的类型 /// public static Dictionary MountType = new Dictionary(); /// /// 挂载的函数调用的对象(用于解决函数需要实例才能调用的场景) /// // public static Dictionary> DelegateInstances = new Dictionary>(); /// /// 挂载函数 /// /// /// public static void AddStaticFunction(string functionName, MethodInfo methodInfo) { FunctionDelegates[functionName] = new DelegateDetails(methodInfo); FunctionInfos[functionName] = methodInfo; } /// /// 挂载函数 /// /// 函数名称 /// 方法信息 /*public static void AddFunction(string functionName, MethodInfo methodInfo, Func? callObj = null) { if (!methodInfo.IsStatic && callObj is null) { SereinEnv.WriteLine(InfoType.WARN, "函数挂载失败:试图挂载非静态的函数,但没有传入相应的获取实例的方法。"); return; } if (!methodInfo.IsStatic && callObj is not null && !DelegateInstances.ContainsKey(functionName)) { // 非静态函数需要给定类型 DelegateInstances.Add(functionName, callObj); } if (!FunctionDelegates.ContainsKey(functionName)) { FunctionDelegates[functionName] = new DelegateDetails(methodInfo); } }*/ /// /// 挂载类型 /// /// 类型 /// 指定类型名称 public static void AddClassType(Type type, string typeName = "") { if (string.IsNullOrEmpty(typeName)) { typeName = type.Name; } if (!MountType.ContainsKey(typeName)) { MountType[typeName] = type; } } } }