Click here to Skip to main content
15,892,575 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 64.3K   1.1K   36  
Twiggery Scripting Language
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using num = System.Single;
using AddressingMode = System.Int32;

namespace Twiggery
{
    /// <summary>
    /// AST node abstract base class
    /// </summary>
    public abstract class Twig
    {
        #region Variables
        /// <summary>
        /// Lex elements list, syntax head
        /// </summary>
        protected List<LexiconSplitter.Element> contextHead = null;

        /// <summary>
        /// Lex elements list, syntax body
        /// </summary>
        protected List<LexiconSplitter.Element> contextBody = null;

        /// <summary>
        /// Lex elements list, syntax tail
        /// </summary>
        protected List<LexiconSplitter.Element> contextTail = null;

        /// <summary>
        /// Current layer sub element of the syntax tree, syntax head
        /// </summary>
        protected Twig subTwigHead = null;

        /// <summary>
        /// Current layer sub element of the syntax tree, syntax body list
        /// </summary>
        protected List<Twig> subTwigBody = null;

        /// <summary>
        /// Current layer sub element of the syntax tree, syntax tail
        /// </summary>
        protected Twig subTwigTail = null;
        #endregion
        #region Helper
        /// <summary>
        /// Get body string of a Twig
        /// </summary>
        /// <param name="t">Head Twig</param>
        /// <returns>Result string</returns>
        public static string GetHeadText(Twig t)
        {
            string s = "";
            foreach (LexiconSplitter.Element e in t.contextHead)
                s += e.Text;

            return s;
        }

        /// <summary>
        /// Get body string of a Twig
        /// </summary>
        /// <param name="t">Body Twig</param>
        /// <returns>Result string</returns>
        public static string GetBodyText(Twig t)
        {
            string s = "";
            foreach (LexiconSplitter.Element e in t.contextBody)
                s += e.Text;

            return s;
        }

        /// <summary>
        /// Get tail string of a Twig
        /// </summary>
        /// <param name="t">Tail Twig</param>
        /// <returns>Result string</returns>
        public static string GetTailText(Twig t)
        {
            string s = "";
            foreach (LexiconSplitter.Element e in t.contextTail)
                s += e.Text;

            return s;
        }
        #endregion
        #region Parse
        /// <summary>
        /// Parse head
        /// </summary>
        protected virtual void parseHead()
        {
            int f = SyntaxChecker.GetInstance().FirstIndexOf(contextHead, "(");
            int l = SyntaxChecker.GetInstance().GetCloseBracketIndex(contextHead, f + 1, "(", ")");
            contextHead.RemoveRange(0, 2);
            contextHead.RemoveAt(contextHead.Count - 1);
            Twig t = new TwigFormula();
            t.Parse(ref contextHead);
            subTwigHead = t;
        }

        /// <summary>
        /// The last processed one
        /// </summary>
        private string lastElem = string.Empty;

        /// <summary>
        /// Parse body
        /// </summary>
        protected virtual void parseBody()
        {
            subTwigBody = new List<Twig>();
            while (contextBody.Count > 0)
            {
                LexiconSplitter.Element elem = contextBody[0];
                Twig t;
                if (elem.Text == "if")
                {
                    t = new TwigIf();
                }
                else if (elem.Text == "elseif")
                {
                    t = new TwigElseif();
                }
                else if (elem.Text == "else")
                {
                    t = new TwigElse();
                }
                else if (elem.Text == "for")
                {
                    t = new TwigFor();
                }
                else if (elem.Text == "while")
                {
                    t = new TwigWhile();
                }
                else if (elem.Text == "do")
                {
                    t = new TwigDoWhile();
                }
                else if (elem.Text == "break")
                {
                    t = new TwigBreak();
                }
                else if (elem.Text == "continue")
                {
                    t = new TwigContinue();
                }
                else if (elem.Text == "return")
                {
                    t = new TwigReturn();
                }
                else
                {
                    t = new TwigFormula();
                }
                t.Parse(ref contextBody);
                subTwigBody.Add(t);

                lastElem = elem.Text;
            }
        }

