예제 #1
0
        public override ArmadaLValue ApplySeqSelect(IToken i_tok, ResolutionContext context, ArmadaRValue idx1, Type ty)
        {
            var me = GetValueInLValueState(context);
            var sz = AH.MakeCardinalityExpr(me);

            var newUndefinedBehaviorAvoidance = GetUndefinedBehaviorAvoidanceConstraint() + idx1.UndefinedBehaviorAvoidance;

            var idx1val = AH.ConvertToIntIfNotInt(idx1.Val);

            if (type is SizedArrayType)
            {
                SizedArrayType st = (SizedArrayType)type;
                if (!AH.TypesMatch(st.Range, ty))
                {
                    context.Fail(i_tok, $"Element of type {st.Range} used as type {ty}");
                    return(null);
                }

                newUndefinedBehaviorAvoidance.Add(AH.MakeLeExpr(AH.MakeZero(), idx1val));
                newUndefinedBehaviorAvoidance.Add(AH.MakeLtExpr(idx1val, sz));
            }
            else if (type is SeqType)
            {
                newUndefinedBehaviorAvoidance.Add(AH.MakeLeExpr(AH.MakeZero(), idx1val));
                newUndefinedBehaviorAvoidance.Add(AH.MakeLtExpr(idx1val, sz));
            }
            else if (type is MapType)
            {
                newUndefinedBehaviorAvoidance.Add(AH.MakeInExpr(idx1val, me));
            }
            else
            {
                context.Fail(i_tok, $"Attempt to index into something that isn't an array, seq, or map");
                return(null);
            }

            return(new UnaddressableIndexArmadaLValue(i_tok, ty, this, newUndefinedBehaviorAvoidance, idx1val));
        }