Exemple #1
0
        public override ArmadaLValue ApplyExprDotName(IToken i_tok, ResolutionContext context, string fieldName, Type ty)
        {
            if (!(type is UserDefinedType))
            {
                context.Fail(i_tok, $"Attempt to take a field ({fieldName}) of non-struct, non-datatype type {type}");
                return(null);
            }

            UserDefinedType ut = (UserDefinedType)type;

            if (context.symbols.DoesStructExist(ut.Name))
            {
                Type fieldType = context.symbols.GetStructFieldType(ut.Name, fieldName);
                if (fieldType == null)
                {
                    context.Fail(i_tok, $"Attempt to take non-existent field ({fieldName}) in struct type {ut.Name}");
                    return(null);
                }
                if (!AH.TypesMatch(fieldType, ty))
                {
                    context.Fail(i_tok, $"Field {fieldName} of type {fieldType} used as type {ty}");
                    return(null);
                }
            }

            return(new UnaddressableFieldArmadaLValue(i_tok, ty, this, crashAvoidance, fieldName, false));
        }
Exemple #2
0
        public override ArmadaLValue ApplySeqSelect(IToken i_tok, ResolutionContext context, ArmadaRValue idx1, Type ty)
        {
            if (!(type is SizedArrayType))
            {
                context.Fail(i_tok, "Attempt to obtain element of non-array type");
                return(null);
            }
            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);
            }

            var crashAvoidance = address.UndefinedBehaviorAvoidance + idx1.UndefinedBehaviorAvoidance;

            var s    = context.GetLValueState();
            var mem  = AH.MakeExprDotName(s, "mem", "Armada_SharedMemory");
            var h    = AH.MakeExprDotName(mem, "heap", "Armada_Heap");
            var tree = AH.MakeExprDotName(h, "tree", "Armada_Tree");

            crashAvoidance.Add(AH.MakeInExpr(address.Val, tree));

            var node        = AH.MakeSeqSelectExpr(tree, address.Val, "Armada_Node");
            var children    = AH.MakeExprDotName(node, "children", AH.MakeChildrenType());
            var idx1_as_int = AH.ConvertToIntIfNotInt(idx1.Val);
            var field       = AH.MakeApply1("Armada_FieldArrayIndex", idx1_as_int, "Armada_Field");
            var child       = AH.MakeSeqSelectExpr(children, field, new PointerType(st.Range));

            crashAvoidance.Add(AH.MakeInExpr(field, children));

            return(new AddressableArmadaLValue(i_tok, st.Range, new ArmadaRValue(crashAvoidance, child)));
        }
Exemple #3
0
        public override ArmadaLValue ApplySeqSelect(IToken i_tok, ResolutionContext context, ArmadaRValue idx1, Type indexType, Type exprType)
        {
            if (!(type is SizedArrayType))
            {
                context.Fail(i_tok, "Attempt to obtain element of non-array type");
                return(null);
            }
            SizedArrayType st = (SizedArrayType)type;

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

            var crashAvoidance = address.UndefinedBehaviorAvoidance + idx1.UndefinedBehaviorAvoidance;

            var s           = context.GetLValueState();
            var h           = $"({s}).mem.heap";
            var idx1_as_int = AH.ConvertToIntIfNotInt(idx1.Val, indexType);

            crashAvoidance.Add($"{address.Val} in {h}.tree");
            crashAvoidance.Add($"0 <= {idx1_as_int} < |{h}.tree[{address.Val}].children|");

            var child = $"{h}.tree[{address.Val}].children[{idx1_as_int}]";

            return(new AddressableArmadaLValue(i_tok, st.Range, new ArmadaRValue(crashAvoidance, child)));
        }
Exemple #4
0
        public override ArmadaLValue ApplyExprDotName(IToken i_tok, ResolutionContext context, string fieldName, Type ty)
        {
            if (!(type is UserDefinedType))
            {
                context.Fail(i_tok, $"Attempt to take a field ({fieldName}) of non-struct type {type}");
                return(null);
            }
            UserDefinedType ut = (UserDefinedType)type;

            if (!context.symbols.DoesStructExist(ut.Name))
            {
                context.Fail(i_tok, $"Attempt to take a field ({fieldName}) of non struct type {ut.Name}");
                return(null);
            }
            Type fieldType = context.symbols.GetStructFieldType(ut.Name, fieldName);

            if (fieldType == null)
            {
                context.Fail(i_tok, $"Attempt to take non-existent field ({fieldName}) in struct type {ut.Name}");
                return(null);
            }
            if (!AH.TypesMatch(fieldType, ty))
            {
                context.Fail(i_tok, $"Field {fieldName} of type {fieldType} used as type {ty}");
                return(null);
            }

            var crashAvoidance = address.UndefinedBehaviorAvoidance;

            var s    = context.GetLValueState();
            var mem  = AH.MakeExprDotName(s, "mem", "Armada_SharedMemory");
            var h    = AH.MakeExprDotName(mem, "heap", "Armada_Heap");
            var tree = AH.MakeExprDotName(h, "tree", "Armada_Tree");

            crashAvoidance.Add(AH.MakeInExpr(address.Val, tree));

            var node     = AH.MakeSeqSelectExpr(tree, address.Val, "Armada_Node");
            var children = AH.MakeExprDotName(node, "children", AH.MakeChildrenType());
            var field    = AH.MakeApply1("Armada_FieldStruct",
                                         AH.MakeNameSegment($"Armada_FieldType_{ut.Name}'{fieldName}", "Armada_FieldType"),
                                         "Armada_Field");
            var child = AH.MakeSeqSelectExpr(children, field, new PointerType(fieldType));

            crashAvoidance.Add(AH.MakeInExpr(field, children));

            return(new AddressableArmadaLValue(i_tok, fieldType, new ArmadaRValue(crashAvoidance, child)));
        }
