ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º Lesson 7 Part 090 F-PC 3.5 Tutorial by Jack Brown º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Explanation of the NOTE Compiler ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ The part before the word DOES> and after the word NOTE describes how to make notes. The part after the word DOES> and before the ; tells how to play a note, or what is to happen when you execute a note type object. \ The note compiler. : NOTE CREATE , \ Compile time like constant. DOES> @ OCTAVE @ * 5 + 10 / \ Run time, fetch value, compute TONE REST S.OFF ; \ frequency and play the note. Now for a detailed explanation of how NOTE works. First look at the compile time or creation part of the word. This is the part before the DOES> . You know from the preceding discussion that CREATE makes a dictionary entry for the word which follows it in the input stream. This time, however, CREATE is included in a definition so the dictionary entry will not be created until NOTE is executed. At this time the word following NOTE in the input stream wile be the name of the musical note we want to create. The comma ( , ) stores the top stack number in the dictionary space following the created note name ( in the notes pfa ). This value will be recovered at run time and used to control the frequency of the sound generator. Second look at the run time or execution time part of the word. This is the part after the DOES>. Recall that whenever a word defined by CREATE executes ( and in this case NOTE because it includes CREATE ), the parameter field address or pfa get pushed to the data stack. The @ which follows the DOES> fetches the value stored at this location ( the value stored by the comma ( , ) at compile time ). This value is multiplied by the OCTAVE and turned into a frequency for the word TONE. TONE starts the sound generator with the compute frequency and REST waits the number of beats specified by the number on the stack. Finally when the beats are finished the sound is turned off. That's it... Its all over... The music language is all contained in the word NOTE. We just make NOTEs as you would make CONSTANTs and then you use the NOTEs to do something. Above we have a program that plays a musical scale. If you would like a song there is one below: \ Music Music?? : PART1 1/4 2ND F# E D C D E D 1ST A F# G A B A F# 1/2 A 1/4 2ND D E ; : PART2 1/2 2ND F# F# 1/4 F# E D E F# E D F# 1/2 E ; : PART3 1/4 2ND F# E F# G A F# D E F# D E 1ST A 1/2 2ND D R ; : PART4 1/4 1ST F# E F# G A G F# E F# E F# G ; : PART5 1/4 2ND D E F# D 1ST B 2ND C# D 1ST A F# G A F# 1/2 E 1/4 D E ; : PART6 1/4 1ST F# E F# G A F# D E F# D E C# 1/2 D R ; : TURKEY PART1 PART2 PART1 PART3 PART4 1/2 1ST A R PART4 1/2 1ST B 1/4 B 2ND C# PART5 PART6 ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Defining a VECTOR with Run Time Error Checking ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ At compile time all elements of the vector are initialized to zero. At run time the vector subscript is checked against that stored at compile time and an error message issued if the subscript is out of range. I have noticed seasoned veterans of other languages comment at Forth's lack or error checking. Well... you can put as much in as you like, and you know what? The more you put in the slower you program will run. A correct program does not need run time error checking. So what is a person to do, like me who cannot write correct programs? Have one version of the word with error checking to use when you are doing development work and another to use when you have all the bugs removed. Here is the definition of VECTOR with error checking. \ Create a one dimensional vector n storage cells \ Usage: VECTOR {name} ( n -- ) \ Later: {name} ( index -- adr ) : VECTOR ( n -- ) CREATE \ This is the compile time routine DUP , \ Compile n, maximum subscript. 0 DO 0 , LOOP \ Initialize vector to zeros. \ Run time- comments are stack state. DOES> \ index adr TUCK @ OVER \ adr index n index <= OVER 0< OR \ adr index flag ABORT" Subscript out of range." \ Error message 1 + 2* + ; \ Compute address of ith element ÖÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· º Problem 7.6 º ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ Use this version of VECTOR to implement the WORK example given at the end of Lesson 7 Part 7. Verify the operation of the run time error checking by coding an out of range subscript in the definition of WORK ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Please Move to Lesson 7 Part 100 ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