ArrayElementExpression
using CLanguage.Compiler;
using CLanguage.Interpreter;
using CLanguage.Types;
using System.Runtime.CompilerServices;
namespace CLanguage.Syntax
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class ArrayElementExpression : Expression
{
public Expression Array { get; set; }
public Expression ElementIndex { get; set; }
public override bool CanEmitPointer => Array.CanEmitPointer;
public ArrayElementExpression(Expression array, Expression elementIndex)
{
Array = array;
ElementIndex = elementIndex;
}
public override CType GetEvaluatedCType(EmitContext ec)
{
CType evaluatedCType = Array.GetEvaluatedCType(ec);
CArrayType cArrayType = evaluatedCType as CArrayType;
if (cArrayType != null)
return cArrayType.ElementType;
CPointerType cPointerType = evaluatedCType as CPointerType;
if (cPointerType != null)
return cPointerType.InnerType;
ec.Report.Error(601, "Left hand side of [ must be an array or pointer");
return CType.Void;
}
protected override void DoEmit(EmitContext ec)
{
DoEmitPointer(ec);
ec.Emit(OpCode.LoadPointer);
}
public override string ToString()
{
return $"{Array}""{ElementIndex}""";
}
protected override void DoEmitPointer(EmitContext ec)
{
Array.Emit(ec);
ElementIndex.Emit(ec);
ec.Emit(OpCode.LoadConstant, GetEvaluatedCType(ec).NumValues);
ec.Emit(OpCode.MultiplyInt32);
ec.Emit(OpCode.OffsetPointer);
}
}
}