CLanguage by praeclarum

<PackageReference Include="CLanguage" Version="0.12.163" />

 MemberFromReferenceExpression

using CLanguage.Compiler; using CLanguage.Interpreter; using CLanguage.Types; using System; using System.Linq; using System.Runtime.CompilerServices; namespace CLanguage.Syntax { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class MemberFromReferenceExpression : Expression { public Expression Left { get; set; } public string MemberName { get; set; } public MemberFromReferenceExpression(Expression left, string memberName) { Left = left; MemberName = memberName; } public override CType GetEvaluatedCType(EmitContext ec) { CType evaluatedCType = Left.GetEvaluatedCType(ec); CStructType cStructType = evaluatedCType as CStructType; if (cStructType != null) { CStructMember cStructMember = cStructType.Members.FirstOrDefault((CStructMember x) => x.Name == MemberName); if (cStructMember == null) { ec.Report.Error(1061, "'{1}' not found in '{0}'", cStructType.Name, MemberName); return CBasicType.SignedInt; } return cStructMember.MemberType; } throw new NotImplementedException("Member type on " + evaluatedCType?.GetType().get_Name()); } protected override void DoEmit(EmitContext ec) { CType evaluatedCType = Left.GetEvaluatedCType(ec); CStructType cStructType = evaluatedCType as CStructType; if (cStructType == null) throw new NotSupportedException("Member access on " + evaluatedCType?.GetType().get_Name()); CStructMember cStructMember = cStructType.Members.FirstOrDefault((CStructMember x) => x.Name == MemberName); if (cStructMember == null) ec.Report.Error(1061, "'{1}' not found in '{0}'", cStructType.Name, MemberName); else { CStructMethod cStructMethod = cStructMember as CStructMethod; if (cStructMethod == null || !(cStructMember.MemberType is CFunctionType)) throw new NotSupportedException("Member field access on struct " + cStructType.Name); ResolvedVariable resolvedVariable = ec.ResolveMethodFunction(cStructType, cStructMethod); if (resolvedVariable != null) { Left.EmitPointer(ec); ec.Emit(OpCode.LoadConstant, Value.Pointer(resolvedVariable.Address)); } } } public override string ToString() { return string.Format("{0}.{1}", new object[2] { Left, MemberName }); } } }