// ( -- ) Jumps unconditionally to the parameter field location next to it and is compiled by ELSE
        public void doJump(ref GlobalSimpleProps gsp)
        {
            CreoleWord currWord   = gsp.Cfb.Address[gsp.InnerPtr];
            List <int> paramField = currWord.ParamField;
            int        jumpAddr   = paramField[gsp.ParamFieldPtr + 1];
            ReturnLoc  rLoc       = (ReturnLoc)gsp.Pop(gsp.ReturnStack);

            gsp.ParamFieldPtr   = jumpAddr;
            rLoc.ParamFieldAddr = gsp.ParamFieldPtr;
            gsp.ReturnStack.Add(rLoc);
        }
        // ( inc -- ) Loops back to doDo until the start >= the end and increments with inc
        public void doPlusLoop(ref GlobalSimpleProps gsp)
        {
            int        incVal     = (int)gsp.Pop(gsp.DataStack);
            CreoleWord currWord   = gsp.Cfb.Address[gsp.InnerPtr];
            List <int> paramField = currWord.ParamField;
            ReturnLoc  rLoc       = (ReturnLoc)gsp.Pop(gsp.ReturnStack);
            LoopInfo   li         = (LoopInfo)gsp.Pop(gsp.ReturnStack);
            int        jumpAddr   = paramField[rLoc.ParamFieldAddr];
            int        loopLimit  = li.Limit;
            string     loopLabel  = li.Label;
            int        currIndex  = li.Index;

            if (incVal == 0)
            {
                loopLimit += incVal;
            }
            else
            {
                loopLimit -= incVal;
            }

            if ((incVal > 0) && (currIndex >= loopLimit) || (incVal < 0) && (currIndex <= loopLimit))
            {
                gsp.ParamFieldPtr++;
                rLoc.ParamFieldAddr = gsp.ParamFieldPtr;
                gsp.LoopLabelPtr--;
            }
            else
            {
                gsp.ParamFieldPtr   = jumpAddr;
                currIndex           = currIndex + incVal;
                li.Index            = currIndex;
                rLoc.ParamFieldAddr = gsp.ParamFieldPtr;
                gsp.ReturnStack.Add(li);
            }

            if (loopLabel == "I")
            {
                gsp.LoopCurrIndexes[0] = currIndex;
            }
            else if (loopLabel == "J")
            {
                gsp.LoopCurrIndexes[1] = currIndex;;
            }
            else if (loopLabel == "K")
            {
                gsp.LoopCurrIndexes[2] = currIndex;;
            }
            else
            {
                Debug.Print("Error: Invalid loop label");
            }
            gsp.ReturnStack.Add(rLoc);
        }
        // ( -- lit ) Run-time code that pushes a literal onto the stack
        public void doLiteral(ref GlobalSimpleProps gsp)
        {
            CreoleWord    currWord         = gsp.Cfb.Address[gsp.InnerPtr];
            List <int>    paramField       = currWord.ParamField;
            List <object> dataField        = currWord.DataField;
            ReturnLoc     rLoc             = (ReturnLoc)gsp.Pop(gsp.ReturnStack);
            int           litDataFieldAddr = paramField[gsp.ParamFieldPtr];

            gsp.DataStack.Add(dataField[litDataFieldAddr]);
            rLoc.ParamFieldAddr++;
            gsp.ParamFieldPtr = rLoc.ParamFieldAddr;
            gsp.ReturnStack.Add(rLoc);
        }
        // ( start end -- ) Starts off the Do by getting the start and end
        public void doStartDo(ref GlobalSimpleProps gsp)
        {
            ReturnLoc rLoc       = (ReturnLoc)gsp.Pop(gsp.ReturnStack);
            int       startIndex = (int)gsp.Pop(gsp.DataStack);
            int       loopEnd    = (int)gsp.Pop(gsp.DataStack);
            LoopInfo  li         = new LoopInfo(gsp.LoopLabels[gsp.LoopLabelPtr], startIndex, loopEnd);

            for (int i = 0; i < 3; i++)
            {
                gsp.LoopCurrIndexes.Add(0);
            }
            gsp.LoopLabelPtr++;
            gsp.ReturnStack.Add(li);
            gsp.ReturnStack.Add(rLoc);
        }
        //  DOES> <list of runtime actions>. When defining word is created, copies code following it into the child definition
        public void compileDoes(ref GlobalSimpleProps gsp)
        {
            ReturnLoc  rLoc             = (ReturnLoc)gsp.Pop(gsp.ReturnStack);
            int        parentRow        = rLoc.DictAddr;
            int        newRow           = gsp.Cfb.Address.Count - 1;
            CreoleWord parentCreoleWord = gsp.Cfb.Address[parentRow];
            CreoleWord childCreoleWord  = gsp.Cfb.Address[newRow];
            string     fqNameField      = childCreoleWord.FQNameField;
            int        doesAddr         = gsp.Cfb.Dict["DOES>.FORTH"].IndexField;
            int        i = 0;

            childCreoleWord.CodeField    = gsp.Cfb.Modules.Compiler.doDoes;
            childCreoleWord.CodeFieldStr = "doDoes";
            // Find the location of the does address in the parent definition
            int startCopyPoint = -1;

            while (i < parentCreoleWord.ParamField.Count)
            {
                if (parentCreoleWord.ParamField[i] == doesAddr)
                {
                    startCopyPoint = i + 1;
                    break;
                }
                else
                {
                    i++;
                }
            }

            // Need the definition's address do doDoes can get it easily either when it's being
            // called from the interpreter from from within a compiled definition
            childCreoleWord.ParamField.Add(newRow);
            childCreoleWord.ParamFieldStart = childCreoleWord.ParamField.Count;
            i = 0;
            while (startCopyPoint < parentCreoleWord.ParamField.Count)
            {
                childCreoleWord.ParamField.Add(parentCreoleWord.ParamField[startCopyPoint]);
                startCopyPoint++;
                i++;
            }
            rLoc.ParamFieldAddr += i;
            gsp.ReturnStack.Add(rLoc);
            gsp.Cfb.Address[newRow]   = childCreoleWord;
            gsp.Cfb.Dict[fqNameField] = childCreoleWord;
        }
