예제 #1
0
        public override AstNode Visit(CaseLabel node)
        {
            // Get the constant expression.
            Expression constant = node.GetConstant();

            // Expand it.
            if(constant != null)
            {
                constant = (Expression)constant.Accept(this);
                node.SetConstant(constant);

                // Get the constant value.
                IChelaType coercionType = currentSwitch.GetCoercionType();
                ConstantValue constantValue = (ConstantValue)constant.GetNodeValue();
                constantValue = constantValue.Cast(coercionType);

                // Make sure the case definition is unique.
                IDictionary<ConstantValue, CaseLabel> caseDict = currentSwitch.CaseDictionary;
                CaseLabel oldCase;
                if(caseDict.TryGetValue(constantValue, out oldCase))
                    Error(node, "previous definition of the same case in {0}.", oldCase.GetPosition().ToString());

                // Register the case.
                caseDict.Add(constantValue, node);
            }

            // Visit the children.
            VisitList(node.GetChildren());

            return node;
        }
예제 #2
0
        public override AstNode Visit(CaseLabel node)
        {
            // Get the constant expr.
            Expression constantExpr = node.GetConstant();
            if(constantExpr != null)
            {
                // Visit the constant expression.
                constantExpr.Accept(this);

                // Perform coercion.
                IChelaType constantType = constantExpr.GetNodeType();
                IChelaType coercionType = node.GetCoercionType();
                if(Coerce(coercionType, constantType) != coercionType)
                    Error(node, "incompatible constant type {0} -> {1}.", constantType.GetDisplayName(), coercionType.GetDisplayName());

                // Delay the case registration to the constant expansion pass.
            }
            else
            {
                // Make sure there's only one default statement.
                AstNode oldDefault = currentSwitch.GetDefaultCase();
                if(oldDefault != null)
                    Error(node, "only one default case is allowed in a switch statement. Previous definition in {0}", oldDefault.GetPosition().ToString());

                // Register the default case.
                currentSwitch.SetDefaultCase(node);
            }

            // Visit the children statements.
            AstNode children = node.GetChildren();
            VisitList(node.GetChildren());

            // The last case cannot be empty.
            if(children == null && node.GetNext() == null)
                Error(node, "last case in a switch cannot be empty.");

            return node;
        }