Example #1
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveType(varScope, compiler);
            if (!this.Condition.ResolvedType.IsIdentical(PType.INT))
            {
                throw new ParserException(this.Condition.FirstToken, "Only ints can be used in switch statements.");
            }

            // consider it all one scope
            for (int i = 0; i < this.Chunks.Length; ++i)
            {
                SwitchChunk chunk = this.Chunks[i];
                for (int j = 0; j < chunk.Cases.Length; ++j)
                {
                    Expression ex = chunk.Cases[j];
                    if (ex != null)
                    {
                        ex             = ex.ResolveType(varScope, compiler);
                        chunk.Cases[j] = ex;
                        if (ex.ResolvedType.RootValue != "int")
                        {
                            throw new ParserException(ex.FirstToken, "Only ints may be used.");
                        }
                    }
                }

                Executable.ResolveTypes(chunk.Code, varScope, compiler);
            }
        }
Example #2
0
        internal override void ResolveTypes(VariableScope varScope, PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveType(varScope, compiler);
            PType conditionType = this.Condition.ResolvedType;
            bool  isInt         = conditionType.IsIdentical(compiler, PType.INT);
            bool  isChar        = !isInt && conditionType.IsIdentical(compiler, PType.CHAR);

            if (!isInt && !isChar)
            {
                throw new ParserException(this.Condition.FirstToken, "Only ints and chars can be used in switch statements.");
            }

            // consider it all one scope
            for (int i = 0; i < this.Chunks.Length; ++i)
            {
                SwitchChunk chunk = this.Chunks[i];
                for (int j = 0; j < chunk.Cases.Length; ++j)
                {
                    Expression ex = chunk.Cases[j];
                    if (ex != null)
                    {
                        ex             = ex.ResolveType(varScope, compiler);
                        chunk.Cases[j] = ex;
                        if ((isInt && ex.ResolvedType.RootValue != "int") ||
                            (isChar && ex.ResolvedType.RootValue != "char"))
                        {
                            throw new ParserException(ex.FirstToken, isInt ? "Only ints may be used." : "Only chars may be used.");
                        }
                    }
                }

                Executable.ResolveTypes(chunk.Code, varScope, compiler);
            }
        }
Example #3
0
 internal override Executable ResolveWithTypeContext(PastelCompiler compiler)
 {
     this.Condition = this.Condition.ResolveWithTypeContext(compiler);
     for (int i = 0; i < this.Chunks.Length; ++i)
     {
         SwitchChunk chunk = this.Chunks[i];
         for (int j = 0; j < chunk.Cases.Length; ++j)
         {
             if (chunk.Cases[j] != null)
             {
                 chunk.Cases[j] = chunk.Cases[j].ResolveWithTypeContext(compiler);
             }
         }
         Executable.ResolveWithTypeContext(compiler, chunk.Code);
     }
     return(this);
 }
Example #4
0
        public override Executable ResolveNamesAndCullUnusedCode(PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveNamesAndCullUnusedCode(compiler);
            for (int i = 0; i < this.Chunks.Length; ++i)
            {
                SwitchChunk chunk = this.Chunks[i];
                for (int j = 0; j < chunk.Cases.Length; ++j)
                {
                    if (chunk.Cases[j] != null)
                    {
                        chunk.Cases[j] = chunk.Cases[j].ResolveNamesAndCullUnusedCode(compiler);
                    }
                }

                chunk.Code = Executable.ResolveNamesAndCullUnusedCodeForBlock(chunk.Code, compiler).ToArray();
            }
            return(this);
        }
Example #5
0
        internal override Executable ResolveWithTypeContext(PastelCompiler compiler)
        {
            this.Condition = this.Condition.ResolveWithTypeContext(compiler);
            HashSet <int> values = new HashSet <int>();

            for (int i = 0; i < this.Chunks.Length; ++i)
            {
                SwitchChunk chunk = this.Chunks[i];
                for (int j = 0; j < chunk.Cases.Length; ++j)
                {
                    if (chunk.Cases[j] != null)
                    {
                        chunk.Cases[j] = chunk.Cases[j].ResolveWithTypeContext(compiler);
                        InlineConstant ic = chunk.Cases[j] as InlineConstant;
                        if (ic == null)
                        {
                            throw new ParserException(chunk.Cases[j].FirstToken, "Only constants may be used as switch cases.");
                        }
                        int value;
                        if (ic.ResolvedType.RootValue == "char")
                        {
                            value = (char)ic.Value;
                        }
                        else
                        {
                            value = (int)ic.Value;
                        }
                        if (values.Contains(value))
                        {
                            throw new ParserException(chunk.Cases[j].FirstToken, "This cases appears multiple times.");
                        }
                        values.Add(value);
                    }
                }
                Executable.ResolveWithTypeContext(compiler, chunk.Code);
            }
            return(this);
        }