示例#1
0
        object Evaluate(Expression expression)
        {
            if (expression is BinaryOperator) {
                var binOp = (BinaryOperator)expression;
                TypeBinding binding = TypeBindings.DecideType(binOp.LeftOperand, symbolTable, errors);

                return TypeModels.EvaluateBinaryOperator(binding, binOp.Oper.Lexeme,
                                                  Evaluate (binOp.LeftOperand), Evaluate(binOp.RightOperand));
            } else if (expression is UnaryOperator) {
                var unOp = (UnaryOperator)expression;
                TypeBinding binding = TypeBindings.DecideType(unOp.Operand, symbolTable, errors);

                return TypeModels.EvaluateUnaryOperator(binding, unOp.Oper.Lexeme,
                                                        Evaluate (unOp.Operand));
            } else if (expression is ExpressionLeaf) {
                var leaf = (ExpressionLeaf)expression;
                switch(leaf.Token.Category)
                {
                    case Category.Literal_Integer:
                        return int.Parse(leaf.Token.Lexeme);
                        break;
                    case Category.Literal_String:
                        return leaf.Token.Lexeme;
                        break;
                    case Category.Identifier:
                        if (symbolTable.IsDeclared (leaf.Token)) {
                            return symbolTable.GetValue(leaf.Token);
                        } else {
                            //should be handled by semantic analyser
                            throw new InvalidOperationException("Undeclared variable");
                        }
                        break;
                    default:
                        return null;
                }
            }
            throw new InvalidOperationException("Unrecognized expression class");
        }
示例#2
0
        public static TypeBinding DecideType(Expression expression, SymbolTable symbolTable, ErrorContainer errors)
        {
            if (expression is BinaryOperator) {
                var binOp = (BinaryOperator)expression;
                TypeBinding leftType = DecideType (binOp.LeftOperand, symbolTable, errors);
                TypeBinding rightType = DecideType (binOp.RightOperand, symbolTable, errors);
                if(leftType == null || rightType == null) {
                    return null;
                }
                if (leftType != rightType) {
                    errors.AddError (binOp.Oper, ErrorType.SemanticError, "Types of left and right operand do not match");
                    return null;
                }
                var ret = rightType.Operate (binOp.Oper.Lexeme);
                if(ret == null) {
                    errors.AddError (binOp.Oper, ErrorType.SemanticError, "Could not apply operator to given types");
                }
                return ret;
            } else if (expression is UnaryOperator) {
                var unOp = (UnaryOperator)expression;
                TypeBinding operandType = DecideType (unOp.Operand, symbolTable, errors);
                if (operandType == null) {
                    return null;
                }
                var ret = operandType.Operate (unOp.Oper.Lexeme);
                if(ret == null) {
                    errors.AddError(unOp.Oper, ErrorType.SemanticError, "Could not apply operator to given type");
                }
                return ret;
            } else if (expression is ExpressionLeaf) {
                var leaf = (ExpressionLeaf)expression;
                switch(leaf.Token.Category) {
                case Category.Literal_Integer:
                    return GetTypeByName(PRIMITIVE_INTEGER_NAME);
                case Category.Literal_String:
                    return GetTypeByName(PRIMITIVE_STRING_NAME);
                case Category.Identifier:
                    if (symbolTable.IsDeclared (leaf.Token)) {
                        return TypeBindings.GetTypeByName(symbolTable.GetVariableType(leaf.Token));
                    } else {
                        errors.AddError (leaf.Token, ErrorType.SemanticError, "Undeclared variable");
                        return null;
                    }
                }
                return null;
            }

            return null;
        }
示例#3
0
 void DoTypeChecking(Expression expression, string type)
 {
     /*if (TypeSystem.GetCategoryFromType (decideType (expression)) != type) {
         errors.addError(expression.head(), ErrorType.Semantic_Error, "Expression does not match the required type");
     }*/
     var binding = TypeBindings.DecideType (expression, symbolTable, errors);
     if (binding == null) {
         //expression was inconsistent
         return;
     } else if (binding.Name != type) {
         errors.AddError(expression.Head(), ErrorType.SemanticError, "Expression does not match the required type");
     }
 }
示例#4
0
 //checks that given expression is consistent, namely that types of each left and right operand match
 void DoConsistencyChecking(Expression expression)
 {
     TypeBindings.DecideType(expression, symbolTable, errors);
 }
示例#5
0
 void AssertionMessage(int line, int column, Expression e)
 {
     string s = "Assertion near line " + line;
     s = s + " column " + column + " failed. Assertion \"" + e.ToString() + "\" was false.";
     Console.WriteLine(s);
 }