Beispiel #1
0
 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}"),
     });
Beispiel #2
0
        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)
                             ));
        }
Beispiel #3
0
 public string VisitGetFieldExpression(GetFieldExpression expression)
 => $"({expression.Left.AcceptVisitor(this)}.{expression.Field})";