新增赋值操作
This commit is contained in:
68
ExpressionElements/Assignment.cs
Normal file
68
ExpressionElements/Assignment.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Flee.ExpressionElements.Base;
|
||||
using Flee.ExpressionElements.MemberElements;
|
||||
using Flee.InternalTypes;
|
||||
using Flee.PublicTypes;
|
||||
|
||||
namespace Flee.ExpressionElements
|
||||
{
|
||||
internal class AssignmentElement : ExpressionElement
|
||||
{
|
||||
private readonly string _variableName;
|
||||
private readonly ExpressionElement _valueExpression;
|
||||
private readonly ExpressionContext _context;
|
||||
|
||||
public AssignmentElement(string variableName, ExpressionElement valueExpression, ExpressionContext context)
|
||||
{
|
||||
_variableName = variableName;
|
||||
_valueExpression = valueExpression;
|
||||
_context = context;
|
||||
|
||||
// 检查变量是否存在
|
||||
if (!_context.Variables.ContainsKey(_variableName))
|
||||
{
|
||||
this.ThrowCompileException("UndefinedVariable", CompileExceptionReason.UndefinedName, _variableName);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Emit(FleeILGenerator ilg, IServiceProvider services)
|
||||
{
|
||||
// 首先计算右侧表达式的值
|
||||
_valueExpression.Emit(ilg, services);
|
||||
|
||||
// 获取一个临时本地变量来存储值
|
||||
var valueType = _valueExpression.ResultType;
|
||||
int tempIndex = ilg.GetTempLocalIndex(valueType);
|
||||
|
||||
// 存储值到临时变量
|
||||
Utility.EmitStoreLocal(ilg, tempIndex);
|
||||
|
||||
// 加载变量集合 (arg 2)
|
||||
ilg.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); // 加载 VariableCollection
|
||||
|
||||
// 加载变量名
|
||||
ilg.Emit(System.Reflection.Emit.OpCodes.Ldstr, _variableName);
|
||||
|
||||
// 加载要设置的值
|
||||
Utility.EmitLoadLocal(ilg, tempIndex);
|
||||
|
||||
// 如果值类型是值类型,需要装箱
|
||||
if (valueType.IsValueType)
|
||||
{
|
||||
ilg.Emit(System.Reflection.Emit.OpCodes.Box, valueType);
|
||||
}
|
||||
|
||||
// 调用 Variables[string] 的 setter
|
||||
var indexerSetter = typeof(VariableCollection).GetProperty("Item", new Type[] { typeof(string) }).GetSetMethod();
|
||||
ilg.Emit(System.Reflection.Emit.OpCodes.Callvirt, indexerSetter);
|
||||
|
||||
// 加载返回值到栈上
|
||||
Utility.EmitLoadLocal(ilg, tempIndex);
|
||||
}
|
||||
|
||||
public override Type ResultType
|
||||
{
|
||||
get { return _valueExpression.ResultType; }
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user