Click here to Skip to main content
15,885,278 members
Articles / Containers / Virtual Machine

Twiggery Scripting Language

Rate me:
Please Sign up or sign in to vote.
4.82/5 (14 votes)
12 Aug 2010LGPL313 min read 63.7K   1.1K   36  
Twiggery Scripting Language
using System;
using System.Collections.Generic;
using System.Text;
using num = System.Single;

namespace Twiggery
{
    public partial class TVM
    {
        /// <summary>
        /// Base class of ASM instructions
        /// </summary>
        public abstract class Asm
        {
            #region Variables
            protected byte opcode = 0;
            /// <summary>
            /// Opcode
            /// </summary>
            public byte Opcode
            {
                get { return opcode; }
            }

            protected num[] operand = null;
            /// <summary>
            /// Operand
            /// </summary>
            public num[] Operand
            {
                get { return operand; }
            }
            #endregion
            #region Assist
            /// <summary>
            /// Byte code to Type
            /// </summary>
            public static Dictionary<byte, Type> BYTE_TYPE = null;

            /// <summary>
            /// Type to Byte code
            /// </summary>
            public static Dictionary<Type, byte> TYPE_BYTE = null;

            /// <summary>
            /// Initialize ASM instruction system
            /// </summary>
            public static void Initialize()
            {
                BYTE_TYPE = new Dictionary<byte, Type>();
                TYPE_BYTE = new Dictionary<Type, byte>();
                #region Memory operation instruction
                BYTE_TYPE.Add(127, typeof(MOV));
                TYPE_BYTE.Add(typeof(MOV), 127);
                BYTE_TYPE.Add(126, typeof(LAM));
                TYPE_BYTE.Add(typeof(LAM), 126);
                #endregion
                #region Numeric calculation instruction
                BYTE_TYPE.Add(119, typeof(ADD));
                TYPE_BYTE.Add(typeof(ADD), 119);
                BYTE_TYPE.Add(118, typeof(SUB));
                TYPE_BYTE.Add(typeof(SUB), 118);
                BYTE_TYPE.Add(117, typeof(MUL));
                TYPE_BYTE.Add(typeof(MUL), 117);
                BYTE_TYPE.Add(116, typeof(DIV));
                TYPE_BYTE.Add(typeof(DIV), 116);
                BYTE_TYPE.Add(115, typeof(MOD));
                TYPE_BYTE.Add(typeof(MOD), 115);
                #endregion
                #region Numeric comparison instruction
                BYTE_TYPE.Add(109, typeof(CE));
                TYPE_BYTE.Add(typeof(CE), 109);
                BYTE_TYPE.Add(108, typeof(CLE));
                TYPE_BYTE.Add(typeof(CLE), 108);
                BYTE_TYPE.Add(107, typeof(CGE));
                TYPE_BYTE.Add(typeof(CGE), 107);
                BYTE_TYPE.Add(106, typeof(CL));
                TYPE_BYTE.Add(typeof(CL), 106);
                BYTE_TYPE.Add(105, typeof(CG));
                TYPE_BYTE.Add(typeof(CG), 105);
                BYTE_TYPE.Add(104, typeof(CNE));
                TYPE_BYTE.Add(typeof(CNE), 104);
                #endregion
                #region Boolean operation instruction
                BYTE_TYPE.Add(99, typeof(AND));
                TYPE_BYTE.Add(typeof(AND), 99);
                BYTE_TYPE.Add(98, typeof(OR));
                TYPE_BYTE.Add(typeof(OR), 98);
                BYTE_TYPE.Add(97, typeof(NOT));
                TYPE_BYTE.Add(typeof(NOT), 97);
                #endregion
                #region Instruction jump
                BYTE_TYPE.Add(10, typeof(JMP));
                TYPE_BYTE.Add(typeof(JMP), 10);
                BYTE_TYPE.Add(11, typeof(JF));
                TYPE_BYTE.Add(typeof(JF), 11);
                BYTE_TYPE.Add(12, typeof(JT));
                TYPE_BYTE.Add(typeof(JT), 12);
                #endregion
                #region Other special instruction
                BYTE_TYPE.Add(0, typeof(HLT));
                TYPE_BYTE.Add(typeof(HLT), 0);
                BYTE_TYPE.Add(1, typeof(CALL));
                TYPE_BYTE.Add(typeof(CALL), 1);
                BYTE_TYPE.Add(2, typeof(ARG));
                TYPE_BYTE.Add(typeof(ARG), 2);
                BYTE_TYPE.Add(3, typeof(HAL));
                TYPE_BYTE.Add(typeof(HAL), 3);
                #endregion
            }

            /// <summary>
            /// Convert from int to byte[]
            /// </summary>
            /// <param name="arg">num</param>
            /// <returns>byte[]</returns>
            protected static byte[] parseNumberToBytes(num arg)
            {
                byte[] buffer = BitConverter.GetBytes(arg);

                return buffer;
            }

