EP RScript
This commit is contained in:
11
PublicTypes/RScriptException.cs
Normal file
11
PublicTypes/RScriptException.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Convention.RScript
|
||||
{
|
||||
[Serializable]
|
||||
public class RScriptException : Exception
|
||||
{
|
||||
public RScriptException(string message, int runtimePointer) : base($"when running {runtimePointer}, {message}") { }
|
||||
public RScriptException(string message, int runtimePointer, Exception inner) : base($"when running {runtimePointer}, {message}", inner) { }
|
||||
}
|
||||
}
|
138
PublicTypes/RScriptImportClass.cs
Normal file
138
PublicTypes/RScriptImportClass.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Convention.RScript
|
||||
{
|
||||
public class RScriptImportClass : ICollection<Type>
|
||||
{
|
||||
private readonly HashSet<Type> importedTypes = new();
|
||||
private readonly Dictionary<string, List<MethodInfo>> cacheImportedFunctions = new();
|
||||
|
||||
public int Count => ((ICollection<Type>)importedTypes).Count;
|
||||
|
||||
public bool IsReadOnly => ((ICollection<Type>)importedTypes).IsReadOnly;
|
||||
|
||||
private void DoAdd(Type type)
|
||||
{
|
||||
foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
|
||||
{
|
||||
if (cacheImportedFunctions.ContainsKey(method.Name) == false)
|
||||
cacheImportedFunctions.Add(method.Name, new());
|
||||
cacheImportedFunctions[method.Name].Add(method);
|
||||
}
|
||||
}
|
||||
|
||||
public Type[] GetImports()
|
||||
{
|
||||
return importedTypes.ToArray();
|
||||
}
|
||||
|
||||
public int CountMethod(string methodName)
|
||||
{
|
||||
return cacheImportedFunctions.TryGetValue(methodName, out var list) ? list.Count : 0;
|
||||
}
|
||||
|
||||
public MethodInfo GetMethod(string methodName)
|
||||
{
|
||||
if (cacheImportedFunctions.TryGetValue(methodName, out var list))
|
||||
{
|
||||
if (list.Count != 1)
|
||||
{
|
||||
throw new AmbiguousMatchException($"Have more than one {methodName} is imported");
|
||||
}
|
||||
return list[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodInfo GetMethodByReturn(string methodName, Type returnType)
|
||||
{
|
||||
if (cacheImportedFunctions.TryGetValue(methodName, out var list))
|
||||
{
|
||||
var query = from item in list where item.ReturnType == returnType select item;
|
||||
if (query.Count() != 1)
|
||||
{
|
||||
throw new AmbiguousMatchException($"Have more than one {methodName} is imported");
|
||||
}
|
||||
return query.First();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodInfo GetMethod(string methodName, params Type[] parameters)
|
||||
{
|
||||
static bool Pr(Type[] parameters1, Type[] parameters2)
|
||||
{
|
||||
if (parameters1.Length != parameters2.Length)
|
||||
return false;
|
||||
for (int i = 0, e = parameters1.Length; i != e; i++)
|
||||
{
|
||||
if (parameters1[i] != parameters2[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cacheImportedFunctions.TryGetValue(methodName, out var list))
|
||||
{
|
||||
var query = from item in list
|
||||
where Pr((from _param in item.GetParameters() select _param.ParameterType).ToArray(), parameters)
|
||||
select item;
|
||||
if (query.Count() != 1)
|
||||
{
|
||||
throw new AmbiguousMatchException($"Have more than one {methodName} is imported");
|
||||
}
|
||||
return query.First();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool TryAdd(Type type)
|
||||
{
|
||||
var stats = importedTypes.Add(type);
|
||||
if (stats)
|
||||
{
|
||||
DoAdd(type);
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
public void Add(Type type)
|
||||
{
|
||||
TryAdd(type);
|
||||
}
|
||||
|
||||
public IEnumerator<Type> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<Type>)importedTypes).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)importedTypes).GetEnumerator();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
((ICollection<Type>)importedTypes).Clear();
|
||||
}
|
||||
|
||||
public bool Contains(Type item)
|
||||
{
|
||||
return ((ICollection<Type>)importedTypes).Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(Type[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<Type>)importedTypes).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(Type item)
|
||||
{
|
||||
return ((ICollection<Type>)importedTypes).Remove(item);
|
||||
}
|
||||
}
|
||||
}
|
151
PublicTypes/RScriptVariables.cs
Normal file
151
PublicTypes/RScriptVariables.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Convention.RScript
|
||||
{
|
||||
public struct RScriptVariableEntry
|
||||
{
|
||||
public Type type;
|
||||
public object data;
|
||||
}
|
||||
public class RScriptVariables : IDictionary<string, RScriptVariableEntry>
|
||||
{
|
||||
private readonly Dictionary<string, Stack<RScriptVariableEntry>> variables = new();
|
||||
|
||||
public RScriptVariableEntry this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return variables[key].Peek();
|
||||
}
|
||||
set
|
||||
{
|
||||
var current = variables[key].Peek();
|
||||
if (current.type != value.type)
|
||||
throw new ArgumentException($"current type is {current.type}, but setter.value is {value.type}");
|
||||
variables[key].Pop();
|
||||
variables[key].Push(value);
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<string> Keys => variables.Keys;
|
||||
|
||||
public ICollection<RScriptVariableEntry> Values => (from item in variables.Values select item.Peek()).ToArray();
|
||||
|
||||
public int Count => variables.Count;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public void Add(string key, RScriptVariableEntry value)
|
||||
{
|
||||
if (variables.ContainsKey(key) == false)
|
||||
variables.Add(key, new());
|
||||
variables[key].Push(value);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<string, RScriptVariableEntry> item)
|
||||
{
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
public void ClearAllLayers()
|
||||
{
|
||||
variables.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="ClearAllLayers"/>
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
ClearAllLayers();
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<string, RScriptVariableEntry> item)
|
||||
{
|
||||
if (variables.TryGetValue(item.Key, out var items))
|
||||
{
|
||||
var current = items.Peek();
|
||||
return current.data == item.Value.data;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return variables.ContainsKey(key);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<string, RScriptVariableEntry>[] array, int arrayIndex)
|
||||
{
|
||||
foreach (var (key, items) in variables)
|
||||
{
|
||||
array[arrayIndex++] = new(key, items.Peek());
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, RScriptVariableEntry>> GetEnumerator()
|
||||
{
|
||||
return (from items in variables select new KeyValuePair<string, RScriptVariableEntry>(items.Key, items.Value.Peek())).GetEnumerator();
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
if (variables.TryGetValue(key, out var items))
|
||||
{
|
||||
items.Pop();
|
||||
if (items.Count == 0)
|
||||
{
|
||||
variables.Remove(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<string, RScriptVariableEntry> item)
|
||||
{
|
||||
if (variables.TryGetValue(item.Key, out var items))
|
||||
{
|
||||
if (item.Value.data == items.Peek().data)
|
||||
{
|
||||
items.Pop();
|
||||
if (items.Count == 0)
|
||||
{
|
||||
variables.Remove(item.Key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetValue(string key, [MaybeNullWhen(false)] out RScriptVariableEntry value)
|
||||
{
|
||||
if (variables.TryGetValue(key, out var items))
|
||||
{
|
||||
value = items.Peek();
|
||||
return true;
|
||||
}
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void SetValue(string varName, object value)
|
||||
{
|
||||
var top = variables[varName].Pop();
|
||||
top.data = value;
|
||||
variables[varName].Push(top);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user