Exemple #5
0
        protected override bool CheckVariableNameListEquivalence(IEnumerable <string> varNames_l, IEnumerable <string> varNames_h,
                                                                 ArmadaSingleMethodSymbolTable s_l, ArmadaSingleMethodSymbolTable s_h,
                                                                 string methodName, string descriptor)
        {
            var vars_l = varNames_l.ToArray();

            string[] vars_h;
            if (methodName == strategy.MethodName)
            {
                vars_h = varNames_h.Where(v => v != strategy.VariableName).ToArray();
            }
            else
            {
                vars_h = varNames_h.ToArray();
            }

            if (vars_l.Length != vars_h.Length)
            {
                AH.PrintError(pgp.prog, $"Method {methodName} has {vars_l.Length} {descriptor} variables in level {pgp.mLow.Name} but {vars_h.Length} of them in level {pgp.mHigh.Name}");
                return(false);
            }

            for (int i = 0; i < vars_l.Length; ++i)
            {
                var name_l = vars_l[i];
                var name_h = vars_h[i];
                if (name_l != name_h)
                {
                    AH.PrintError(pgp.prog, $"In method {methodName}, {descriptor} non-introduced variable number {i+1} is named {name_l} in level {pgp.mLow.Name} but named {name_h} in level {pgp.mHigh.Name}");
                    return(false);
                }
                var v_l = s_l.LookupVariable(name_l);
                var v_h = s_h.LookupVariable(name_h);
                if (!AH.TypesMatch(v_l.ty, v_h.ty))
                {
                    AH.PrintError(pgp.prog, $"In method {methodName}, the {descriptor} variable named {name_l} has type {v_l.ty} in level {pgp.mLow.Name} but type {v_h.ty} in level {pgp.mHigh.Name}");
                    return(false);
                }
            }

            return(true);
        }
Exemple #6
0
        public override ArmadaLValue ApplySeqSelect(IToken i_tok, ResolutionContext context, ArmadaRValue idx1, Type indexType, Type exprType)
        {
            var me = GetValueInLValueState(context);
            var sz = $"|{me}|";

            var newUndefinedBehaviorAvoidance = GetUndefinedBehaviorAvoidanceConstraint() + idx1.UndefinedBehaviorAvoidance;

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

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

                newUndefinedBehaviorAvoidance.Add($"0 <= {idx1val} < {sz}");
            }
            else if (type is SeqType)
            {
                newUndefinedBehaviorAvoidance.Add($"0 <= {idx1val} < {sz}");
            }
            else if (type is MapType)
            {
                // There's no need to consider it undefined behavior if idx1.Val isn't in this map, since we're just
                // using it as an lvalue.  It's fine to update an element of a map that isn't yet in its domain.
                // So we don't need to do:
                //   newUndefinedBehaviorAvoidance.Add($"({idx1.Val}) in ({me})");
                return(new UnaddressableIndexArmadaLValue(i_tok, exprType, this, newUndefinedBehaviorAvoidance, idx1.Val));
            }
            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, exprType, this, newUndefinedBehaviorAvoidance, idx1val));
        }
Exemple #7
0
        public override ArmadaLValue ApplyExprDotName(IToken i_tok, ResolutionContext context, string fieldName, Type targetType)
        {
            if (!(type is UserDefinedType))
            {
                context.Fail(i_tok, $"Attempt to take a field ({fieldName}) of non-struct type {type}");
                return(null);
            }
            UserDefinedType ut = (UserDefinedType)type;

            if (!context.symbols.DoesStructExist(ut.Name))
            {
                context.Fail(i_tok, $"Attempt to take a field ({fieldName}) of non struct type {ut.Name}");
                return(null);
            }
            Type fieldType = context.symbols.GetStructFieldType(ut.Name, fieldName);

            if (fieldType == null)
            {
                context.Fail(i_tok, $"Attempt to take non-existent field ({fieldName}) in struct type {ut.Name}");
                return(null);
            }
            if (!AH.TypesMatch(fieldType, targetType))
            {
                context.Fail(i_tok, $"Field {fieldName} of type {fieldType} used as type {targetType}");
                return(null);
            }

            var crashAvoidance = address.UndefinedBehaviorAvoidance;

            var s        = context.GetLValueState();
            var h        = $"({s}).mem.heap";
            int fieldPos = context.symbols.GetStructFieldPos(ut.Name, fieldName);

            crashAvoidance.Add($"{address.Val} in {h}.tree");
            crashAvoidance.Add($"0 <= {fieldPos} < |{h}.tree[{address.Val}].children|");

            var child = $"{h}.tree[{address.Val}].children[{fieldPos}]";

            return(new AddressableArmadaLValue(i_tok, fieldType, new ArmadaRValue(crashAvoidance, child)));
        }
Exemple #8
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));
        }