예제 #1
0
 public static bool HasReturn(IStatement s)
 {
     if (s is Skip || s is Assignment)
     {
         return(false);
     }
     if (s is Conditional)
     {
         Conditional c = (Conditional)s;
         return(HasReturn(c.ThenBranch()) || HasReturn(c.ElseBranch()));
     }
     if (s is Loop)
     {
         return(HasReturn(((Loop)s).Body()));
     }
     if (s is Block)
     {
         Block b = (Block)s;
         IEnumerator <IStatement> it = b.GetMembers();
         while (it.MoveNext())
         {
             if (HasReturn(it.Current))
             {
                 return(true);
             }
         }
         return(false);
     }
     if (s is Return)
     {
         return(true);
     }
     throw new IException("Semantic Error", "", "Semantic", 0, 0);
 }
예제 #2
0
 public static Value InterpretWithReturn(IStatement s, Functions funcs, State state)
 {
     state.Display();
     if (s is Conditional)
     {
         Conditional c = (Conditional)s;
         IStatement  chosen;
         if (Interpret(c.Test(), funcs, state).DBoolValue())
         {
             chosen = c.ThenBranch();
         }
         else
         {
             chosen = c.ElseBranch();
         }
         if (chosen is Return)
         {
             return(Interpret(((Return)chosen).Result(), funcs, state));
         }
         else
         {
             return(InterpretWithReturn(chosen, funcs, state));
         }
     }
     if (s is Loop)
     {
         Loop l = (Loop)s;
         if (Interpret(l.Test(), funcs, state).DBoolValue())
         {
             return(InterpretWithReturn(l, funcs, Interpret(l.Body(), funcs, state)));
         }
     }
     if (s is Block)
     {
         Block b = (Block)s;
         IEnumerator <IStatement> it = b.GetMembers();
         while (it.MoveNext())
         {
             IStatement bs = it.Current;
             if (bs is Skip)
             {
                 continue;
             }
             if (bs is Return)
             {
                 return(Interpret(((Return)s).Result(), funcs, state));
             }
             else
             {
                 state = Interpret(s, funcs, state);
             }
         }
     }
     if (s is Return)
     {
         return(Interpret(((Return)s).Result(), funcs, state));
     }
     throw new IException("tried to Interpret statement with return when it didn't have a return", "", "Semantic", 0, 0);
 }
예제 #3
0
 public static State Interpret(Conditional c, Functions funcs, State state)
 {
     if (Interpret(c.Test(), funcs, state).DBoolValue())
     {
         return(Interpret(c.ThenBranch(), funcs, state));
     }
     else
     {
         return(Interpret(c.ElseBranch(), funcs, state));
     }
 }
예제 #4
0
        public static bool IsSkipped(Conditional c, Functions funcs, State state)
        {
            IStatement chosen;

            if (Interpret(c.Test(), funcs, state).DBoolValue())
            {
                chosen = c.ThenBranch();
            }
            else
            {
                chosen = c.ElseBranch();
            }
            return(chosen is Skip);
        }
예제 #5
0
        public static IStatement Transform(IStatement s, Functions funcs, TypeMap tm)
        {
            if (s is Skip || s is Return || s is Call)
            {
                return(s);
            }
            if (s is Assignment)
            {
                Assignment a = (Assignment)s;

                Variable    target = a.Target();
                IExpression src    = a.Source();

                Type targettype = (Type)tm[a.Target()];
                Type srctype    = StaticTypeCheck.TypeOf(a.Source(), funcs, tm);

                if (targettype == Type.FLOAT)
                {
                    if (srctype == Type.INT)
                    {
                        src     = new Unary(new Operator(Operator.FLOAT), src);
                        srctype = Type.FLOAT;
                    }
                }
                else if (targettype == Type.INT)
                {
                    if (srctype == Type.CHAR)
                    {
                        src     = new Unary(new Operator(Operator.INT), src);
                        srctype = Type.INT;
                    }
                    else if (srctype == Type.FLOAT)
                    {
                        src     = new Unary(new Operator(Operator.INT), src);
                        srctype = Type.INT;
                    }
                }
                StaticTypeCheck.Check(targettype == srctype, "bug in assignment to " + target);
                return(new Assignment(target, src));
            }

            if (s is Conditional)
            {
                Conditional c    = (Conditional)s;
                IExpression test = c.Test();
                IStatement  tbr  = Transform(c.ThenBranch(), funcs, tm);
                IStatement  ebr  = Transform(c.ElseBranch(), funcs, tm);
                return(new Conditional(test, tbr, ebr));
            }

            if (s is Loop)
            {
                Loop        l    = (Loop)s;
                IExpression test = l.Test();
                IStatement  body = l.Body();
                return(new Loop(test, body));
            }

            if (s is Block)
            {
                Block b    = (Block)s;
                Block @out = new Block();
                IEnumerator <IStatement> members = b.GetMembers();
                while (members.MoveNext())
                {
                    @out.AddMember(Transform(members.Current, funcs, tm));
                }
                return(@out);
            }
            throw new IException("Semantic Error", "", "Semantic", 0, 0);
        }
예제 #6
0
        public static void Validate(IStatement s, Functions funcs, TypeMap tm)
        {
            if (s == null)
            {
                throw new IException("TypeChecking: null statement", "", "Semantic", 0, 0);
            }

            else if (s is Skip)
            {
                return;
            }
            else if (s is Assignment)
            {
                Assignment a = (Assignment)s;
                Check(tm.ContainsKey(a.Target()), "Target not found in type map! (target: " + a.Target() + ")");
                Validate(a.Source(), funcs, tm);
                Type targettype = (Type)tm[a.Target()];
                Type srctype    = TypeOf(a.Source(), funcs, tm);
                if (targettype != srctype)
                {
                    if (targettype == Type.FLOAT)
                    {
                        Check(srctype == Type.INT, "Caught mixed mode assignment in static type Checker from " + srctype + " to " + targettype + " (target: " + a.Target() + ")");
                    }
                    else if (targettype == Type.INT)
                    {
                        Check(srctype == Type.CHAR || srctype == Type.FLOAT, "Caught mixed mode assignment in static type Checker from " + srctype + " to " + targettype + " (target: " + a.Target() + ")");
                    }
                    else
                    {
                        Check(false, "Caught mixed mode assignment in static type Checker from " + srctype + " to " + targettype + " (target: " + a.Target() + ")");
                    }
                }
                return;
            }
            else if (s is Block)
            {
                Block b = (Block)s;
                IEnumerator <IStatement> members = b.GetMembers();
                while (members.MoveNext())
                {
                    Validate(members.Current, funcs, tm);
                }
            }
            else if (s is Loop)
            {
                Loop l = (Loop)s;
                Validate(l.Test(), funcs, tm);
                Validate(l.Body(), funcs, tm);
            }
            else if (s is Conditional)
            {
                Conditional c = (Conditional)s;
                Validate(c.Test(), funcs, tm);
                Validate(c.ThenBranch(), funcs, tm);
                Validate(c.ElseBranch(), funcs, tm);
            }
            else if (s is Return)
            {
                Return   r = (Return)s;
                Function f = funcs[r.FunctionName().ToString()];
                Type     t = TypeOf(r.Result(), funcs, tm);
                Check(t == f.type(), "Return expression doesn't match function's return type! (got a " + t + ", expected a " + f.type() + ")");
            }
            else
            {
                throw new IException("Type Checking Error : " + s, "", "Semantic", 0, 0);
            }
        }