Forth

Bookmark this on Digg
Bookmark this on Delicious
Share on reddit

Frequently Used Words in Forth

Operators

WordDescription
1+ 1-increment, decrement
2* 2/Double/ Divide by 2
/MODModulo operation
= < > <= >= <>relational operators
! +! -!assignment operators
AND OR XORlogical operators
<< U>>bit shift
MIN MAXcompares 2 values at the top of the stack and returns the smaller number (MIN)/larger number (MAX)
.prints the top most value on the stack
.Sprints all values in stack
@the value on top of the stack points to a memory address which value is put on top of the current stack
+ - *plus, minus, multiply
SWAPswap 2 values on top of stack with each other
DUPduplicate the value at the top of stack and place it on stack
DROPdelete the value at top of stack
OVERcopy the 2nd most value on top of stack and overwrite the first value in the stack
ROTrotate the top 3 values in stack
2SWAPReverses the top two pairs of numbers.
2DUPDuplicates the top pair of numbers.
2OVERMakes a copy of the second pair of numbers and pushes it on top.
2DROPDiscards the top pair of numbers.
MODpush the remainder into the stack

Variable Declarations

WordDescription
VARIABLE {name}Declare a variable. Using an variable will only return its memory address. use @ to return the value inside the address
{value} CONSTANT {name}declare a constant value
: {name} {operation} ;Declare a word. a new line can be started within operation.
."hello world"print out a string
CRprint out a carriage return
{conditional statement} IF {true operation} THENif statement. can only be used when declaring a word. Can be nested
{conditional statement} IF {true operation} ELSE {false operation} THENsame as above, but with else
{loop num} {initial value} DO {operation} LOOPloop statement. same rules as if statement apply.
BEGIN {conditional statement} WHILE {operation} REPEATindefinite loop. Can not use counters or UNLOOP
BEGIN {operation} AGAINInfinite loop, to branch out use EXIT
I Jcounters for loop
UNLOOPget out of loop
EXITbranch out while executing a WORD
SPACEprint out a space character
{num} EMITprint out a character with ASCII code
{num} SPACESprint out a space num times

Redstone Input/Output

WORDDESCRIPTION
IOXADDRset the bus ID of I/O Device you want to use
{value} IOX!set the output of the I/O device
IOX@get the input value from the I/O device
{value} IOXSETturn on the set value
{value} IOXRSTturn off the set value

Other

WORDDESCRIPTION
PAGEclear screen
SAVE" name"name an empty floppy
{value} TICKSsleep, 1 tick = 1/20 second
{num} TIMES {word}execute a WORD num times
DISKIDprint the disk ID of the disk currently in drive

IO Expander Output Color Values

ColorValue
White1
Orange2
Magenta4
Light Blue8
Yellow16
Lime32
Pink64
Gray128
Light Gray256
Cyan512
Purple1024
Blue2048
Brown4096
Green8192
Red16384
Black32768

