This commit is contained in:
ninemine
2025-07-02 13:11:26 +08:00
parent 4d49ab1990
commit d0dfe39fe9
6 changed files with 248 additions and 60 deletions

View File

@@ -52,7 +52,7 @@ namespace Convention.EasySave.Internal
// This obviously won't work if exceptions are disabled. // This obviously won't work if exceptions are disabled.
try try
{ {
//if (assemblyNames.Contains(assembly.GetName().Name)) //if (assemblyNames.Contains(assembly.GetName().StructureName))
assemblyList.Add(assembly); assemblyList.Add(assembly);
} }
catch { } catch { }

View File

@@ -1,21 +1,50 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Reflection;
using System.Threading.Tasks;
namespace Convention.Symbolization.Internal namespace Convention.Symbolization.Internal
{ {
public abstract class Function : Variable public abstract class Function : CloneableVariable<Function>
{ {
public readonly FunctionSymbol FunctionInfo; public readonly FunctionSymbol FunctionInfo;
public abstract Variable Invoke(Variable[] parameters);
public Function(string symbolName, Type returnType, Type[] parameterTypes, Modification[] modifiers) protected Function(string symbolName,string functionName, Type returnType, Type[] parameterTypes, Modification[] modifiers) : base(symbolName)
{ {
FunctionInfo = new(symbolName, returnType, parameterTypes, modifiers); FunctionInfo = new(functionName, returnType, parameterTypes, modifiers);
}
public abstract Variable Invoke(SymbolizationContext context, Variable[] parameters);
}
public sealed class DelegationalFunction : Function
{
public readonly MethodInfo methodInfo;
public DelegationalFunction(string symbolName, MethodInfo methodInfo)
: base(symbolName, methodInfo.Name, methodInfo.ReturnType, methodInfo.GetParameters().ToList().ConvertAll(x => x.ParameterType).ToArray(), Array.Empty<Modification>())
{
this.methodInfo = methodInfo!;
}
public override DelegationalFunction CloneVariable(string targetSymbolName)
{
return new DelegationalFunction(targetSymbolName, methodInfo);
}
public override bool Equals(Function other)
{
return other is DelegationalFunction df && df.methodInfo == this.methodInfo;
}
public override Variable Invoke(SymbolizationContext context, Variable[] parameters)
{
Variable invoker = parameters.Length > 0 ? parameters[0] : null;
Variable[] invokerParameters = parameters.Length > 0 ? parameters.Skip(1).ToArray() : Array.Empty<Variable>();
object result = methodInfo.Invoke(invoker, invokerParameters);
return result as Variable;
} }
} }
public readonly struct FunctionSymbol public readonly struct FunctionSymbol
{ {
public readonly string FunctionName; public readonly string FunctionName;

View File

@@ -4,18 +4,60 @@ using System.Linq;
namespace Convention.Symbolization.Internal namespace Convention.Symbolization.Internal
{ {
public sealed class Namespace : Variable<Namespace> public sealed class Namespace : Variable<Namespace>, ICanFindVariable
{ {
public Dictionary<string, Namespace> SubNamespaces = new(); private int Updateable = 0;
public Dictionary<FunctionSymbol, Function> Functions = new();
public Dictionary<string, Structure> Structures = new(); public void BeginUpdate()
{
Updateable++;
}
private readonly Dictionary<string, Namespace> SubNamespaces = new();
private readonly Dictionary<FunctionSymbol, Function> Functions = new();
private readonly Dictionary<string, Structure> Structures = new();
public Namespace CreateOrGetSubNamespace(string subNamespace)
{
if (Updateable == 0)
throw new InvalidOperationException("Cannot create sub-namespace outside of an update block.");
if(!SubNamespaces.TryGetValue(subNamespace,out var result))
{
result = new Namespace(subNamespace);
SubNamespaces[subNamespace] = result;
}
return result;
}
public void AddFunction(Function function)
{
if (Updateable == 0)
throw new InvalidOperationException("Cannot add function outside of an update block.");
ArgumentNullException.ThrowIfNull(function);
Functions.Add(function.FunctionInfo, function);
}
public void AddStructure(Structure structure)
{
if (Updateable == 0)
throw new InvalidOperationException("Cannot add structure outside of an update block.");
ArgumentNullException.ThrowIfNull(structure);
Structures.Add(structure.SymbolInfo.SymbolName, structure);
}
public void EndAndApplyUpdate()
{
Updateable--;
if (Updateable == 0)
Refresh();
}
private readonly Dictionary<string, int> SymbolCounter = new(); private readonly Dictionary<string, int> SymbolCounter = new();
private readonly Dictionary<string, List<Variable>> Symbol2Variable = new(); private readonly Dictionary<string, List<Variable>> Symbol2Variable = new();
public void Refresh() public void Refresh()
{ {
// Refresh SymbolCounter // Refresh Symbols
SymbolCounter.Clear(); SymbolCounter.Clear();
foreach (var ns in SubNamespaces) foreach (var ns in SubNamespaces)
{ {
@@ -27,30 +69,52 @@ namespace Convention.Symbolization.Internal
else else
SymbolCounter[symbol.Key] = symbol.Value; SymbolCounter[symbol.Key] = symbol.Value;
} }
foreach (var symbol in ns.Value.Symbol2Variable)
{
if (Symbol2Variable.TryGetValue(symbol.Key, out List<Variable> value))
value.AddRange(symbol.Value);
else
Symbol2Variable[symbol.Key] = new(symbol.Value);
}
} }
foreach (var func in Functions) foreach (var func in Functions)
{ {
if (SymbolCounter.ContainsKey(func.Key.FunctionName)) {
SymbolCounter[func.Key.FunctionName]++; if (SymbolCounter.TryGetValue(func.Key.FunctionName, out var value))
SymbolCounter[func.Key.FunctionName] = ++value;
else else
SymbolCounter[func.Key.FunctionName] = 1; SymbolCounter[func.Key.FunctionName] = 1;
} }
{
if (Symbol2Variable.TryGetValue(func.Key.FunctionName, out var value))
value.Add(func.Value);
else
Symbol2Variable[func.Key.FunctionName] = new() { func.Value };
}
{
if (Symbol2Variable.TryGetValue(func.Key.FunctionName, out var value))
value.Add(func.Value);
else
Symbol2Variable[func.Key.FunctionName] = new() { func.Value };
}
}
foreach (var @struct in Structures) foreach (var @struct in Structures)
{ {
if (SymbolCounter.ContainsKey(@struct.Key)) {
SymbolCounter[@struct.Key]++; if (SymbolCounter.TryGetValue(@struct.Key, out int value))
SymbolCounter[@struct.Key] = ++value;
else else
SymbolCounter[@struct.Key] = 1; SymbolCounter[@struct.Key] = 1;
} }
{
if (Symbol2Variable.TryGetValue(@struct.Key, out List<Variable> value))
value.Add(@struct.Value);
else
Symbol2Variable[@struct.Key] = new() { @struct.Value };
}
}
} }
public static Namespace CreateOrGetSubNamespace(string namespaceName, Namespace parent)
{
if (parent.SubNamespaces.TryGetValue(namespaceName, out var sub))
return sub;
parent.SubNamespaces[namespaceName] = new(namespaceName);
return parent.SubNamespaces[namespaceName];
}
public static Namespace CreateRootNamespace() public static Namespace CreateRootNamespace()
{ {
return new("global"); return new("global");
@@ -81,5 +145,40 @@ namespace Convention.Symbolization.Internal
return Array.Empty<Variable>(); return Array.Empty<Variable>();
return result.ToArray(); return result.ToArray();
} }
public Namespace FindSubNamespace(string subNamespaceName)
{
if (!SubNamespaces.TryGetValue(subNamespaceName, out var result))
return null;
return result;
}
public Function[] FindFunction(string symbolName)
{
if (!Symbol2Variable.TryGetValue(symbolName, out var result))
return Array.Empty<Function>();
return result.OfType<Function>().ToArray();
}
public Function FindFunctionInNamespace(FunctionSymbol symbol)
{
if (!Functions.TryGetValue(symbol, out var result))
return null;
return result;
}
public Structure[] FindStructure(string symbolName)
{
if (!Symbol2Variable.TryGetValue(symbolName, out var result))
return Array.Empty<Structure>();
return result.OfType<Structure>().ToArray();
}
public Structure FindStructureInNamespace(string symbolName)
{
if (!Structures.TryGetValue(symbolName, out var result))
return null;
return result;
}
} }
} }

View File

@@ -6,39 +6,82 @@ using System.Threading.Tasks;
namespace Convention.Symbolization.Internal namespace Convention.Symbolization.Internal
{ {
public sealed class Structure : Variable public sealed class Structure : Variable<Structure>, ICanFindVariable
{ {
public readonly string Name; private Dictionary<string, Variable> MemberFields;
private Dictionary<VariableSymbol, Variable> VariableSymbolAndDefaultValue; public readonly Namespace ParentNamespace;
private Structure(string name) public Dictionary<string, Variable> CloneMemberFields()
{ {
this.Name = name; return new(from pair in MemberFields
} select new KeyValuePair<string, Variable>(
public Structure(string name, Dictionary<VariableSymbol, Variable> variableSymbolAndDefaultValue) pair.Key,
{ pair.Value is ICloneable cloneable ? (cloneable.Clone() as Variable) : pair.Value)
this.Name = name; );
this.VariableSymbolAndDefaultValue = variableSymbolAndDefaultValue;
} }
public override object Clone() private Structure(string symbolName, Namespace parentNamespace) : base(symbolName)
{ {
Structure target = new(Name); this.ParentNamespace = parentNamespace;
foreach (var pair in VariableSymbolAndDefaultValue)
{
target.VariableSymbolAndDefaultValue[pair.Key] = pair.Value;
}
return target;
} }
public bool Equals(Structure other) public static Structure Create(string structureName, Namespace parent)
{ {
return Name.Equals(other.Name); Structure result = new(structureName, parent);
parent.AddStructure(result);
return result;
} }
public override int GetHashCode() public override bool Equals(Structure other)
{ {
return Name.GetHashCode(); return this == other;
}
public Variable[] Find(string symbolName)
{
if (MemberFields.TryGetValue(symbolName, out var variable))
{
return new[] { variable };
}
return Array.Empty<Variable>();
}
}
public sealed class StructureInstance : CloneableVariable<StructureInstance>,ICanFindVariable
{
public readonly Structure StructureType;
private readonly Dictionary<string, Variable> MemberFields;
public StructureInstance(string symbolName, Structure structureType)
: base(symbolName)
{
this.StructureType = structureType;
this.MemberFields = structureType.CloneMemberFields();
}
public override bool Equals(StructureInstance other)
{
return this == other;
}
public override StructureInstance CloneVariable(string targetSymbolName)
{
return new StructureInstance(targetSymbolName, this.StructureType);
}
public Variable GetField(string memberName)
{
if (MemberFields.TryGetValue(memberName, out var result))
return result;
else
throw new KeyNotFoundException($"Member '{memberName}' not found in structure '{StructureType.SymbolInfo.SymbolName}'.");
}
public Variable[] Find(string symbolName)
{
if (MemberFields.TryGetValue(symbolName, out var variable))
{
return new[] { variable };
}
return Array.Empty<Variable>();
} }
} }
} }

View File

@@ -51,21 +51,38 @@ namespace Convention.Symbolization.Internal
} }
} }
public interface ICanFindVariable
{
public Variable[] Find(string symbolName);
}
public abstract class CloneableVariable<T> : Variable<T>, ICloneable public abstract class CloneableVariable<T> : Variable<T>, ICloneable
{ {
protected CloneableVariable(string symbolName, Type variableType) : base(symbolName) protected CloneableVariable(string symbolName) : base(symbolName)
{ {
} }
protected CloneableVariable(string symbolName, CloneableVariable<T> variable) : base(symbolName) public object Clone() => CloneVariable(SymbolInfo.SymbolName);
public abstract T CloneVariable(string targetSymbolName);
}
public sealed class NullVariable : CloneableVariable<NullVariable>
{
public NullVariable(string symbolName) : base(symbolName)
{ {
} }
public object Clone() => CloneVariable(); public override NullVariable CloneVariable(string targetSymbolName)
{
public abstract T CloneVariable(); return new(targetSymbolName);
} }
public override bool Equals(NullVariable other)
{
return true;
}
}
public readonly struct VariableSymbol public readonly struct VariableSymbol
{ {

View File

@@ -18,7 +18,7 @@ namespace Convention.Symbolization
public SymbolizationRunner(SymbolizationContext context) public SymbolizationRunner(SymbolizationContext context)
{ {
GlobalNamespace = new(); GlobalNamespace = Internal.Namespace.CreateRootNamespace();
Context = context; Context = context;
} }
public SymbolizationRunner() :this(new()){ } public SymbolizationRunner() :this(new()){ }