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))); }
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))); }
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)); }
public NextRoutine(Program i_prog, ArmadaSymbolTable i_symbols, NextType i_nextType, MethodInfo methodInfo, ArmadaStatement i_armadaStatement, Statement i_stmt, ArmadaPC i_pc, ArmadaPC i_endPC) { prog = i_prog; symbols = i_symbols; nextType = i_nextType; validStepBuilder = new PredicateBuilder(i_prog); crashAvoidanceBuilder = new PredicateBuilder(i_prog); getNextStateBuilder = new ExpressionBuilder(i_prog); method = methodInfo != null ? methodInfo.method : null; armadaStatement = i_armadaStatement; stmt = i_stmt; pc = i_pc; endPC = i_endPC; formals = new List <NextFormal>(); valid = true; s = ReserveVariableName("s", "Armada_TotalState"); tid = ReserveVariableName("tid", "Armada_ThreadHandle"); locv = null; // s.stop_reason.Armada_NotStopped? var stop_reason = AH.MakeExprDotName(s, "stop_reason", "Armada_StopReason"); var not_stopped = AH.MakeExprDotName(stop_reason, "Armada_NotStopped?", new BoolType()); AddConjunct(not_stopped); // tid in s.threads var threads = AH.MakeExprDotName(s, "threads", AH.MakeThreadsType()); var tid_in_threads = AH.MakeInExpr(tid, threads); AddConjunct(tid_in_threads); // var t := s.threads[tid]; t = AddVariableDeclaration("t", AH.MakeSeqSelectExpr(threads, tid, "Armada_Thread")); // var locv := Armada_GetThreadLocalView(s, tid); locv = AH.MakeApply2("Armada_GetThreadLocalView", s, tid, "Armada_SharedMemory"); locv = AddVariableDeclaration("locv", locv); if (pc != null) { var current_pc = AH.MakeExprDotName(t, "pc", "Armada_PC"); var pc_correct = AH.MakeEqExpr(current_pc, AH.MakeNameSegment(pc.ToString(), "Armada_PC")); AddConjunct(pc_correct); // t.top.Armada_StackFrame_{methodName}? var top = AH.MakeExprDotName(t, "top", "Armada_StackFrame"); var top_frame_correct = AH.MakeExprDotName(top, $"Armada_StackFrame_{pc.methodName}?", new BoolType()); AddConjunct(top_frame_correct); if (methodInfo != null) { var constraints = methodInfo.GetEnablingConstraintCollector(pc); if (constraints != null && !constraints.Empty) { var enabling_condition = AH.MakeApply2($"Armada_EnablingConditions_{pc}", s, tid, new BoolType()); AddConjunct(enabling_condition); } } } }