Fixes to 1992/buzzard.2
Running make all now links first. The README.md now has been checked for formatting and typos. The buzzard.2.README.md file has also been checked for formatting and typos.
This commit is contained in:
1 parent
456f2d8ff3
commit
9f17036900
3 files changed
+64
-54
No files matched your search
@@ -111,7 +111,7 @@ PROG= ${ENTRY}
|
|||||||
#
|
#
|
||||||
OBJ= ${PROG}.o
|
OBJ= ${PROG}.o
|
||||||
DATA=
|
DATA=
|
||||||
TARGET= ${PROG}
|
TARGET= ${PROG} first
|
||||||
#
|
#
|
||||||
ALT_OBJ= ${PROG}.alt.o
|
ALT_OBJ= ${PROG}.alt.o
|
||||||
ALT_TARGET= ${PROG}.alt
|
ALT_TARGET= ${PROG}.alt
|
||||||
|
|||||||
+59
-49
@@ -7,7 +7,8 @@ make all
|
|||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
First:
|
First, you must make sure that first is made first (even though `make all`
|
||||||
|
should do it :-) ):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make first
|
make first
|
||||||
@@ -16,7 +17,10 @@ make first
|
|||||||
Second:
|
Second:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
# get help:
|
||||||
echo help | cat third help.th - | ./first
|
echo help | cat third help.th - | ./first
|
||||||
|
|
||||||
|
# try out a demo:
|
||||||
cat third demo5.th | ./first
|
cat third demo5.th | ./first
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -102,7 +106,7 @@ To do something interesting, you need to feed first the file
|
|||||||
[third](third) first. In unix, you can do
|
[third](third) first. In unix, you can do
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
% cat third help.th - | ./first
|
cat third help.th - | ./first
|
||||||
```
|
```
|
||||||
|
|
||||||
to do this. Hopefully most operating systems will provide a way to do this. It
|
to do this. Hopefully most operating systems will provide a way to do this. It
|
||||||
@@ -112,17 +116,18 @@ minutes on an 8086 PC); `THIRD` will prompt you when it is finished. The file
|
|||||||
part.
|
part.
|
||||||
|
|
||||||
For more information on what you can do once you've piped [third](third) into
|
For more information on what you can do once you've piped [third](third) into
|
||||||
first, type 'help' and consult FORTH manuals for further reference. Six sample
|
first, type 'help' and consult
|
||||||
THIRD programs are included in the files demo[1-6].th.
|
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) manuals for
|
||||||
[buzzard.2.README.md](buzzard.2.README.md) has more information.
|
further reference. Six sample THIRD programs are included in the files
|
||||||
|
demo[1-6].th. [buzzard.2.README.md](buzzard.2.README.md) has more information.
|
||||||
|
|
||||||
Keep in mind that you are still running first, and are for the most part limited
|
Keep in mind that you are still running `first`, and are for the most part
|
||||||
by `first`'s tokenizer (notably, unknown words will attempt to be parsed as
|
limited by `first`'s tokenizer (notably, unknown words will attempt to be parsed
|
||||||
integers.) It is possible to build a new parser that parses by hand, reading a
|
as integers.) It is possible to build a new parser that parses by hand, reading
|
||||||
single character at a time; however, such a parser cannot easily use the
|
a single character at a time; however, such a parser cannot easily use the
|
||||||
existing dictionary, and so would have to implement its own, thus requiring
|
existing dictionary, and so would have to implement its own, thus requiring
|
||||||
reimplementing all of first and third a second time--I did not care to tackle
|
reimplementing all of `first` and `third` a second time--I did not care to
|
||||||
this project.
|
tackle this project.
|
||||||
|
|
||||||
|
|
||||||
### Compiling
|
### Compiling
|
||||||
@@ -133,16 +138,16 @@ on smaller machines; `m[]` needs to be at least 2000 long, though.
|
|||||||
I say `first` is portable mainly because it uses native types. Unlike
|
I say `first` is portable mainly because it uses native types. Unlike
|
||||||
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language), which
|
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language), which
|
||||||
traditionally allows byte and multi-byte operations, all operations are
|
traditionally allows byte and multi-byte operations, all operations are
|
||||||
performed on C `int`s. That means first code is only as portable as the same
|
performed on C `int`s. That means `first` code is only as portable as the same
|
||||||
code would be in C. As in C, the result of dividing -1 by 2 is machine (or
|
code would be in C. As in C, the result of dividing `-1` by `2` is machine (or
|
||||||
rather compiler) dependent.
|
rather compiler) dependent.
|
||||||
|
|
||||||
### How is first obfuscated?
|
### How is first obfuscated?
|
||||||
|
|
||||||
`first` is obfuscated in several ways. Some minor obfuscations like
|
`first` is obfuscated in several ways. Some minor obfuscations like
|
||||||
`&w[&m[1]][s]` for `s+m[w+1]` were in the original source but are no longer
|
`&w[&m[1]][s]` for `s+m[w+1]` were in the original source but are no longer
|
||||||
because, apparently, ANSI doesn't allow it (gcc -ansi -pedantic doesn't mind it,
|
because, apparently, ANSI doesn't allow it (`gcc -ansi -pedantic` doesn't mind
|
||||||
though.)
|
it, though.)
|
||||||
|
|
||||||
Other related obfuscations are still present. The top of the stack is cached in
|
Other related obfuscations are still present. The top of the stack is cached in
|
||||||
a variable, which increases performance massively if the compiler can figure out
|
a variable, which increases performance massively if the compiler can figure out
|
||||||
@@ -153,47 +158,51 @@ register allocate it.)
|
|||||||
More significant are the design obfuscations. `m[0]` is the "dictionary
|
More significant are the design obfuscations. `m[0]` is the "dictionary
|
||||||
pointer", used when compiling words, and `m[1]` is the return stack index. Both
|
pointer", used when compiling words, and `m[1]` is the return stack index. Both
|
||||||
are used as integer offsets into `m`. Both are kept in `m`, instead of as
|
are used as integer offsets into `m`. Both are kept in `m`, instead of as
|
||||||
separate pointers, because they are then accessible to first programs, which is
|
separate pointers, because they are then accessible to `first` programs, which
|
||||||
a crucial property of first. Similarly the way words are stored in the
|
is a crucial property of `first`. Similarly the way words are stored in the
|
||||||
dictionary is not obvious, so it can be difficult to follow exactly what the
|
dictionary is not obvious, so it can be difficult to follow exactly what the
|
||||||
compiler words are doing.
|
compiler words are doing.
|
||||||
|
|
||||||
Assuming you've waded through all that, you still have to penetrate the most
|
Assuming you've waded through all that, you still have to penetrate the most
|
||||||
significant obfuscation. Traditionally, the question is whether a reader can
|
significant obfuscation. Traditionally, the question is whether a reader can
|
||||||
answer the question "what will this do when I run it". A reader who has
|
answer the question "what will this do when I run it". A reader who has
|
||||||
deciphered first to this point may think they know the answer to this question,
|
deciphered `first` to this point may think they know the answer to this
|
||||||
but they may not know the answer to the more important question, "what will this
|
question, but they may not know the answer to the more important question, "what
|
||||||
program do when given the right input?" FORTH aficionados, and especially FORTH
|
will this program do when given the right input?"
|
||||||
implementers, may recognize the similarity of the internal compiler format to
|
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) aficionados,
|
||||||
many FORTH internal representations, and, being aware that FORTH interpreters
|
and especially FORTH implementers, may recognize the similarity of the internal
|
||||||
can often be self-compiling, may be suspicious that this program can compile
|
compiler format to many FORTH internal representations, and, being aware that
|
||||||
FORTH, or a significant subset of it, or at least be capable of doing so if fed
|
FORTH interpreters can often be self-compiling, may be suspicious that this
|
||||||
the right input. Of course, the name "THIRD" should be a dead giveaway, if the
|
program can compile FORTH, or a significant subset of it, or at least be capable
|
||||||
name "first" wasn't. (These numbers were largely chosen because they were five
|
of doing so if fed the right input. Of course, the name "THIRD" should be a
|
||||||
letters long, like "FORTH", and would not require truncation to five letters,
|
dead giveaway, if the name "first" wasn't. (These numbers were largely chosen
|
||||||
which would be a dead giveaway. Besides, THIRD represents a step backwards, in
|
because they were five letters long, like "FORTH", and would not require
|
||||||
more ways than one.)
|
truncation to five letters, which would be a dead giveaway. Besides, THIRD
|
||||||
|
represents a step backwards, in more ways than one.)
|
||||||
|
|
||||||
|
|
||||||
### What exactly is `first`, then?
|
### What exactly is `first`, then?
|
||||||
|
|
||||||
`first` is a tiny interpreter which implements a sufficient pseudo-subset of
|
`first` is a tiny interpreter which implements a sufficient pseudo-subset of
|
||||||
FORTH to allow it to bootstrap a relatively complete version of FORTH (based
|
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) to allow it
|
||||||
loosely on forth79), which I call THIRD. Complete relative to what, I'm not
|
to bootstrap a relatively complete version of FORTH (based loosely on forth79),
|
||||||
sure.
|
which I call THIRD. Complete relative to what, I'm not sure.
|
||||||
|
|
||||||
I believe first is close to the smallest amount of code possible to get this
|
I believe `first` is close to the smallest amount of code possible to get this
|
||||||
effect *using forth-style primitives*, and still have some efficiency (it is
|
effect *using forth-style primitives*, and still have some efficiency (it is
|
||||||
possible to get by without multiplication if you have addition, obviously). In
|
possible to get by without multiplication if you have addition, obviously). In
|
||||||
the design file, design, I give a justification for why each primitive in first
|
the design file, design, I give a justification for why each primitive in
|
||||||
was included.
|
`first` was included.
|
||||||
|
|
||||||
THIRD is sorta slow, because first has so few primitives that many things that
|
THIRD is sorta slow, because `first` has so few primitives that many things that
|
||||||
are primitives in FORTH (like swap) take a significant amount of time in THIRD.
|
are primitives in
|
||||||
|
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) (like swap)
|
||||||
|
take a significant amount of time in THIRD.
|
||||||
|
|
||||||
When you get the 'Ok.' message from third, try out some sample FORTH code (first
|
When you get the `Ok.` message from third, try out some sample
|
||||||
|
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) code (first
|
||||||
has no way of knowing if keyboard input is waiting, so it can't actually prompt
|
has no way of knowing if keyboard input is waiting, so it can't actually prompt
|
||||||
you in a normal way. It only prints 'Ok.' after you define a word).
|
you in a normal way. It only prints `'Ok.'` after you define a word).
|
||||||
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -230,18 +239,19 @@ using by typing:
|
|||||||
here .
|
here .
|
||||||
```
|
```
|
||||||
|
|
||||||
The number THIRD replies with is the number of machine words (ints) that the
|
The number THIRD replies with is the number of machine words (`int`s) that the
|
||||||
dictionary (the first code) takes up, plus the 512 ints for the return stack.
|
dictionary (the first code) takes up, plus the 512 `int`s for the return stack.
|
||||||
If you compile the basic THIRD system without the help word (strings take up one
|
If you compile the basic THIRD system without the help word (strings take up one
|
||||||
int per character in the string!), you should find that you're using around 1000
|
`int` per character in the string!), you should find that you're using around
|
||||||
ints (plus the return stack).
|
1000 `int`s (plus the return stack).
|
||||||
|
|
||||||
Thus THIRD gives you a relatively complete FORTH system in less than 700 chars
|
Thus THIRD gives you a relatively complete
|
||||||
of C source + about 1000 ints of memory--and it's portable too (you could copy
|
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) system in
|
||||||
over the THIRD memory dump to another machine, in theory). If the above numbers
|
less than 700 chars of C source + about 1000 `int`s of memory--and it's portable
|
||||||
seem to you to be mixing apples and oranges (C source and compiled THIRD code),
|
too (you could copy over the THIRD memory dump to another machine, in theory).
|
||||||
note that you should in theory be able to stick the compiled THIRD code into the
|
If the above numbers seem to you to be mixing apples and oranges (C source and
|
||||||
C source.
|
compiled THIRD code), note that you should in theory be able to stick the
|
||||||
|
compiled THIRD code into the C source.
|
||||||
|
|
||||||
Software Construction Company gets credit for rekindling my interest in FORTH
|
Software Construction Company gets credit for rekindling my interest in FORTH
|
||||||
and thus indirectly inspiring me to write this program.
|
and thus indirectly inspiring me to write this program.
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ help.th online listing of THIRD primitives
|
|||||||
|
|
||||||
# FIRST demos:
|
# FIRST demos:
|
||||||
|
|
||||||
Use `first < {demo}`.
|
Use `./first < <demo>`.
|
||||||
|
|
||||||
demo1.1st prints Hello World! assuming ASCII
|
demo1.1st prints Hello World! assuming ASCII
|
||||||
|
|
||||||
# THIRD demos:
|
# THIRD demos:
|
||||||
|
|
||||||
Use `cat third {demo} | first`.
|
Use `cat third <demo> | ./first`.
|
||||||
|
|
||||||
demo1.th prints Hello World! regardless of character set
|
demo1.th prints Hello World! regardless of character set
|
||||||
demo2.th demonstrates a simple loop
|
demo2.th demonstrates a simple loop
|
||||||
@@ -23,7 +23,7 @@ demo6.th demonstrates switching from compiler to execution mode
|
|||||||
|
|
||||||
# Interactive THIRD:
|
# Interactive THIRD:
|
||||||
|
|
||||||
Use `cat third - | first`.
|
Use `cat third - | ./first`.
|
||||||
|
|
||||||
To include the primitive on-line help, use
|
To include the primitive on-line help, use
|
||||||
`cat third help.th - | first`.
|
`cat third help.th - | ./first`.
|
||||||
Reference in new issue
Block a user