Click here to Skip to main content
15,885,067 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.3K   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;

using Conscript.Compiler;
using Conscript.Runtime;

namespace Conscript.Runtime
{
    /// <summary>
    /// Byte code operand representation.
    /// </summary>
    public class Operand
    {
        #region Private Variables

        private OperandType m_operandType;
        private object m_objectValue;
        private object m_objectIndex;

        #endregion

        #region Private Methods

        private Operand(OperandType operandType, object objectValue, object objectIndex)
        {
            m_operandType = operandType;
            m_objectValue = objectValue;
            m_objectIndex = objectIndex;
        }

        private String ToString(object objectValue)
        {
            if (objectValue.GetType() == typeof(String))
                return "\"" + objectValue + "\"";
            else
                return objectValue.ToString();
        }

        #endregion

        #region Public Static Methods

        /// <summary>
        /// Creates a literal operand using the given literal value.
        /// </summary>
        /// <param name="objectValue">Literal value.</param>
        /// <returns>Literal operand.</returns>
        public static Operand CreateLiteral(object objectValue)
        {
            return new Operand(OperandType.Literal, objectValue, null);
        }

        /// <summary>
        /// Creates a variable operand using the given variable identifier.
        /// </summary>
        /// <param name="strIdentifier">Variable identifier.</param>
        /// <returns>Simple variable operand</returns>
        public static Operand CreateVariable(String strIdentifier)
        {
            return new Operand(OperandType.Variable, strIdentifier, null);
        }

        /// <summary>
        /// Creates a variable reference indexed by a literal value.
        /// </summary>
        /// <param name="strIdentifier">Identifier for the indexed variable.</param>
        /// <param name="objectIndex">Literal index.</param>
        /// <returns>Literal-indexed variable operand.</returns>
        public static Operand CreateLiteralIndexedVariable(
            String strIdentifier, object objectIndex)
        {
            return new Operand(OperandType.LiteralIndexedVariable, strIdentifier, objectIndex);
        }

        /// <summary>
        /// Creates a variable reference indexed by another variable.
        /// </summary>
        /// <param name="strIdentifier">Identifier for the indexed variable.
        /// </param>
        /// <param name="strIndexIdentifier">Identifier for the index.</param>
        /// <returns>Variable-indexed variable operand.</returns>
        public static Operand CreateVariableIndexedVariable(
            String strIdentifier, String strIndexIdentifier)
        {
            return new Operand(OperandType.VariableIndexedVariable, strIdentifier, strIndexIdentifier);
        }

        /// <summary>
        /// Creates a <see cref="ScriptInstruction"/> reference.
        /// </summary>
        /// <param name="scriptInstruction">Script instruction referred by
        /// the operand.</param>
        /// <returns>Script instruction reference operand.</returns>
        public static Operand CreateInstructionRef(
            ScriptInstruction scriptInstruction)
        {
            return new Operand(OperandType.InstructionRef, scriptInstruction, null);
        }

        /// <summary>
        /// Creates a <see cref="ScriptFunction"/> reference.
        /// </summary>
        /// <param name="scriptFunction">Script function referred by
        /// the operand.</param>
        /// <returns>Script function reference operand.</returns>
        public static Operand CreateScriptFunctionRef(
            ScriptFunction scriptFunction)
        {
            return new Operand(OperandType.ScriptFunctionRef, scriptFunction, null);
        }

