Click here to Skip to main content
15,891,316 members
Articles / Containers / Virtual Machine

Conscript IDE: An Integrated Development Environment (IDE) implementation for the Conscript scripting language

Rate me:
Please Sign up or sign in to vote.
4.90/5 (23 votes)
4 Sep 2008CPOL4 min read 100.8K   2.2K   158  
The third and final article in the Conscript .NET scripting engine article series.
using System;
using System.Collections.Generic;
using System.Text;

namespace Conscript.Runtime
{
    /// <summary>
    /// Underlying implementation of the script's array type.
    /// </summary>
    public class AssociativeArray
        : Dictionary<object, object>
    {
        #region Private Methods

        private void OutputValue(StringBuilder stringBuilder, object objectValue)
        {
            if (objectValue.GetType() == typeof(String))
            {
                stringBuilder.Append("\"");
                stringBuilder.Append(objectValue);
                stringBuilder.Append("\"");
            }
            else
                stringBuilder.Append(objectValue);
        }

        private bool EqualValues(object objectValue1, object objectValue2)
        {
            Type type1 = objectValue1.GetType();
            Type type2 = objectValue2.GetType();

            if (type1 == typeof(int) && type2 == typeof(int))
                return (int)objectValue1 == (int)objectValue2;
            else if (type1 == typeof(int) && type2 == typeof(float))
                return (int)objectValue1 == (float)objectValue2;
            else if (type1 == typeof(float) && type2 == typeof(int))
                return (float)objectValue1 == (int)objectValue2;
            else if (type1 == typeof(float) && type2 == typeof(float))
                return (float)objectValue1 == (float)objectValue2;
            else if (type1 == typeof(String) || type2 == typeof(String))
                return objectValue1.ToString() == objectValue2.ToString();
            else
                return objectValue1 == objectValue2;
        }

        private void AddValue(object objectValue)
        {
            int iIndex = 0;
            while (ContainsKey(iIndex))
                ++iIndex;
            this[iIndex] = objectValue;
        }

        private void SubtractValue(object objectValue)
        {
            List<object> listValues = new List<object>();
            foreach (object objectOldValue in Values)
                if (!EqualValues(objectOldValue, objectValue))
                    listValues.Add(objectOldValue);

            Clear();
            int iIndex = 0;
            foreach (Object objectOldValue in listValues)
                this[iIndex++] = objectOldValue;
        }

        private void AddArray(AssociativeArray assocativeArray)
        {
            int iIndex = 0;
            while (ContainsKey(iIndex)) ++iIndex;

            foreach (object objectValue in assocativeArray.Values)
                this[iIndex++] = objectValue;
        }

        private void SubtractArray(AssociativeArray associativeArray)
        {
            foreach (object objectValue in associativeArray.Values)
                SubtractValue(objectValue);
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Adds a simple value using an automatically generated numeric
        /// index, or appends the context of another array.
        /// </summary>
        /// <param name="objectValue">Simple or array value to add.</param>
        public void Add(object objectValue)
        {
            if (objectValue.GetType() == typeof(AssociativeArray))
                AddArray((AssociativeArray)objectValue);
            else
                AddValue(objectValue);
        }

        /// <summary>
        /// Removes the given element value or performs a set
        /// subtraction if the given parameter is an array.
        /// </summary>
        /// <param name="objectValue">Simple or array value to remove.
        /// </param>
        public void Subtract(object objectValue)
        {
            if (objectValue.GetType() == typeof(AssociativeArray))
                SubtractArray((AssociativeArray)objectValue);
            else
                SubtractValue(objectValue);
        }

        /// <summary>
        /// Returns a string representation of the array.
        /// </summary>
        /// <returns>String representation of the array.</returns>
        public override string ToString()
        {
            StringBuilder stringBuilder
                = new StringBuilder();

            stringBuilder.Append("{");

            bool bFirst = true;
            foreach (object objectKey in Keys)
            {
                if (!bFirst)
                    stringBuilder.Append(", ");
                bFirst = false;

                OutputValue(stringBuilder, objectKey);

                stringBuilder.Append(":");

                OutputValue(stringBuilder, this[objectKey]);

            }

            stringBuilder.Append("}");

            return stringBuilder.ToString();
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Returns an array element using the given index object.
        /// </summary>
        /// <param name="objectKey">Index object.</param>
        /// <returns>Array element returned by the indexer.</returns>
        public new object this[object objectKey]
        {
            get
            {
                // handle size property
                if (objectKey.GetType() == typeof(String)
                    && ((String)objectKey) == "size")
                    return this.Count;

                if (!ContainsKey(objectKey))
                    return NullReference.Instance;

                return base[objectKey];
            }
            set
            {
                // handle null key
                if (objectKey == null)
                    objectKey = NullReference.Instance;

                // handle size property
                if (objectKey.GetType() == typeof(String)
                    && ((String)objectKey) == "size")
                    throw new ExecutionException("Cannot modify read-only array property 'size'.");

                // handle null value
                if (value == null)
                    base[objectKey] = NullReference.Instance;
                else
                    base[objectKey] = value;
            }
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Malta Malta
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions