public VarInfoTable Copy()
        {
            var res = new VarInfoTable(code);

            foreach (var kv in this)
            {
                res[kv.Key] = this[kv.Key];
            }
            return(res);
        }
        public VarInfoTable Merge(VarInfoTable other)
        {
            var res = new VarInfoTable(code);

            foreach (var kv in this)
            {
                res[kv.Key] = this[kv.Key].Merge(other[kv.Key]);
            }
            return(res);
        }
 public static bool AreEqual(VarInfoTable a, VarInfoTable b)
 {
     foreach (var kv in a)
     {
         if (!a[kv.Key].Equals(b[kv.Key]))
         {
             return(false);
         }
     }
     return(true);
 }
        public static VarInfo FromAssign(Assign s, VarInfoTable t)
        {
            var r = s.Result;

            if (s.Left is null)
            {
                var v = s.Right;
                if (v is IntConst c)
                {
                    return(new VarInfo(Flag.Const, c.Num));
                }
                if (v is Var vr)
                {
                    return(t[vr.Id].Copy());
                }
                return(new VarInfo(Flag.NAC));
            }
            var v1 = s.Right;
            var v2 = s.Left;

            {
                if (v1 is IntConst c1 && v2 is IntConst c2)
                {
                    return(new VarInfo(Flag.Const, c1.Num + c2.Num));
                }
            }

            {
                if (v1 is Var vr1 && v2 is IntConst c2)
                {
                    if (t[vr1.Id].IsConst)
                    {
                        return(new VarInfo(Flag.Const, t[vr1.Id].Value.Value + c2.Num));
                    }
                    if (t[vr1.Id].IsNac)
                    {
                        return(new VarInfo(Flag.NAC));
                    }
                    if (t[vr1.Id].IsUndef)
                    {
                        return(new VarInfo(Flag.UNDEF));
                    }
                }
            }

            {
                if (v2 is Var vr1 && v1 is IntConst c2)
                {
                    if (t[vr1.Id].IsConst)
                    {
                        return(new VarInfo(Flag.Const, t[vr1.Id].Value.Value + c2.Num));
                    }
                    if (t[vr1.Id].IsNac)
                    {
                        return(new VarInfo(Flag.NAC));
                    }
                    if (t[vr1.Id].IsUndef)
                    {
                        return(new VarInfo(Flag.UNDEF));
                    }
                }
            }

            {
                if (v1 is Var vr1 && v2 is Var vr2)
                {
                    return(MergeBin(t[vr1.Id], t[vr2.Id], s.Operation));
                }
            }
            throw new Exception();
        }