示例#1
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            TO2Type leftType  = left.ResultType(context);
            TO2Type rightType = right.ResultType(context);

            if (context.HasErrors)
            {
                return;
            }

            IOperatorEmitter leftEmitter = leftType.AllowedSuffixOperators(context.ModuleContext)
                                           .GetMatching(context.ModuleContext, op, rightType);
            IOperatorEmitter rightEmitter = rightType.AllowedPrefixOperators(context.ModuleContext)
                                            .GetMatching(context.ModuleContext, op, leftType);

            if (leftEmitter == null && rightEmitter == null)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.IncompatibleTypes,
                                     $"Cannot {op} a {leftType} with a {rightType}",
                                     Start,
                                     End
                                     ));
                return;
            }

            right.Prepare(context);

            left.EmitCode(context, false);
            rightEmitter?.OtherType.AssignFrom(context.ModuleContext, leftType).EmitConvert(context);
            right.EmitCode(context, false);
            leftEmitter?.OtherType.AssignFrom(context.ModuleContext, rightType).EmitConvert(context);

            if (context.HasErrors)
            {
                return;
            }

            if (leftEmitter != null)
            {
                leftEmitter.EmitCode(context, this);
            }
            else
            {
                rightEmitter.EmitCode(context, this);
            }

            if (dropResult)
            {
                context.IL.Emit(OpCodes.Pop);
            }
        }
示例#2
0
        public override TO2Type ResultType(IBlockContext context)
        {
            TO2Type leftType  = left.ResultType(context);
            TO2Type rightType = right.ResultType(context);

            IOperatorEmitter operatorEmitter =
                leftType.AllowedSuffixOperators(context.ModuleContext)
                .GetMatching(context.ModuleContext, op, rightType) ??
                rightType.AllowedPrefixOperators(context.ModuleContext)
                .GetMatching(context.ModuleContext, op, leftType);

            if (operatorEmitter == null)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.IncompatibleTypes,
                                     $"Cannot {op} a {leftType} with a {rightType}",
                                     Start,
                                     End
                                     ));
                return(BuiltinType.Unit);
            }

            return(operatorEmitter.ResultType);
        }
示例#3
0
 public override IOperatorCollection AllowedPrefixOperators(ModuleContext context) =>
 aliasedType.AllowedPrefixOperators(declaredModule);