        /// <summary>
        /// Parse syntax tail
        /// </summary>
        protected virtual void parseTail()
        {
            int f = SyntaxChecker.GetInstance().FirstIndexOf(contextTail, "(");
            int l = SyntaxChecker.GetInstance().GetCloseBracketIndex(contextTail, f + 1, "(", ")");
            contextTail.RemoveRange(0, 2);
            contextTail.RemoveAt(contextTail.Count - 1);
            Twig t = new TwigFormula();
            t.Parse(ref contextTail);
            subTwigTail = t;
        }

        /// <summary>
        /// Parse lex elements to AST
        /// </summary>
        /// <param name="context">Lex elements list</param>
        /// <param name="headString">Syntax head string</param>
        protected virtual void parseKeyword(ref List<LexiconSplitter.Element> context, string headString)
        {
            // Skip comments
            List<int> commentLines = new List<int>();
            for (int i = 0; i < context.Count; i++)
            {
                if (LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.COMMENT == context[i].ElementType)
                    commentLines.Add(i);
            }
            for (int i = commentLines.Count - 1; i >= 0; i--)
            {
                context.RemoveAt(commentLines[i]);
            }
            contextHead = new List<LexiconSplitter.Element>();
            contextBody = new List<LexiconSplitter.Element>();
            contextTail = new List<LexiconSplitter.Element>();
            contextHead.Add(context[0]);
            context.RemoveAt(0);
            // Split
            int t =0;
            if (headString == "if" || headString == "elseif" || headString == "while")
            {
                t = SyntaxChecker.GetInstance().FirstIndexOf(context, "(");
                t = SyntaxChecker.GetInstance().GetCloseBracketIndex(context, t + 1, "(", ")");
            }
            else
            {
                t = SyntaxChecker.GetInstance().FirstIndexOf(context, ")");
            }
            int f = 0;
            int l = 0;
            bool withBrackets = true;
            if (headString == "else" && context[0].Text != "{")
            {
                f = 0;
                l = SyntaxChecker.GetInstance().FirstIndexOf(context, ";");
                withBrackets = false;
            }
            else if (context[t + 1].Text == "{" || (headString == "else" && context[0].Text == "{"))
            {
                f = SyntaxChecker.GetInstance().FirstIndexOf(context, "{");
                l = SyntaxChecker.GetInstance().GetCloseBracketIndex(context, f + 1, "{", "}");
            }
            else if (headString == "do")
            {
                f = SyntaxChecker.GetInstance().FirstIndexOf(context, "{");
                l = SyntaxChecker.GetInstance().GetCloseBracketIndex(context, f + 1, "{", "}");
            }
            else
            {
                f = t + 1;
                l = SyntaxChecker.GetInstance().FirstIndexOf(context, ";");
                withBrackets = false;
            }
            for (int i = 0; i < f; i++)
            {
                contextHead.Add(context[0]);
                context.RemoveAt(0);
            }
            List<LexiconSplitter.Element> tail = new List<LexiconSplitter.Element>();
            int end = context.Count + f - 1;
            for (int i = l; i < end; i++)
            {
                tail.Insert(0, context[context.Count - 1]);
                context.RemoveAt(context.Count - 1);
            }
            if (withBrackets)
            {
                context.RemoveAt(0);
                context.RemoveAt(context.Count - 1);
            }
            foreach (LexiconSplitter.Element elem in context)
            {
                contextBody.Add(elem);
            }
            if (headString == "do")
            {
                int _df = SyntaxChecker.GetInstance().FirstIndexOf(tail, "(");
                int _dl = SyntaxChecker.GetInstance().GetCloseBracketIndex(tail, _df + 1, "(", ")");
                _df--;
                _dl++;
                contextTail.AddRange(tail.GetRange(_df, _dl - _df));
                tail.RemoveRange(_df, _dl - _df);
            }
            context = tail;
        }
        #endregion

        /// <summary>
        /// Parse lex elements to AST
        /// </summary>
        /// <param name="context">Lex elements list</param>
        public virtual void Parse(ref List<LexiconSplitter.Element> context)
        {
        }

