Esempio n. 1
0
        public static void Validate(IExpression e, Functions funcs, TypeMap tm)
        {
            if (e is Value)
            {
                return;
            }
            if (e is Call)
            {
                Validate((Call)e, funcs, tm);
                return;
            }
            if (e is Variable)
            {
                Variable v = (Variable)e;
                Check(tm.ContainsKey(v), "Caught undeclared variable in static type Check: " + v);
                return;
            }
            if (e is Binary)
            {
                Binary b = (Binary)e;

                Type type1 = TypeOf(b.Term1(), funcs, tm);
                Type type2 = TypeOf(b.Term2(), funcs, tm);

                Validate(b.Term1(), funcs, tm);
                Validate(b.Term2(), funcs, tm);
                if (b.Operator().IsArithmeticOp())
                {
                    Check((type1 == Type.INT && type2 == Type.INT) || (type1 == Type.FLOAT && type2 == Type.FLOAT) || (type1 == Type.INT && type2 == Type.FLOAT) || (type1 == Type.FLOAT && type2 == Type.INT), "Type error for arithmetic op " + b.Operator() + "; got types " + type1 + " and " + type2);
                }
                else if (b.Operator().IsRelationalOp())
                {
                    Check((type1 == Type.INT && type2 == Type.INT) || (type1 == Type.FLOAT && type2 == Type.FLOAT) || (type1 == Type.INT && type2 == Type.FLOAT) || (type1 == Type.FLOAT && type2 == Type.INT) || (type1 == Type.BOOL && type2 == Type.BOOL) || (type1 == Type.CHAR && type2 == Type.CHAR), "Type error for relational op " + b.Operator() + "; got types " + type1 + " and " + type2);
                }
                else if (b.Operator().IsBooleanOp())
                {
                    Check(type1 == Type.BOOL && type2 == Type.BOOL, "Caught non-bool operand for " + b.Operator() + " in static type Checker; got types " + type1 + " and " + type2);
                }
                else
                {
                    throw new IException("Type Checking Error", "", "Semantic", 0, 0);
                }
                return;
            }
            else if (e is Unary)
            {
                Unary u = (Unary)e;
                Type  t = TypeOf(u.term, funcs, tm);
                Validate(u.term, funcs, tm);
                if (u.Operator().IsNotOp())
                {
                    Check(t == Type.BOOL, "Attempted not operation on non-bool (attempted on " + t + ")");
                }
                else if (u.Operator().IsNegateOp())
                {
                    Check(t == Type.FLOAT || t == Type.INT, "Attempted negate operation on something other than a float or int (attempted on " + t + ")");
                }
                else if (u.Operator().IsIntOp())
                {
                    Check(t == Type.FLOAT || t == Type.CHAR, "Attempted int cast from something other than a float or a char (attempted on " + t + ")");
                }
                else if (u.Operator().IsFloatOp())
                {
                    Check(t == Type.INT, "Attempted float cast from something other than an int (attempted on " + t + ")");
                }
                else if (u.Operator().IsCharOp())
                {
                    Check(t == Type.INT, "Attempted char cast from something other than an int (attempted on " + t + ")");
                }
            }
            else
            {
                throw new IException("Type Checking Error", "", "Semantic", 0, 0);
            }
        }
Esempio n. 2
0
 public static Type TypeOf(IExpression e, Functions funcs, TypeMap tm)
 {
     if (e is Value)
     {
         return(((Value)e).Type());
     }
     else if (e is Call)
     {
         Call     c = (Call)e;
         Function f = funcs[c.Identifier().ToString()];
         return(f.type());
     }
     else if (e is Variable)
     {
         Variable v = (Variable)e;
         Check(tm.ContainsKey(v), "Caught undefined variable in static type Checker: " + v);
         return((Type)tm[v]);
     }
     else if (e is Binary)
     {
         Binary b = (Binary)e;
         if (b.Operator().IsArithmeticOp())
         {
             if (TypeOf(b.Term1(), funcs, tm) == Type.INT && TypeOf(b.Term1(), funcs, tm) == Type.INT)
             {
                 return(Type.INT);
             }
             else
             {
                 return(Type.FLOAT);
             }
         }
         else if (b.Operator().IsRelationalOp() || b.Operator().IsBooleanOp())
         {
             return(Type.BOOL);
         }
         else
         {
             throw new IException("Unknown binary op in static type Checker, expression: " + e, "", "Semantic", 0, 0);
         }
     }
     else if (e is Unary)
     {
         Unary u = (Unary)e;
         if (u.Operator().IsNotOp())
         {
             return(Type.BOOL);
         }
         else if (u.Operator().IsNegateOp())
         {
             return(TypeOf(u.term, funcs, tm));
         }
         else if (u.Operator().IsIntOp())
         {
             return(Type.INT);
         }
         else if (u.Operator().IsFloatOp())
         {
             return(Type.FLOAT);
         }
         else if (u.Operator().IsCharOp())
         {
             return(Type.CHAR);
         }
     }
     throw new IException("Type Checking Error", "", "Semantic", 0, 0);
 }
Esempio n. 3
0
        public static Value Interpret(Unary u, Functions funcs, State state)
        {
            Operator op = u.Operator();
            Value    v  = Interpret(u.term, funcs, state);

            StaticTypeCheck.Check(!v.Undefined(), "reference to undef value in unary op");
            if (op.val.Equals(Operator.NOT))
            {
                if (v.Type() != Type.BOOL)
                {
                    throw new IException("Can only apply ! operator to bool (attempted on " + v + ")", "", "Semantic", 0, 0);
                }
                else
                {
                    return(new BoolValue(!v.DBoolValue()));
                }
            }
            else if (op.val.Equals(Operator.NEG))
            {
                if (v.Type() == Type.FLOAT)
                {
                    return(new FloatValue(-v.DFloatValue()));
                }
                else if (v.Type() == Type.INT)
                {
                    return(new IntValue(-v.DIntValue()));
                }
                else
                {
                    throw new IException("Can only apply - operator to int or float (attempted on " + v + ")", "", "Semantic", 0, 0);
                }
            }
            else if (op.val.Equals(Operator.FLOAT))
            {
                if (v.Type() != Type.INT)
                {
                    throw new IException("Can only cast int to float (tried to cast " + v + ")", "", "Semantic", 0, 0);
                }
                else
                {
                    return(new FloatValue((float)v.DIntValue()));
                }
            }
            else if (op.val.Equals(Operator.INT))
            {
                if (v.Type() == Type.FLOAT)
                {
                    return(new IntValue((int)v.DFloatValue()));
                }
                else if (v.Type() == Type.CHAR)
                {
                    return(new IntValue((int)v.DCharValue()));
                }
                else
                {
                    throw new IException("Can only cast float or char to int (tried to cast " + v + ")", "", "Semantic", 0, 0);
                }
            }
            else if (op.val.Equals(Operator.CHAR))
            {
                if (v.Type() == Type.INT)
                {
                    return(new CharValue((char)v.DIntValue()));
                }
                else
                {
                    throw new IException("Can only cast int to char (tried to cast " + v + ")", "", "Semantic", 0, 0);
                }
            }
            throw new IException("Semantic Error", "", "Semantic", 0, 0);
        }