        /// <summary>
        /// Creates a <see cref="HostFunctionPrototype"/> reference.
        /// </summary>
        /// <param name="hostFunctionPrototype">Host function referred by
        /// the operand.</param>
        /// <returns>Host function reference operand.</returns>
        public static Operand CreateHostFunctionRef(
            HostFunctionPrototype hostFunctionPrototype)
        {
            return new Operand(OperandType.HostFunctionRef, hostFunctionPrototype, null);
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Returns a string representation of the operand.
        /// </summary>
        /// <returns>String representation of the operand.</returns>
        public override string ToString()
        {
            switch (m_operandType)
            {
                case OperandType.Literal:
                    return ToString(m_objectValue);
                case OperandType.Variable:
                    return m_objectValue.ToString();
                case OperandType.LiteralIndexedVariable:
                    return m_objectValue + "[" + ToString(m_objectIndex) + "]";
                case OperandType.VariableIndexedVariable:
                    return m_objectValue + "[" + m_objectIndex + "]";
                case OperandType.InstructionRef:
                    return "[" + ((ScriptInstruction) m_objectValue).Address.ToString("00000000") + "]";
                case OperandType.ScriptFunctionRef:
                    {
                        ScriptFunction scriptFunction = (ScriptFunction)m_objectValue;
                        return "[" + scriptFunction.EntryPoint.Address.ToString("00000000") + "] : " + scriptFunction.Name + "(...)";
                    }
                case OperandType.HostFunctionRef:
                    return m_objectValue.ToString();
                default:
                    return m_operandType.ToString();
            }
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// The operand's <see cref="OperandType"/>.
        /// </summary>
        public OperandType Type
        {
            get { return m_operandType; }
            set { m_operandType = value; }
        }

        /// <summary>
        /// Value interpretation of the operand.
        /// </summary>
        public object Value
        {
            get { return m_objectValue; }
        }

        /// <summary>
        /// Index literal interpretation of the operand.
        /// </summary>
        public object IndexLiteral
        {
            get
            {
                if (m_operandType != OperandType.LiteralIndexedVariable)
                    throw new ExecutionException(
                        "Index identifier can only be accessed for literal-indexed variables.");
                return m_objectIndex;
            }
            set
            {
                if (m_operandType != OperandType.LiteralIndexedVariable)
                    throw new ExecutionException(
                        "Index identifier can only be accessed for literal-indexed variables.");
                m_objectIndex = value;
            }
        }

        /// <summary>
        /// Index variable interpretation of the operand.
        /// </summary>
        public String IndexIdentifier
        {
            get
            {
                if (m_operandType != OperandType.VariableIndexedVariable)
                    throw new ExecutionException(
                        "Index identifier can only be accessed for variable-indexed variables.");
                return (String) m_objectIndex; 
            }
            set
            {
                if (m_operandType != OperandType.VariableIndexedVariable)
                    throw new ExecutionException(
                        "Index identifier can only be accessed for variable-indexed variables.");
                m_objectIndex = value;
            }
        }

        /// <summary>
        /// <see cref="ScriptInstruction"/> interpretation of the operand.
        /// </summary>
        public ScriptInstruction InstructionRef
        {
            get
            {
                if (m_operandType != OperandType.InstructionRef)
                    throw new ParserException(
                        "Operand is not an instruction reference.");

                return (ScriptInstruction) m_objectValue;
            }
            set
            {
                if (m_operandType != OperandType.InstructionRef)
                    throw new ParserException(
                        "Operand is not an instruction reference.");

                m_objectValue = value;
            }
        }

        /// <summary>
        /// <see cref="ScriptFunction"/> interpretation of the operand.
        /// </summary>
        public ScriptFunction ScriptFunctionRef
        {
            get
            {
                if (m_operandType != OperandType.ScriptFunctionRef)
                    throw new ParserException(
                        "Operand is not a script function reference.");

                return (ScriptFunction)m_objectValue;
            }
            set
            {
                if (m_operandType != OperandType.ScriptFunctionRef)
                    throw new ParserException(
                        "Operand is not a script function reference.");

                m_objectValue = value;
            }
        }

        /// <summary>
        /// <see cref="HostFunctionPrototype"/> interpretation of the
        /// operand.
        /// </summary>
        public HostFunctionPrototype HostFunctionRef
        {
            get
            {
                if (m_operandType != OperandType.HostFunctionRef)
                    throw new ParserException(
                        "Operand is not a host function reference.");

                return (HostFunctionPrototype)m_objectValue;
            }
            set
            {
                if (m_operandType != OperandType.HostFunctionRef)
                    throw new ParserException(
                        "Operand is not a host function reference.");

                m_objectValue = 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