49 thoughts on “Forth

  1. very very very very very very VERY VERY helpful thank you so much i can use the computer part now very useful info keep it up il def. tell my buds about this page

  2. A useful shortcut: to check whether the redstone input at some colour value N is on, use “IOX@ N AND”. This can be handed straight to conditionals if N is a power of 2 (if value N is on, then true, else false). If N isn’t a power of 2 (i.e. multiple colour values), use “N IOX@ N AND =” instead, unless you want to effectively boolean OR all the summed-2^X-values-that-make-N together. If you’re checking that several are all on, I’d recommend just summing their colour values and using the second snippet.

  3. If you want to wait for a input from the io expander you can do it like this.
    (this code runs a loop for 600 ticks (30 seconds) while it waits for a signal from cable 16 (yellow)) Kudos to Nihiltres for helping out with the IOX@ 16 AND bit, as I had been struggeling with IOX @ = 16 for a while.

    : TEST 600 0 DO IOX@ 16 AND IF .” TRUE” LEAVE ELSE .” FALSE THEN LOOP ;

    Hope this helps anyone :)

    • : TEST 600 0 DO IOX@ 16 AND IF .” True” LEAVE ELSE .” False” DROP THEN LOOP ;

      You need to add DROP to the false statement to not break the loop counter.

    • forth is designed to be far more “modular” than your using it there. i do a similar thing [i have a big "stop the machine" lever on the wall] but i do this

      : IsReset IOX@ 16 AND 16 = ; (assuming a switch on yellow )

      then main code:

      : Something BEGIN Stuff IsReset UNTIL ;

      you can then a) re-use IsReset in other words b) makes the mainline more sensible.

      tip: make words for EVERYTHING :)
      my main code for my door system is

      BEGIN
      200 TICKS
      LightChanged IF DoDoors
      THEN
      IsReset UNTIL

      the more you modularise the words themselves, the simpler it is to debug… e.g i can do
      LightChanged .
      or IsReset .
      to test various aspects before i write the main code

      hope that helps even more…

      • So does your IsReset detect the lever if a lot of levers are on? I didn’t really understand what that 16 AND 16 = part does. I don’t fully understand how AND and = works.
        This page didn’t really teach me a lot. There are very basic operations here but the description is not for programming beginners (for example carriage return). Also, I expected Forth to be fully stack based and {num} TIMES {word} doesn’t seem to be fully stack based. I will probably learn 6502 assembly to create my own language and it will be as much stacked based as it can.

        P.S. I am only 13

  4. Some extra commands I’ve found somewhat useful that aren’t listed here:

    COLD is the startup message, as in “cold start”. While this isn’t very useful in and of itself, knowing the command name means that you can redefine it! I like to redefine the startup message before saving my computer’s state to a blank floppy. Alternatively, use “PAGE COLD” on the command line to get that “just-started-up” feeling.

    FREE returns the number of free bytes of RAM, as in the default COLD. I usually only use it when redefining COLD, but I’m sure it can be otherwise useful.

    RADIX is the variable for the system radix. Want all numbers to be input and output as binary? Just “2 RADIX !”. Remember, input is assumed to be in the radix you’ve chosen, so you’ll have to “1010 RADIX !” to get back from binary to decimal, and you can’t use digits higher than the ones that exist in your current radix. Existing words and variables don’t need to be changed, but beware radices high enough to cause numbers and words to conflict. I haven’t properly tested what oddities happen if you select a number less than 2, but it doesn’t seem like a good idea.

  5. I forgot to mention something related to FREE: the system assumes that numbers are signed, so “32767 1 + .” prints “-32768″. To print FREE properly, use “FREE U.”; “U.” tells the system to interpret the number as unsigned when printing it, so “32767 1 + U.” returns “32768″. Unsigned numbers use the interval [0, 65535] instead of the signed number interval [-32768, 32767]. If your computer has 4 or more 8K RAM Modules, this is important, as you may have more than 32767 bytes of RAM free.

  6. Thank you very much for your help. But I have still a problem.
    Hm… could it be, there is no way to use this system like a PLC? If I’m right there is nor “real” infinite loop. Even if I use BEGIN and AGAIN the loop stop after 30 seconds or something like that. But for a use like a PLC it would be great if the system infinite process the programm. Is there a way? Or have I still use the “usual” redpower for these things?

    • I have the same problem, but you should be able to set up a loop with the words themselves.
      : FIRST FIRST ;

      If that doesn’t work, try calling in a cycle.
      : FIRST SECOND;
      : SECOND FIRST ;

      the main issue is that leaves no way to exit so instead use
      : FIRST SECOND;
      : SECOND KEY? IF QUIT ELSE FIRST THEN ;

      personally I put the KEY? as deep into my loop as I can (so it gets called often and I can stop a malfunctioning program as fast as possible). KEY? just checks the input buffer for a waiting keystroke, it doesn’t matter when the key was hit so there is no particular timing required between hitting the key and the check.

      • Odd. Tried to include “body of loop” in brackets (after the initial FIRST) but it never showed up. Unfortunately my proposals won’t work since they are referencing a word which doesn’t exist yet.

        In testing I’ve noticed that executing things like
        BEGIN (loop) AGAIN
        from the interpreter only runs once but as part of an executed word they work correctly.
        : QUARRY BEGIN (loop) AGAIN ;

        • BEGIN and AGAIN are compile time loops, you can’t use them in the interpreter. I think they also clobber up memory, so

  7. Is there a way to make a word run in the background? My word is basically an infinite loop but if I use the exit command it stops the loop and when I run the loop I can’t do anything else. To get out of it I end up having to restart the computer. Is there a command that lets me continue to use the computer once an infinite loop is working?

    • >Is there a way to make a word run in the background?

      You could use an IO Expander to hook multiple CPUs to a “master” CPU, where turning on or off a colored wires will run/stop “background” tasks on one or more sub-CPUs. It’s not like CPUs are very expensive in terms of resources (compared to whatever process you’d need multiple CPUs to run effectively).

      • Technically an IO Expander isn’t needed for inter-computer communication. The computers are capable of communicating directly to each other by reading and writing to the ‘redbus’ which is shared by all computers connected to the ribbon cable. Unfortunately I do not know enough on the subject to be able to explain it fully…

      • you don’t /have/ to define a word, you can print in immediate mode.

        i think the error was more the missing space after the
        [dot][quote]

        words in forth are quite specifically a string of non space separated chars… the word which prints is in fact the .” part the space after the quote separates the .” word from the text you need to print.

        so, in the above suggestion, you have actually shown it correctly, the questioner hadn’t tho – which is probably the problem :)

        the way that a word can be defined as /any/ char can be confusing to even me ;) [ironic understatement ;) ]

        e.g. consider the difference between

        3 IOX! ( sets the IO expander to 3 ) – the ! is part of the word
        compared to
        3 IOXADDR ! ( sets the current IOX address to 3 – the ! is a separate word in forth meaning “store the stack (3 here) in this variable (IOXADDR)”

  8. Hi there, Have a question.. Im using Nihiltres method to check if an Cable is powered. but it has to count each time it is live. i’ve thought about just using a delay. but its not as.. perfect as i was hoping. 15 button presses count 16 times. i then thought of checking to see if a variable was false. if not, then dont increase the count. but if no then increase the count.
    then after the increase count by one command, have it set variable to true. heres what i mean in just a simple basic.

    if input 1 live then
    if z is false then count ++ z set true
    else
    z set false
    endif

    if that makes sense.
    BASICALLy, i wanted to know if there was a way easier way to do this. as im going to be using all 16 channels on the IOX and think 16 ?? or 15?? anyway 16 variable is a stupid idea. unless i use an array… does forth do arrays?

  9. sCRAtch the old question. i think i came up with a way around it. but now i have a new question.
    Variables and strings.. HOW? can you store a string into a variable?

  10. Does it just happen to me or is there a problem with the FORGET command

    When a compilation fails because of a syntax error or when I define a word 2 times, FORGET will only delete the last defined (as intended) but cannot seem to find the second one when I reFORGET. The word still shows up when I use WORDS…

    Whats up with that? /scratch head

    • Nope, your totally right, i get the same issue, it appears in words. but you can forget the word, nor can you execute the remaining word ” Unknown Token” error.
      I ended up with 5 T1 ‘s once.. accidently.

  11. Can somebody please help me with this code here:

    : lights_f1_on
    4 IOXADDR !
    5 TICKS
    1 IOXSET
    2 IOXRST
    5 TICKS
    32 IOXADDR !
    ;
    : lights_f1_off
    4 IOXADDR !
    5 TICKS
    1 IOXRST
    2 IOXSET
    5 TICKS
    32 IOXADDR !
    ;
    : lights_f2_on
    4 IOXADDR !
    5 TICKS
    4 IOXSET
    8 IOXRST
    5 TICKS
    32 IOXADDR !
    ;
    : lights_f2_off
    4 IOXADDR !
    5 TICKS
    4 IOXRST
    8 IOXSET
    5 TICKS
    32 IOXADDR !
    ;
    : lights_office_on
    4 IOXADDR !
    5 TICKS
    16 IOXSET
    5 TICKS
    32 IOXADDR !
    ;
    : lights_office_off
    4 IOXADDR !
    5 TICKS
    16 IOXRST
    5 TICKS
    32 IOXADDR !
    ;
    : stair_on
    4 IOXADDR !
    5 TICKS
    32 IOXSET
    5 TICKS
    32 IOXADDR !
    ;
    : stair_off
    4 IOXADDR !
    5 TICKS
    32 IOXRST
    5 TICKS
    32 IOXADDR !
    ;

    : Server
    32 IOXADDR !
    CR .” Server application now running”
    BEGIN
    CR .” In loop”
    THEN
    1 IOX@ = IF
    lights_f1_on
    CR .” Floor 1 lights turned on”
    32 IOXADDR !
    10 TICKS
    THEN
    2 IOX@ = IF
    lights_f1_off
    CR .” Floor 1 lights turned off”
    32 IOXADDR !
    10 TICKS
    THEN
    3 IOX@ = IF
    lights_f2_on
    CR .” Floor 2 lights turned on”
    32 IOXADDR !
    10 TICKS
    THEN
    4 IOX@ = IF
    lights_f2_off
    CR .” Floor 2 lights turned off”
    32 IOXADDR !
    10 TICKS
    THEN
    5 IOX@ = IF
    lights_office_on
    CR .” Office lights turned on”
    32 IOXADDR !
    10 TICKS
    THEN
    6 IOX@ = IF
    lights_office_off
    CR .” Office lights turned off”
    32 IOXADDR !
    10 TICKS
    7 IOX@ = IF
    stair_on
    CR .” Stair lights turned on”
    32 IOXADDR !
    10 TICKS
    8 IOX@ = IF
    stair_off
    CR .” Stair lights turned off”
    32 IOXADDR !
    10 TICKS
    THEN
    512 IOX@ = IF
    CR .” Server application exiting…”
    32 IOXADDR !
    40 TICKS
    EXIT
    THEN
    0 IOX@ = IF
    CR .” Zero”
    EXIT
    THEN
    CR .” None”
    EXIT
    CR .” None2″
    AGAIN
    CR .” Left loop”
    EXIT
    ;

    It is supposed to act as a server to control lights and other funtions via signals from client computers but instead it randomly changes outputs on IOXADDR 4. Help would be appreciated. Thanks.

    • WHY DO YOU NEED A COMPUTER FOR THIS??? I was writing the text below and thought that. And i thought it’s very strange that you need it and your inputs are also strange because for most of the lights you need several inputs on. I assume you still need it so I wrote a bit about your program (I did it before writing the above).

      There are a lot of problems in your Server program i recommend making a word for each input check. Your program also might not detect if several inputs are on if you are using levers and too slow for buttons.
      This might work but please note that mistakes are a part of programming (usually):

      : lights_template_on
      4 IOXADDR !
      5 TICKS
      IOXSET
      5 TICKS
      32 IOXADDR !
      ;

      : lights_template_off
      4 IOXADDR !
      5 TICKS
      IOXRST
      5 TICKS
      32 IOXADDR !
      ;

      These were from your lights_f1_on and _off just the number before IOXSET and IOXRST was deleted.These templates will make less writing and less memory usage.

      : lights_f1_on
      1 lights_template_on
      2 lights_template_off
      CR .” Floor 1 lights turned on”
      ;

      : lights_f1_off
      1 lights_template_off
      2 lights_template_on
      CR .” Floor 1 lights turned on”
      ;

      Didn’t finish it but i might come back here later and write the rest. I am quite lazy and only 13 years old :P .

      Please write if you don’t need the rest of the code!!!

  12. Like many others i used a personal system for my base and majority of the coding works so far for my purposes.

    One of them is a remote activation of a machine by use of the Wireless Redstone Mod, which works for me both mechanical means and direct iox manipulation.The Idea i used, is to enter a customized code, 1234
    I have got the majority down, but i hit a weird bug? or my coding is wrong

    Following code works for me except for number 3 & 4, which both returns 128.
    .
    : !# DUP 0 = IF 512 THEN DUP
    1 = IF 1 THEN DUP 2 = IF 2 THEN DUP 3 = IF 4 THEN DUP
    4 = IF 8 THEN DUP 5 = IF 16 THEN DUP 6 = IF 32 THEN DUP
    7 = IF 64 THEN DUP 8 = IF 128 THEN DUP 9 = IF 256 THEN DUP
    10 = IF 1024 THEN DUP 11 = IF 2048 THEN DUP
    12 = IF 4096 THEN DUP 13 = IF 8192 THEN DUP
    14 = IF 16384 THEN DUP 15 = IF 32768 THEN ;

  13. Thanks this was helpful. I have a question though. I have lights that were turned on with a computer and won’t turn off. I’ve tried 0 IOX! and that didn’t work. Is there a way to turn them off without completely replacing my wiring?

  14. Hello, I need some help with FORTH.

    I need a program that runs continuously, and if an input wire(white) goes on, a loop is started.
    If the white turns off, a different loop is started.

    My questions:
    1. Is this possible?
    2. If so, how would I do it? I don’t understand much of this language, I need some help on this.

  15. Does this work?
    Im trying a simple infinite loop broken by Redstone input.

    : master
    Begin
    1024 iox@ if
    Exit
    Else
    chickenfarm
    Then
    Again
    ;

  16. In Forth, i want to load a program from a disk in the disk drive, how i can do it? if in forth it isn’t posible, how i can create a program that do it??
    i mean if someelse can put a code like:
    : LOAD (program to load, this need to be written only for load the com)
    compile: and now the comands that will do to work
    compile: ;
    PD: com = the command to load from the disk in the disk drive
    And now if i tipe LOAD (THE PROGRAM HERE) i can load a program from a disk. Very thanks if anyone do this and paste here the example complete.
    and now i am searching to load the disk like a program, example:
    : LOADDISK (name of disk) (program that will be created)
    compile: here a command that get all the programs of the disk an get
    all to a program
    compile: ;

    I tipe this because i want to have the bigfoot tetris in my disk without restarting the cpu, i mean when i create the program LOADDISK i write
    LOADDISK TETRIS TETRISOFBIGFOOT, when LOADDISK is the program, TETRIS the disk and TETRISOFBIGFOOT the command that if i write i can play the tetris xd.
    Thanks for anyone for any answer, it will be very good for all

  17. Hello can someone tell me how to get a number via user input inside an infinite loop ?
    I want to build an elevator where you have to type only the number of the floor you want to go, without typing words.

  18. The / and MOD operators in MineOS are the other way around: / is the remainder and MOD is division. I suspect this is an oversight and may change in some future version. If you wish your code to maintain portability I suggest using the /MOD operator only and NIPping or DROPping as required. If this really is an issue for you they can be patched with:
    ‘ NIP ‘ / 3 + !
    ‘ DROP ‘ MOD 3 + !

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by sweetCaptcha