public IEnumerable <Operation> VisitGetFieldExpression(GetFieldExpression expression) { if (expression.Left is NameExpression ne0 && ne0.Depth == 0) { yield return(Operation.Mov( NewRegister(8), new NameOperand($"Function{expression.Field}") )); yield break; } var str = (StructType)Types.TypeOf(expression.Left); var size = str.Fields[expression.Field] switch { NumberType nt => (nt.BitSize / 8), PointerType _ => 8, _ => throw new Exception("Getter value calculation must result in simple type") }; if (expression.Left is NameExpression ne && ne.Depth == 1) { var(onStack, idx) = CurrentFunctionParams.Params[expression.Field]; yield return(Operation.Mov( NewRegister(8), new Memory(new Shift(Register.Rsp, ParameterOffset(onStack, idx)), size) )); yield break; } foreach (var op in _addressVisitor.VisitExpression(expression.Left)) { yield return(op); } var adr = LastRegister; yield return(Operation.Mov( NewRegister(size), new Memory(new Shift(adr, TypeEvaluator.GetOffset(str, expression.Field)), adr.Size) )); }
public IEnumerable <Operation> MakeAssigner(Shift left, Shift right, BaseType type) { switch (type) { case EmptyType _: break; case FunctionType _: throw new Exception("Can not assign functions"); case NumberType numberType: { var r = NewRegister(numberType.BitSize / 8); yield return(Operation.Mov(r, new Memory(right, numberType.BitSize / 8))); yield return(Operation.Mov(new Memory(left, numberType.BitSize / 8), r)); break; } case PointerType _: { var r = NewRegister(8); yield return(Operation.Mov(r, new Memory(right, 8))); yield return(Operation.Mov(new Memory(left, 8), r)); break; } case StructType structType: foreach (var op in structType.Fields.SelectMany((f, i) => MakeAssigner( new Shift(left.Register, left.Shft + TypeEvaluator.GetOffset(structType, i)), new Shift(right.Register, right.Shft + TypeEvaluator.GetOffset(structType, i)), f ) )) { yield return(op); } break; default: throw new ArgumentOutOfRangeException(nameof(type)); } }