music
OSdata.com: programming text book 

OSdata.com

add in Forth

summary

OSdata RSS
News Feed


OSdata blog RSS.

OSdata blog RSS - add to Bloglines
OSdata blog RSS - add to Google Reader.
OSdata blog RSS - add to My AOL
OSdata blog RSS - add to Newsgator.

    This section discusses the Forth keyword ADD.

    This is part of an instructional series on the building of a Forth programming environment in any standard browser using JavaScript.

    Threaded Interpreted Languages (TILs), including Forth, are designed for customization.

    In addition to writing your own Forth programs, please modify the underlying engine to meet your specific needs.

    Please have fun with this project. Make it your own.

    The most recent version is at stable release version or http://www.twiddledom.com/coder/js78.html

    Free Open Souce: Licensed under MIT license. License printed in full below.

previous page   next page
previous page
stack check
  next page
cross scripting
Google

add in Forth

summary

    This section discusses the Forth keyword ADD.

adding in Forth

pop first addend

    Forth pops the top two numbers from the top of the stack, adds those two numbers together, and pushes the answer back onto the top of the stack.

    In our case, we load the top item into a JavaScript variable while removing it from the JavaScript datastack array. (Note that the orginal method is still retained as a comment. The original method left stray elements on the end o the array.)

firstitem = Number(datastack.pop());

    Note that we use the built-in JavaScript type coersion to change a valid numeric string into an actual binary number. If we didn’t do this, the sum operation would concatentate strings rather than add numbers.

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

obtain second addend

    We simply copy the second addend from the new top of stack into a JavaScript variable. If we were implementing this in machine code, we would use an actual pop operation and then push the sum on the stack at the end, but there is no reason to add extra overhead to the JavaScript interpreter.

seconditem = Number(datastack[topofstack-1]);

    Same note about the type conversion as for the first addend.

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

obtain the sum

    And we add the two inputs together to obtain the sum. Note that we are keeping each element in a separate JavaScript variable so that we can use these values in our error reporting routine.

newtotal = firstitem + seconditem;

    You can make this whole routine faster by doing all of these steps in a single JavaScrript assignment statement.

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

put answer on top of stack

    At this point we adjust our stack pointer variable and place the sum on the new top of the stack.

topofstack = --topofstack;
datastack[topofstack] = newtotal;

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

error reporting

    And a couple of lines for debugging:

stackcontent = datastack[topofstack];
document.getElementById("response").innerHTML = "<p align=\"center\">add result is " + newtotal + " and top of stack is " + topofstack + " and current stack item is " + stackcontent + "</p>";

    Note that Forth normally responds OK upon a successful ADD.

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

    In later versions, this error reporting becomes part of a standard debug routine.

stackcontent = datastack[topofstack];
this.debugstring = "add result is " + newtotal;

return

    And our return from subroutine:

return 0;

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

    More recent return:

return OK;

error detection and correction

    We include some error detection and abort the routine if it will fail.

    These routines come before the actual adding operations, but are presented second here. It simply makes more sense for instruction to show the working portion of the function first, then show the added house-keeping material.

    I will provide complete copies of the original and current versions of this routine at the end of this discussion. The instructional code uses the original version.

check for stack size

    We must have at least two addends on the stack. We check to see if this is true, and return with an error report if it isn’t.

if (topofstack <= 1) {
  document.getElementById("response").innerHTML = "<p align=\"center\">not enough items on stack to add</p>";
  return 0;
}

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

guarantee numbers

    We want to guarantee that both addends are actually numeric. We can accept numbers as either binary numbers or as strings (conversion forced as shown above).

if ( !isNumeric(datastack[topofstack]) ) {
  document.getElementById("response").innerHTML = "<p align=\"center\">item on top of stack is NOT numeric - add fails</p>";
  return 0;
}

if (!isNumeric(datastack[topofstack-1])) {
  document.getElementById("response").innerHTML = "<p align=\"center\">item on second on stack is NOT numeric - add fails</p>";
  return 0;
}

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

numeric check function

    The numeric check function is copied from a version widely available on the internet. I like to properly credit authors, but in this case I simply can’t determine the original author.

function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
} /* END FUNCTION isNumeric */

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

