Merge pull request #197 from xexyl/1992-buzzard.2

Fixes in 1992/buzzard.2/README.md
This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-03-28 14:44:30 -07:00
commit 156d776a89
1 file changed
+30 -26
+30 -26
View File
@@ -10,7 +10,7 @@
make all make all
### To run ## To run:
First: First:
@@ -26,13 +26,16 @@
cat third help.th - | ./first cat third help.th - | ./first
NOTE: Wait until Ok is printed and the type: NOTE: Wait until Ok is printed and the type:
2 3 + . cr <-- yes you should really type the 2 letters: cr
Forth: 2 3 + . cr
Yes you should really type the 2 letters: cr.
Fourth:
Sorry, this is third! Sorry, this is third!
### Alternate code ## Alternate code:
An alternate version of this entry, `buzzard.2.alt.c`, is provided. This alternate code An alternate version of this entry, `buzzard.2.alt.c`, is provided. This alternate code
does not contain a fix that the author notes below. does not contain a fix that the author notes below.
@@ -51,7 +54,7 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
What it does: What it does:
first implements a relatively primitive stack machine. How `first` implements a relatively primitive stack machine. How
primitive? It supplies 13 visible primitives: 3 arithmetic, primitive? It supplies 13 visible primitives: 3 arithmetic,
1 comparison, 2 memory-access, 2 character I/O, 3 primitives 1 comparison, 2 memory-access, 2 character I/O, 3 primitives
for defining new words, 1 tokenizing, and 1 special stack for defining new words, 1 tokenizing, and 1 special stack
@@ -70,16 +73,16 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
further down. further down.
How to run it: ### How to run it:
first expects you to first enter the names of the 13 primitives, `first` expects you to first enter the names of the 13 primitives,
separated by whitespace--it doesn't care what you name them, but separated by whitespace--it doesn't care what you name them, but
if all the names aren't unique, you won't be able to use some of if all the names aren't unique, you won't be able to use some of
them. After this you may type any sequence of valid first input. them. After this you may type any sequence of valid first input.
Valid first input is defined as any sequence of whitespace-delimited Valid first input is defined as any sequence of whitespace-delimited
tokens which consist of primitives, new words you've defined, and tokens which consist of primitives, new words you've defined, and
integers (as parsed by "%d"). Invalid input behaves unpredictably, integers (as parsed by `"%d"`). Invalid input behaves unpredictably,
but gives no warning messages. A sample program, demo1.1st, is but gives no warning messages. A sample program, `demo1.1st`, is
included, but it only works on ASCII systems. included, but it only works on ASCII systems.
Do not expect to be able to do anything interesting with first. Do not expect to be able to do anything interesting with first.
@@ -87,7 +90,7 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
To do something interesting, you need to feed first the file To do something interesting, you need to feed first the file
third first. In unix, you can do third first. In unix, you can do
% cat third help.th - | first % cat third help.th - | ./first
to do this. Hopefully most operating systems will provide a to do this. Hopefully most operating systems will provide a
way to do this. It may take some time for this to complete way to do this. It may take some time for this to complete
@@ -112,23 +115,23 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
a second time--I did not care to tackle this project. a second time--I did not care to tackle this project.
Compiling: ### Compiling:
first is reasonably portable. You may need to adjust the `first` is reasonably portable. You may need to adjust the
size of the buffers on smaller machines; m[] needs to be size of the buffers on smaller machines; `m[]` needs to be
at least 2000 long, though. at least 2000 long, though.
I say first is portable mainly because it uses native types. I say `first` is portable mainly because it uses native types.
Unlike FORTH, which traditionally allows byte and multi-byte Unlike FORTH, which traditionally allows byte and multi-byte
operations, all operations are performed on C 'int's. That operations, all operations are performed on C `int`s. That
means first code is only as portable as the same code would 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 be in C. As in C, the result of dividing -1 by 2 is machine
(or rather compiler) dependent. (or rather compiler) dependent.
How is first obfuscated? ### How is first obfuscated?
first is obfuscated in several ways. Some minor obfuscations `first` is obfuscated in several ways. Some minor obfuscations
like &w[&m[1]][s] for s+m[w+1] were in the original source like `&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 but are no longer because, apparently, ANSI doesn't allow it
(gcc -ansi -pedantic doesn't mind it, though.) (gcc -ansi -pedantic doesn't mind it, though.)
Other related obfuscations are still present. The top of the Other related obfuscations are still present. The top of the
@@ -138,8 +141,8 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
is a global variable and neither gcc nor most bundled compilers is a global variable and neither gcc nor most bundled compilers
seem to register allocate it.) seem to register allocate it.)
More significant are the design obfuscations. m[0] is the More significant are the design obfuscations. `m[0]` is the
"dictionary pointer", used when compiling words, and m[1] is "dictionary pointer", used when compiling words, and `m[1]` is
the return stack index. Both are used as integer offsets into the return stack index. Both are used as integer offsets into
m. Both are kept in m, instead of as separate pointers, m. Both are kept in m, instead of as separate pointers,
because they are then accessible to first programs, which is a because they are then accessible to first programs, which is a
@@ -154,22 +157,22 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
to this point may think they know the answer to this question, to this point may think they know the answer to this question,
but they may not know the answer to the more important question, but they may not know the answer to the more important question,
"what will this program do when given the right input?" FORTH "what will this program do when given the right input?" FORTH
afficianados, and especially FORTH implementors, may recognize aficionados, and especially FORTH implementers, may recognize
the similarity of the internal compiler format to many FORTH the similarity of the internal compiler format to many FORTH
interal representations, and, being aware that FORTH interpreters internal representations, and, being aware that FORTH interpreters
can often by self-compiling, may be suspicious that this program can often by self-compiling, may be suspicious that this program
can compile FORTH, or a significant subset of it, or at least be can compile FORTH, or a significant subset of it, or at least be
capable of doing so if fed the right input. Of course, the name capable of doing so if fed the right input. Of course, the name
"THIRD" should be a dead giveaway, if the name "first" wasn't. "THIRD" should be a dead giveaway, if the name "first" wasn't.
(These numbers were largely chosed because they were five letters (These numbers were largely chosen because they were five letters
long, like "FORTH", and would not require truncation to five long, like "FORTH", and would not require truncation to five
letters, which would be a dead giveaway. Besides, THIRD represents letters, which would be a dead giveaway. Besides, THIRD represents
a step backwards, in more ways than one.) 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 `first` is a tiny interpreter which implements a sufficient
pseudo-subset of FORTH to allow it to bootstrap a relatively pseudo-subset of FORTH to allow it to bootstrap a relatively
complete version of FORTH (based loosely on forth79), which complete version of FORTH (based loosely on forth79), which
I call THIRD. Complete relative to what, I'm not sure. I call THIRD. Complete relative to what, I'm not sure.
@@ -189,8 +192,10 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
waiting, so it can't actually prompt you in a normal way. It waiting, so it can't actually prompt you in a normal way. It
only prints 'Ok.' after you define a word). only prints 'Ok.' after you define a word).
2 3 + . cr ( add 2 and 3, and print it and a newline.) 2 3 + . cr ( add 2 and 3, and print it and a newline.)
and THIRD responds and THIRD responds
5 5
@@ -226,7 +231,6 @@ Use `buzzard.2.alt` as you would `buzzard.2` above.
in theory be able to stick the compiled THIRD code into in theory be able to stick the compiled THIRD code into
the C source. the C source.
Software Construction Company gets credit for rekindling Software Construction Company gets credit for rekindling
my interest in FORTH and thus indirectly inspiring me my interest in FORTH and thus indirectly inspiring me
to write this program. to write this program.