Пример #1
0
        internal override IList <Executable> Resolve(Parser parser)
        {
            ConstantResolutionState resolutionState = parser.ConstantAndEnumResolutionState[this];

            if (resolutionState == ConstantResolutionState.RESOLVED)
            {
                return(new Executable[0]);
            }
            if (resolutionState == ConstantResolutionState.RESOLVING)
            {
                throw new ParserException(this.FirstToken, "The resolution of this enum creates a cycle.");
            }
            parser.ConstantAndEnumResolutionState[this] = ConstantResolutionState.RESOLVING;

            this.Expression = this.Expression.Resolve(parser);

            if (this.Expression is IntegerConstant ||
                this.Expression is BooleanConstant ||
                this.Expression is FloatConstant ||
                this.Expression is StringConstant)
            {
                // that's fine.
            }
            else
            {
                throw new ParserException(this.FirstToken, "Invalid value for const. Expression must resolve to a constant at compile time.");
            }

            parser.ConstantAndEnumResolutionState[this] = ConstantResolutionState.RESOLVED;

            return(new Executable[0]);
        }
Пример #2
0
        internal override Expression Resolve(ParserContext parser)
        {
            ConstantResolutionState resolutionState = parser.ConstantAndEnumResolutionState[this.EnumDefinition];

            if (resolutionState != ConstantResolutionState.RESOLVED)
            {
                this.EnumDefinition.Resolve(parser);
            }

            if (this.EnumDefinition.IntValue.ContainsKey(this.Field))
            {
                return(new IntegerConstant(this.FirstToken, this.EnumDefinition.IntValue[this.Field], this.Owner));
            }
            throw new ParserException(this.FieldToken, "The enum '" + this.EnumDefinition.Name + "' does not contain a definition for '" + this.Field + "'");
        }
Пример #3
0
        internal override void Resolve(Parser parser)
        {
            ConstantResolutionState resolutionState = parser.ConstantAndEnumResolutionState[this];

            if (resolutionState == ConstantResolutionState.RESOLVED)
            {
                return;
            }
            if (resolutionState == ConstantResolutionState.RESOLVING)
            {
                throw new ParserException(this.FirstToken, "The resolution of this enum creates a cycle.");
            }
            parser.ConstantAndEnumResolutionState[this] = ConstantResolutionState.RESOLVING;

            this.Expression = this.Expression.Resolve(parser);

            if (!(this.Expression is IConstantValue))
            {
                throw new ParserException(this.FirstToken, "Invalid value for const. Expression must resolve to a constant at compile time.");
            }

            parser.ConstantAndEnumResolutionState[this] = ConstantResolutionState.RESOLVED;
        }
Пример #4
0
        internal override Expression Resolve(Parser parser)
        {
            this.Root = this.Root.Resolve(parser);

            string step = this.StepToken.Value;

            if (this.Root is EnumReference)
            {
                EnumDefinition enumDef = ((EnumReference)this.Root).EnumDefinition;

                ConstantResolutionState resolutionState = parser.ConstantAndEnumResolutionState[enumDef];
                if (resolutionState != ConstantResolutionState.RESOLVED)
                {
                    enumDef.Resolve(parser);
                }

                switch (step)
                {
                case "length":
                    return(new IntegerConstant(this.FirstToken, enumDef.IntValue.Count, this.Owner));

                case "max":
                    return(new SpecialEntity.EnumMaxFunction(this.FirstToken, enumDef, this.Owner));

                case "values":
                    return(new SpecialEntity.EnumValuesFunction(this.FirstToken, enumDef, this.Owner));
                }

                if (enumDef.IntValue.ContainsKey(step))
                {
                    return(new IntegerConstant(this.FirstToken, enumDef.IntValue[step], this.Owner));
                }
                else
                {
                    throw new ParserException(this.StepToken, "The enum '" + enumDef.Name + "' does not contain a definition for '" + step + "'");
                }
            }

            if (this.Root is BaseKeyword)
            {
                return(new BaseMethodReference(this.Root.FirstToken, this.DotToken, this.StepToken, this.Owner).Resolve(parser));
            }

            if (this.Root is StringConstant)
            {
                if (step == "join")
                {
                    throw new ParserException(this.StepToken,
                                              "There is no join method on strings. Did you mean to do list.join(string) instead?");
                }
                else if (step == "size")
                {
                    throw new ParserException(this.StepToken, "String size is indicated by string.length.");
                }
                else if (step == "length")
                {
                    int length = ((StringConstant)this.Root).Value.Length;
                    return(new IntegerConstant(this.FirstToken, length, this.Owner));
                }
            }

            return(this);
        }
Пример #5
0
        internal override void Resolve(ParserContext parser)
        {
            ConstantResolutionState resolutionState = parser.ConstantAndEnumResolutionState[this];

            if (resolutionState == ConstantResolutionState.RESOLVED)
            {
                return;
            }
            if (resolutionState == ConstantResolutionState.RESOLVING)
            {
                throw new ParserException(this, "The resolution of this enum creates a cycle.");
            }
            parser.ConstantAndEnumResolutionState[this] = ConstantResolutionState.RESOLVING;

            HashSet <int> consumed = new HashSet <int>();

            for (int i = 0; i < this.Items.Length; ++i)
            {
                string itemName = this.Items[i].Value;

                if (itemName == "length")
                {
                    throw new ParserException(this.Items[i], "The name 'length' is not allowed as an enum value as it is a reserved field. In general, enum members should be in ALL CAPS anyway.");
                }

                if (this.IntValue.ContainsKey(itemName))
                {
                    throw new ParserException(this.Items[i], "Duplicate item in same enum. ");
                }

                this.IntValue[itemName] = -1;

                if (this.Values[i] != null)
                {
                    IntegerConstant ic = this.Values[i].Resolve(parser) as IntegerConstant;
                    if (ic == null)
                    {
                        throw new ParserException(this.Values[i], "Enum values must be integers or left blank.");
                    }
                    this.Values[i] = ic;
                    if (consumed.Contains(ic.Value))
                    {
                        throw new ParserException(this.Values[i], "This integer value has already been used in the same enum.");
                    }

                    consumed.Add(ic.Value);
                    this.IntValue[itemName] = ic.Value;
                }
            }
            parser.ConstantAndEnumResolutionState[this] = ConstantResolutionState.RESOLVED;

            int next = 0;

            for (int i = 0; i < this.Items.Length; ++i)
            {
                if (this.Values[i] == null)
                {
                    while (consumed.Contains(next))
                    {
                        ++next;
                    }

                    this.IntValue[this.Items[i].Value] = next;
                    consumed.Add(next);
                }
            }
        }