complete code

    I will now include the entire orginal and current versions of the ADD function so that you can see all of the steps in context.

original version

    There is a minor error in the original version (a misnamed variable). I didn’t notice the mistake until I added more code later that used variable. I have left the mistake in to show I am human and as a reminder to check all of your work.

    I already explained above the other commented out line -- also from the older original version.

function add() {

var outputvalue; /* notice mistake - mismatched names */

if (topofstack <= 1) {
  document.getElementById("response").innerHTML = "<p align=\"center\">not enough items on stack to add</p>";
  return 0;
}

if ( !isNumeric(datastack[topofstack]) ) {
  document.getElementById("response").innerHTML = "<p align=\"center\">item on top of stack is NOT numeric - add fails</p>";
  return 0;
}

if (!isNumeric(datastack[topofstack-1])) {
  document.getElementById("response").innerHTML = "<p align=\"center\">item on second on stack is NOT numeric - add fails</p>";
  return 0;
}

//firstitem = Number(datastack[topofstack]);
firstitem = Number(datastack.pop());
seconditem = Number(datastack[topofstack-1]);
newtotal = firstitem + seconditem;
topofstack = --topofstack;
datastack[topofstack] = newtotal;

stackcontent = datastack[topofstack];
document.getElementById("response").innerHTML = "<p align=\"center\">add result is " + newtotal + " and top of stack is " + topofstack + " and current stack item is " + stackcontent + "</p>";

return 0;

} /* END FUNCTION add */

    This code can be found in context at http://www.twiddledom.com/coder/js10.html.

current version

    Note that this is an object-oriented version. I started the coding in procedural programming just to make sure I had the basics working properly before switching over to object-oriented programming.

add:function () {

var newtotal;

if (this.topofstack <= 1) {
  this.responsestring = "not enough items on stack to add";
  this.debugstring = "not enough items on stack to add";
  return ERROR;
}

if ( !this.isNumeric(this.datastack[this.topofstack]) ) {
  this.responsestring = "item on top of stack is NOT numeric - add fails";
  this.debugstring = "item on top of stack is NOT numeric - add fails";
  return ERROR;
}

if (!this.isNumeric(this.datastack[this.topofstack-1])) {
  this.responsestring = "item on second on stack is NOT numeric - add fails";
  this.debugstring = "item on second on stack is NOT numeric - add fails";
  return ERROR;
}

firstitem = Number(this.datastack.pop());
seconditem = Number(this.datastack[this.topofstack-1]);
newtotal = seconditem + firstitem;
this.topofstack = --this.topofstack;
this.datastack[this.topofstack] = newtotal;

stackcontent = this.datastack[this.topofstack];
this.debugstring = "add result is " + newtotal;

return OK;

}, /* END FUNCTION add */

conclusion

    It is as simple as that!

return to Forth in JavaScript
return to Outrageous Coder

previous page   next page
previous page
stack check
  next page
cross scripting

contact
comments, suggestions, corrections, criticisms

because of ridiculous spam attacks,
contact through Twitter (@OutrageousCoder) will be more reliable than the contact form

please contact us

your name:
email address:
phone number:
message:

return to table of contents
free downloadable college text book

license

    This is example code from OSdata, This Side of Sanity, and Twiddledom, released under the MIT License.

    Copyright © 2014, 2015 Milo

    Licensed under the MIT License. You may obtain a copy of the License at

        http://opensource.org/licenses/MIT

    The MIT License (MIT)

    Copyright © 2014, 2015 Milo

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

previous page   next page
previous page
stack check
  next page
cross scripting

Google


Made with Macintosh

    This web site handcrafted on Macintosh computers using Tom Bender’s Tex-Edit Plus and served using FreeBSD .

Viewable With Any Browser


    †UNIX used as a generic term unless specifically used as a trademark (such as in the phrase “UNIX certified”). UNIX is a registered trademark in the United States and other countries, licensed exclusively through X/Open Company Ltd.

    Names and logos of various OSs are trademarks of their respective owners.

    Copyright © 2014 Milo

    Created: October 15, 2014

    Last Updated: October 15, 2014


return to table of contents
free downloadable college text book

previous page   next page
previous page
stack check
  next page
cross scripting