public IEnumerable <Operation> VisitExpression(Expression expression) { return(expression switch { BinaryExpression binaryExpression => VisitBinaryExpression(binaryExpression), MagicExpression magicExpression => VisitMagicExpression(magicExpression), NameExpression nameExpression => VisitNameExpression(nameExpression), UnaryExpression unaryExpression => VisitUnaryExpression(unaryExpression), GetFieldExpression getFieldExpression => VisitGetFieldExpression(getFieldExpression), _ => throw new ArgumentOutOfRangeException(nameof(expression) + $"was {expression}"), });
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 string VisitGetFieldExpression(GetFieldExpression expression) => $"({expression.Left.AcceptVisitor(this)}.{expression.Field})";