// ( -- ) 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; }
// 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); }