Beispiel #6
0
        // Run time code for colon definitions
        public void doColon(ref GlobalSimpleProps gsp)
        {
            CreoleWord currWord   = gsp.Cfb.Address[gsp.InnerPtr];
            List <int> paramField = currWord.ParamField;

            while (gsp.ParamFieldPtr < paramField.Count)
            {
                int       addrInPF  = paramField[gsp.ParamFieldPtr];
                Codefield codeField = gsp.Cfb.Address[addrInPF].CodeField;
                gsp.ParamFieldPtr++;
                ReturnLoc rLoc = new ReturnLoc(gsp.InnerPtr, gsp.ParamFieldPtr);
                gsp.Scratch = rLoc;
                gsp.Push(gsp.ReturnStack);
                codeField(ref gsp);
                rLoc              = (ReturnLoc)gsp.Pop(gsp.ReturnStack);
                gsp.InnerPtr      = rLoc.DictAddr;
                gsp.ParamFieldPtr = rLoc.ParamFieldAddr;
            }
        }
        // ( flag -- ) Run-time code for IF
        public void do0Branch(ref GlobalSimpleProps gsp)
        {
            CreoleWord currWord = gsp.Cfb.Address[gsp.InnerPtr];

            List <int> paramField = currWord.ParamField;
            ReturnLoc  rLoc       = (ReturnLoc)gsp.Pop(gsp.ReturnStack);
            int        jumpAddr   = paramField[rLoc.ParamFieldAddr];
            int        branchFlag = (int)gsp.Pop(gsp.DataStack);

            if (branchFlag == 0)
            {
                gsp.ParamFieldPtr = jumpAddr;
            }
            else
            {
                gsp.ParamFieldPtr++;
            }
            rLoc.ParamFieldAddr = gsp.ParamFieldPtr;
            gsp.ReturnStack.Add(rLoc);
        }