        /// <summary>
        /// Process if-elseif-else
        /// </summary>
        /// <param name="twig">The twig which sub twig is to be processed</param>
        public void ProcessIfElse(Twig twig)
        {
            int pie = 0;    // Process with If-Else :)
            for (int i = 0; i < twig.subTwigBody.Count; i++)
            {
                Twig t = twig.subTwigBody[i];
                if (0 == pie && t is TwigIf)
                {
                    // Begining of an 'if' twig
                    pie++;
                }
                else if (1 == pie && t is TwigElseif)
                {
                    // 'if' - 'elseif'
                    pie++;
                }
                else if (2 == pie && !(t is TwigElseif) && !(t is TwigElse))
                {
                    // Add an 'else'
                    pie = 0;

                    Twig te = new TwigElse();
                    twig.subTwigBody.Insert(twig.subTwigBody.IndexOf(t), te);
                    i = twig.subTwigBody.IndexOf(te);
                }
                else if (1 == pie && (t is TwigElse))
                {
                    // End of an 'if' twig
                    pie = 0;
                }
                else if (2 == pie && (t is TwigElse))
                {
                    // End of an 'if' twig
                    pie = 0;
                }
            }
            if (2 == pie)
            {
                Twig te = new TwigElse();
                twig.subTwigBody.Add(te);
            }
        }

        /// <summary>
        /// Compile from an AST to instructions and push them into a TASM instruction stack
        /// </summary>
        /// <param name="vm">TASM instruction stack</param>
        public virtual void PushAsm(ref TVM vm)
        {
            if (null != subTwigBody)
            {
                ProcessIfElse(this);
                foreach (Twig t in subTwigBody)
                {
                    t.PushAsm(ref vm);
                }
            }
        }
    }

    /// <summary>
    /// "function" Twig
    /// </summary>
    public class TwigFunction : Twig
    {
        private string functionName = null;

        private List<string> functionArguments = null;

        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            base.parseKeyword(ref context, "function");
            parseBody();

