示例#1
0
        /// <summary>
        /// This method is responsible for parsing an object property
        /// reference line from inside of a .con or .ai file, and converting
        /// the property into a C# property
        /// </summary>
        /// <remarks>
        /// The type of value is figured out within the method, but only certain types of
        /// object types can be parsed here.
        /// </remarks>
        /// <param name="token">The token for this ObjectProperty</param>
        /// <param name="objectLevel">Specifies the nested object level for this Property</param>
        public virtual void Parse(Token token, int objectLevel = 0)
        {
            // Seperate our property name and values
            TokenArgs tokenArgs = token.TokenArgs;
            string    propName  = tokenArgs.PropertyNames[objectLevel];

            // Fetch our property that we are setting the value to
            KeyValuePair <string, PropertyInfo> prop = GetProperty(propName);
            Type propType     = prop.Value.PropertyType;
            bool isCollection = propType.GetInterface("IObjectPropertyCollection") != null;

            // Get the value that is set
            var value = prop.Value.GetValue(this);

            // Is this an object method, or Object Property?
            if (propType.BaseType.Name == "ObjectMethod")
            {
                // Object methods are always instantiated in the object's constructor
                ObjectMethod method = (ObjectMethod)value;
                ConFileEntry item   = method.Invoke(token);

                // Add item to the file entry list
                if (item != null)
                {
                    token.File?.AddEntry(item, token);
                }
            }
            else
            {
                // If the value is null, then we create a new object property instance
                ObjectProperty obj = (ObjectProperty)value;
                if (obj == null)
                {
                    // Create instance and add it to the entries list
                    obj = ObjectProperty.Create(prop.Value, this, token);

                    // Add entry? Property Collections add thier own properties
                    if (!isCollection)
                    {
                        token.File?.AddProperty(obj);
                    }
                }

                // Create our instance, and parse
                obj.SetValue(token, objectLevel);
                prop.Value.SetValue(this, obj);
            }
        }
示例#2
0
        internal void AddPropertyAfter(ObjectProperty property, ConFileEntry afterItem)
        {
            // Make sure this entry doesnt already exist
            if (Entries.IndexOf(property) > 0)
                throw new Exception("The specified ObjectProperty already exists in this confile.");

            // Find the owner object
            int index = Entries.IndexOf(afterItem) + 1;
            if (index == 0)
                throw new Exception("The specified \"afterObject\" does not exist in this ConFile");

            // Insert item
            if (index == Entries.Count)
                Entries.Add(property);
            else
                Entries.Insert(index, property);
        }
示例#3
0
        /// <summary>
        /// Gets the Reference of an Expression, that occurs before the specified
        /// entry.
        /// </summary>
        /// <param name="name">The name of the variable or constant expression</param>
        /// <param name="beforeEntry">
        /// The entry where this variable or constant expression is referenced
        /// </param>
        /// <returns>
        /// Returns the last reference value of the specifed expression, occuring
        /// before the <paramref name="beforeEntry"/>
        /// </returns>
        public Expression GetExpressionReference(string name, ConFileEntry beforeEntry)
        {
            // Check to see if this expression exists
            if (!Expressions.ContainsKey(name))
                goto Undefined;

            // Grab the last reference before this confile entry
            int index = Entries.IndexOf(beforeEntry);
            if (index == -1)
                throw new Exception("The specified entry does not exist in this ConFile");

            // Now find the last set expression reference value
            for (int i = index - 1; i >= 0; i--)
            {
                ConFileEntry entry = Entries[i];
                TokenType kind = entry.Token.Kind;
                if (kind == TokenType.Constant || kind == TokenType.Variable)
                {
                    // cast to Expression
                    Expression exp = entry as Expression;
                    if (exp.Name == name)
                    {
                        // This expression hasnt been assigned yet.. shame
                        /***
                         * We have no way yet to determine if a variable is assigned
                         * inside an If/While statement, so skip for now
                         *
                         * if (String.IsNullOrWhiteSpace(exp.Value))
                            throw new Exception($"Value cannot be null; Expression \"{name}\" is unassigned");
                         */

                        return exp;
                    }
                }
            }

            // If we are here, the expression was not defined yet
            Undefined:
            {
                string err;
                if (name.StartsWith("c"))
                    err = $"Undefined constant \"{name}\"";
                else
                    err = $"Undefined variable \"{name}\"";

                throw new Exception(err);
            }
        }
示例#4
0
        /// <summary>
        /// Adds a new object to this confile, and returns it's reference
        /// </summary>
        /// <param name="entry"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public void AddEntry(ConFileEntry entry, Token token)
        {
            if (token.Kind == TokenType.RemComment)
            {
                return;
            }
            else if (token.Kind == TokenType.ObjectStart)
            {
                Objects.Add((ConFileObject)entry);
            }
            else if (token.Kind == TokenType.ActiveSwitch)
            {
                // Create a new reference and add it
                var reference = new ObjectReference()
                {
                    Token = token,
                    Object = (ConFileObject)entry
                };
                References.Add(reference);

                // Set entry to the object reference
                entry = reference;
            }
            else if (entry is Expression)
            {
                Expression exp = entry as Expression;
                if (!Expressions.ContainsKey(exp.Name))
                {
                    // Add the expression
                    Expressions.Add(exp.Name, new List<Expression>() { exp });
                }
            }

            // Always add the entry
            Entries.Add(entry);
        }