Exemple #1
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)
                             ));
        }
Exemple #2
0
        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));
            }
        }