            /// <summary>
            /// Conver byte[] to int
            /// </summary>
            /// <param name="arg">byte[]</param>
            /// <returns>num</returns>
            protected static num parseBytesToNumber(byte[] arg)
            {
                if (typeof(num) == typeof(float))
                {
                    return BitConverter.ToSingle(arg, 0);
                }
                else if (typeof(num) == typeof(int))
                {
                    return BitConverter.ToInt32(arg, 0);
                }

                return num.MinValue;
            }
            #endregion
            #region Analyze
            /// <summary>
            /// Convert ASM instruction into bytecode
            /// </summary>
            /// <param name="asmOp">ASM instruction</param>
            /// <param name="bytes">Bytecode buffer</param>
            public static void ToBytes(Asm asm, ref List<byte> bytes)
            {
                num op1 = asm.operand.Length >= 1 ? asm.operand[0] : 0;
                num op2 = asm.operand.Length >= 2 ? asm.operand[1] : 0;

                byte[] bBuffer1 = parseNumberToBytes(op1);
                byte[] bBuffer2 = parseNumberToBytes(op2);

                bytes.Add(asm.opcode);
                for (int i = 0; i < 4; i++)
                    bytes.Add(bBuffer1[i]);
                for (int i = 0; i < 4; i++)
                    bytes.Add(bBuffer2[i]);
            }

            /// <summary>
            /// Convert bytecode into ASM instruction
            /// </summary>
            /// <param name="bytes">Bytecode buffer</param>
            /// <returns>ASM instruction</returns>
            public static Asm FromBytes(ref List<byte> bytes)
            {
                byte op = bytes[0];
                bytes.RemoveAt(0);
                byte[] bOp1 ={ bytes[0], bytes[1], bytes[2], bytes[3] };
                bytes.RemoveRange(0, 4);
                byte[] bOp2 ={ bytes[0], bytes[1], bytes[2], bytes[3] };
                bytes.RemoveRange(0, 4);

                num op1 = parseBytesToNumber(bOp1);
                num op2 = parseBytesToNumber(bOp2);
                Type t = BYTE_TYPE[op];
                Asm asm = (Asm)Activator.CreateInstance(t);
                if (asm.operand.Length >= 1)
                    asm.operand[0] = op1;
                if (asm.operand.Length >= 2)
                    asm.operand[1] = op2;

                return asm;
            }
            #endregion
        }
        #region Memory operation instruction
        /// <summary>
        /// Copy data
        /// </summary>
        public class MOV : Asm
        {
            public MOV()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Set addressing mode
        /// </summary>
        public class LAM : Asm
        {
            public LAM()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[1];
            }
        }
        #endregion
        #region Numeric calculation instruction
        /// <summary>
        /// Add
        /// </summary>
        public class ADD : Asm
        {
            public ADD()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Minus
        /// </summary>
        public class SUB : Asm
        {
            public SUB()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Multiply
        /// </summary>
        public class MUL : Asm
        {
            public MUL()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Divide
        /// </summary>
        public class DIV : Asm
        {
            public DIV()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Mod
        /// </summary>
        public class MOD : Asm
        {
            public MOD()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }
        #endregion
        #region Numeric comparison instruction
        /// <summary>
        /// Equal
        /// </summary>
        public class CE : Asm
        {
            public CE()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Less or equal
        /// </summary>
        public class CLE : Asm
        {
            public CLE()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Greater or equal
        /// </summary>
        public class CGE : Asm
        {
            public CGE()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Less
        /// </summary>
        public class CL : Asm
        {
            public CL()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Greater
        /// </summary>
        public class CG : Asm
        {
            public CG()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Not equal
        /// </summary>
        public class CNE : Asm
        {
            public CNE()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }
        #endregion
        #region Boolean operation instruction
        /// <summary>
        /// And
        /// </summary>
        public class AND : Asm
        {
            public AND()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Or
        /// </summary>
        public class OR : Asm
        {
            public OR()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[2];
            }
        }

        /// <summary>
        /// Not
        /// </summary>
        public class NOT : Asm
        {
            public NOT()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[1];
            }
        }
        #endregion
        #region Instruction jump
        /// <summary>
        /// Jump without conditions
        /// </summary>
        public class JMP : Asm
        {
            public JMP()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[1];
            }
        }

        /// <summary>
        /// Jump if false
        /// </summary>
        public class JF : Asm
        {
            public JF()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[1];
            }
        }

        /// <summary>
        /// Jump if true
        /// </summary>
        public class JT : Asm
        {
            public JT()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[1];
            }
        }
        #endregion
        #region Other special instruction
        /// <summary>
        /// Halt
        /// </summary>
        public class HLT : Asm
        {
            public HLT()
            {
                opcode = TYPE_BYTE[this.GetType()];
            }
        }
        /// <summary>
        /// Function call
        /// </summary>
        public class CALL : Asm
        {
            public CALL()
            {
                opcode = TYPE_BYTE[this.GetType()];
                // The first operand is the index of a function in the function table,
                // and the second one is the arguments count
                operand = new num[2];
            }
        }
        /// <summary>
        /// Push function argument
        /// Push an argument addressing mode and data
        /// </summary>
        public class ARG : Asm
        {
            public ARG()
            {
                opcode = TYPE_BYTE[this.GetType()];
                // The first operand is the addressing mode,
                // the second one is the data
                operand = new num[2];
            }
        }
        /// <summary>
        /// Heap alloc request
        /// </summary>
        public class HAL : Asm
        {
            public HAL()
            {
                opcode = TYPE_BYTE[this.GetType()];
                operand = new num[1];
            }
        }
        #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 GNU Lesser General Public License (LGPLv3)


Written By
Architect
China China
Video game player & creator; Hardware geek & maker.

Comments and Discussions