home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
forth
/
compiler
/
fpc
/
tutor
/
l7p090
< prev
next >
Wrap
Text File
|
1990-07-15
|
5KB
|
102 lines
╔════════════════════════════════════════════════════╗
║ 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 │
└───────────────────────────────────┘