            functionName = contextHead[1].Text;
            // Arguments
            functionArguments = new List<string>();
            if (contextHead[3].Text != ")")
            {
                for (int i = 3; i < contextHead.Count - 1; i += 2)
                {
                    string id = contextHead[i].Text;
                    if (ScriptCommon.IsNumber(id))
                    {
                        throw new ScriptException("Invalid function argument identifier " + id);
                    }
                    functionArguments.Add(id);
                    SymbolTable.GetInstance().GetVariableIndex(id);
                }
            }
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().BlockBeginFunction(ref vm);
            TVM.Asm hal = new TVM.HAL();
            vm.AsmPush(hal);
            base.PushAsm(ref vm);
            TVM.Asm hlt = new TVM.HLT();
            vm.AsmPush(hlt);
            BrokenTwig.GetInstance().BlockEndFunction(ref vm);
            int varCount = SymbolTable.GetInstance().GetVariableCount();
            vm[0].Operand[0] = varCount;
        }
    }

    /// <summary>
    /// "if" Twig
    /// </summary>
    public class TwigIf : Twig
    {
        /// <summary>Without 'elseif' or 'else'</summary>
        private bool withoutElseifOrElse = true;

        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            base.parseKeyword(ref context, "if");
            if (context.Count > 0)
            {
                withoutElseifOrElse = (context[0].Text != "elseif" && context[0].Text != "else");
            }
            parseHead();
            parseBody();
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().BlockBeginIfElseFalse(ref vm);
            if (!withoutElseifOrElse)
            {
                BrokenTwig.GetInstance().BlockBeginIfElseTrue(ref vm);
            }
            // Condition
            {
                subTwigHead.PushAsm(ref vm);

                AddressingMode am1 = TVM.AM_IMD;
                AddressingMode am2 = TVM.AM_STK;
                AddressingMode am = TVM.CombineAddressingMode(am1, am2);
                TVM.Asm lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                TVM.Asm ce = new TVM.CE();
                ce.Operand[0] = 0;
                ce.Operand[1] = 0;
                vm.AsmPush(ce);

                BrokenTwig.GetInstance().JumpIfElseFalse(vm.AsmCount);
                TVM.Asm jt = new TVM.JF();
                vm.AsmPush(jt);
            }
            // Body
            base.PushAsm(ref vm);
            // End
            if (!withoutElseifOrElse)
            {
                BrokenTwig.GetInstance().JumpIfElseTrue(vm.AsmCount);
                TVM.Asm jmp = new TVM.JMP();
                vm.AsmPush(jmp);
            }
            else
            {
                BrokenTwig.GetInstance().BlockEndIfElseFalse(ref vm, vm.AsmCount);
            }
        }
    }

    /// <summary>
    /// "elseif" Twig
    /// </summary>
    public class TwigElseif : Twig
    {
        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            base.parseKeyword(ref context, "elseif");
            parseHead();
            parseBody();
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().BlockEndIfElseFalse(ref vm, vm.AsmCount);
            BrokenTwig.GetInstance().BlockBeginIfElseFalse(ref vm);
            // Condition
            {
                subTwigHead.PushAsm(ref vm);

                AddressingMode am1 = TVM.AM_IMD;
                AddressingMode am2 = TVM.AM_STK;
                AddressingMode am = TVM.CombineAddressingMode(am1, am2);
                TVM.Asm lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                TVM.Asm ce = new TVM.CE();
                ce.Operand[0] = 0;
                ce.Operand[1] = 0;
                vm.AsmPush(ce);

                BrokenTwig.GetInstance().JumpIfElseFalse(vm.AsmCount);
                TVM.Asm jt = new TVM.JF();
                vm.AsmPush(jt);
            }
            // Body
            base.PushAsm(ref vm);
            // End
            BrokenTwig.GetInstance().JumpIfElseTrue(vm.AsmCount);
            TVM.Asm jmp = new TVM.JMP();
            vm.AsmPush(jmp);
        }
    }

    /// <summary>
    /// "else" Twig
    /// </summary>
    public class TwigElse : Twig
    {
        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            base.parseKeyword(ref context, "else");
            parseBody();
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().BlockEndIfElseFalse(ref vm, vm.AsmCount);
            base.PushAsm(ref vm);
            BrokenTwig.GetInstance().BlockEndIfElseTrue(ref vm, vm.AsmCount);
        }
    }

    /// <summary>
    /// "for" Twig
    /// </summary>
    public class TwigFor : Twig
    {
        /// <summary>Loop variable</summary>
        private string id = "";

        /// <summary>Start value</summary>
        private string from = "";

        /// <summary>End value</summary>
        private string to = "";

        /// <summary>Step value</summary>
        private string step = "";

        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            base.parseKeyword(ref context, "for");
            parseBody();

            id = contextHead[2].Text;
            from = contextHead[4].Text;
            to = contextHead[6].Text;
            if (8 == contextHead.Count)     // Default step
            {
                step = "1";
            }
            else
            {
                step = contextHead[8].Text;
            }
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().BlockBeginLoop(ref vm);
            num ii = SymbolTable.GetInstance().GetVariableIndex(id);
            num si = num.Parse(step);
            // Initialized value
            {
                AddressingMode am1 = ScriptCommon.IsNumber(from) ? TVM.AM_IMD : TVM.AM_RAM;
                AddressingMode am = TVM.CombineAddressingMode(am1, TVM.AM_RAM);
                TVM.Asm lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                num start = (am1 == TVM.AM_IMD) ? num.Parse(from) : SymbolTable.GetInstance().GetVariableIndex(from);
                TVM.Asm assign = new TVM.MOV();
                assign.Operand[0] = start;
                assign.Operand[1] = ii;
                vm.AsmPush(assign);
            }
            // Condition
            int labelCondition = vm.AsmCount;
            {
                AddressingMode am2 = ScriptCommon.IsNumber(to) ? TVM.AM_IMD : TVM.AM_RAM;
                AddressingMode am = TVM.CombineAddressingMode(TVM.AM_RAM, am2);
                TVM.Asm lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                num end = (am2 == TVM.AM_IMD) ? num.Parse(to) : SymbolTable.GetInstance().GetVariableIndex(to);
                TVM.Asm compare = null;
                if (si >= 0)
                {
                    compare = new TVM.CLE();
                }
                else
                {
                    compare = new TVM.CGE();
                }
                compare.Operand[0] = ii;
                compare.Operand[1] = end;
                vm.AsmPush(compare);

                BrokenTwig.GetInstance().JumpBreak(vm.AsmCount);
                TVM.Asm jnt = new TVM.JT();
                jnt.Operand[0] = 0;
                vm.AsmPush(jnt);
            }
            // Body
            base.PushAsm(ref vm);
            // Step
            {
                AddressingMode am = TVM.CombineAddressingMode(TVM.AM_RAM, TVM.AM_IMD);
                TVM.Asm lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                TVM.Asm add = new TVM.ADD();
                add.Operand[0] = ii;
                add.Operand[1] = si;
                vm.AsmPush(add);

                am = TVM.CombineAddressingMode(TVM.AM_STK, TVM.AM_RAM);
                lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                TVM.Asm mov = new TVM.MOV();
                mov.Operand[0] = 0;
                mov.Operand[1] = ii;
                vm.AsmPush(mov);

                BrokenTwig.GetInstance().JumpContinue(vm.AsmCount);
                TVM.Asm jmp = new TVM.JMP();
                vm.AsmPush(jmp);
            }
            // End
            int labelOutside = vm.AsmCount;
            BrokenTwig.GetInstance().BlockEndLoop(ref vm, labelCondition, labelOutside);
        }
    }

    /// <summary>
    /// "while" Twig
    /// </summary>
    public class TwigWhile : Twig
    {
        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            base.parseKeyword(ref context, "while");
            parseHead();
            parseBody();
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().BlockBeginLoop(ref vm);
            int labelCondition = vm.AsmCount;
            // Condition
            {
                subTwigHead.PushAsm(ref vm);

                AddressingMode am1 = TVM.AM_IMD;
                AddressingMode am2 = TVM.AM_STK;
                AddressingMode am = TVM.CombineAddressingMode(am1, am2);
                TVM.Asm lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                TVM.Asm ce = new TVM.CE();
                ce.Operand[0] = 0;
                ce.Operand[1] = 0;
                vm.AsmPush(ce);

                BrokenTwig.GetInstance().JumpBreak(vm.AsmCount);
                TVM.Asm jt = new TVM.JF();
                vm.AsmPush(jt);
            }
            // Body
            base.PushAsm(ref vm);
            // End
            {
                TVM.Asm jmp = new TVM.JMP();
                jmp.Operand[0] = labelCondition;
                vm.AsmPush(jmp);

                int labelOutside = vm.AsmCount;
                BrokenTwig.GetInstance().BlockEndLoop(ref vm, labelCondition, labelOutside);
            }
        }
    }

    /// <summary>
    /// "do" Twig
    /// </summary>
    public class TwigDoWhile : Twig
    {
        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            base.parseKeyword(ref context, "do");
            parseBody();
            parseTail();
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().BlockBeginLoop(ref vm);
            int labelCondition = vm.AsmCount;
            // Loop body
            base.PushAsm(ref vm);
            // Loop condition
            {
                subTwigTail.PushAsm(ref vm);

                AddressingMode am1 = TVM.AM_IMD;
                AddressingMode am2 = TVM.AM_STK;
                AddressingMode am = TVM.CombineAddressingMode(am1, am2);
                TVM.Asm lam = new TVM.LAM();
                lam.Operand[0] = am;
                vm.AsmPush(lam);

                TVM.Asm cne = new TVM.CNE();
                cne.Operand[0] = 0;
                cne.Operand[1] = 0;
                vm.AsmPush(cne);

                BrokenTwig.GetInstance().JumpContinue(vm.AsmCount);
                TVM.Asm jt = new TVM.JF();
                vm.AsmPush(jt);
            }
            // Loop end
            int labelOutside = vm.AsmCount;
            BrokenTwig.GetInstance().BlockEndLoop(ref vm, labelCondition, labelOutside);
        }
    }

    /// <summary>
    /// formula Twig
    /// </summary>
    public class TwigFormula : Twig
    {
        // Process negative symbol
        private void processNegative(ref List<LexiconSplitter.Element> contextBody)
        {
            if (contextBody.Count > 1 && "-" == contextBody[contextBody.Count - 2].Text)
            {
                if (contextBody.Count < 3 ||
                    (contextBody[contextBody.Count - 3].ElementType != LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.CONST &&
                    contextBody[contextBody.Count - 3].ElementType != LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.IDENTIFIER &&
                    contextBody[contextBody.Count - 3].Text != ")"))
                {
                    contextBody.Insert(contextBody.Count - 2, new LexiconSplitter.Element("(", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.SEPERATOR));
                    contextBody.Insert(contextBody.Count - 2, new LexiconSplitter.Element("0", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.CONST));
                    contextBody.Add(new LexiconSplitter.Element(")", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.SEPERATOR));
                }
            }
        }

        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            contextBody = new List<LexiconSplitter.Element>();
            int f = SyntaxChecker.GetInstance().FirstIndexOf(context, ";");
            if (-1 != f)
            {
                for (int i = 0; i < f; i++)
                {
                    contextBody.Add(context[0]);
                    context.RemoveAt(0);

                    processNegative(ref contextBody);
                }
                context.RemoveAt(0);
            }
            else
            {
                foreach (LexiconSplitter.Element e in context)
                {
                    contextBody.Add(e);

                    processNegative(ref contextBody);
                }
                context.Clear();
            }
        }

        public override void PushAsm(ref TVM vm)
        {
            List<TVM.Asm> asmList = null;
            if (contextBody.Count == 1)                 // Single boolean
            {
                asmList = FormulaProcessor.GetInstance().BooleanVariable(ref contextBody);
            }
            else
            {
                if (contextBody.Count > 3 &&
                    contextBody[1].Text == "=" &&
                    contextBody[2].ElementType == LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.IDENTIFIER &&
                    contextBody[3].Text == "(")
                {
                    int ilb = SyntaxChecker.GetInstance().GetCloseBracketIndex(contextBody, 4, "(", ")");
                    if (contextBody.Count - 1 == ilb)   // Function call with '=' ahead
                    {
                        LexiconSplitter.Element elem = contextBody[0];
                        contextBody.RemoveRange(0, 2);
                        contextBody.Insert(2, elem);
                        if (4 != contextBody.Count)
                        {
                            LexiconSplitter.Element comma = new LexiconSplitter.Element(",", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.SEPERATOR);
                            contextBody.Insert(3, comma);
                        }
                        asmList = FormulaProcessor.GetInstance().FunctionCallFormula(ref contextBody);
                    }
                    else                                // Assign formula
                    {
                        asmList = FormulaProcessor.GetInstance().AssignFormula(ref contextBody);
                    }
                }
                else if (contextBody[1].Text == "=")    // Assign formula
                {
                    asmList = FormulaProcessor.GetInstance().AssignFormula(ref contextBody);
                }
                else if (contextBody[1].Text == "(" &&  // Function call without '=' ahead
                    SyntaxChecker.GetInstance().GetCloseBracketIndex(contextBody, 2, "(", ")") == contextBody.Count - 1)
                {
                    asmList = FormulaProcessor.GetInstance().FunctionCallFormula(ref contextBody);
                }
                else                                    // Boolean judgement
                {
                    asmList = FormulaProcessor.GetInstance().BooleanFormula(ref contextBody);
                }
            }
            foreach (TVM.Asm asm in asmList)
            {
                vm.AsmPush(asm);
            }
        }
    }

    /// <summary>
    /// "break" Twig
    /// </summary>
    public class TwigBreak : Twig
    {
        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            context.RemoveRange(0, 2);
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().JumpBreak(vm.AsmCount);
            TVM.Asm jmp = new TVM.JMP();
            vm.AsmPush(jmp);
        }
    }

    /// <summary>
    /// "continue" Twig
    /// </summary>
    public class TwigContinue : Twig
    {
        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            context.RemoveRange(0, 2);
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().JumpContinue(vm.AsmCount);
            TVM.Asm jmp = new TVM.JMP();
            vm.AsmPush(jmp);
        }
    }

    /// <summary>
    /// "return" Twig
    /// </summary>
    public class TwigReturn : Twig
    {
        public override void Parse(ref List<LexiconSplitter.Element> context)
        {
            context.RemoveRange(0, 2);
        }

        public override void PushAsm(ref TVM vm)
        {
            BrokenTwig.GetInstance().JumpReturn(vm.AsmCount);
            TVM.Asm jmp = new TVM.JMP();
            vm.AsmPush(jmp);
        }
    }
}

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