(As an aside, I feel that this is what attracted the CollapseOS author to pursue Forth. Most of the folks interested in the retro collapse computing seem to really like creating artisinal/small team programs rather than large collaborations.)
A formal review process for merging any commit, requiring approvals from several developers; two or three experts on good Forth code practices the team; and a document outlining what those are --- ought to do it? I think.
Plus tooling. Forth can undoubtedly be linted for issues like definitions without stack effect annotations, so the reviewers don't have to waste time pointing that out.
I wouldn't even be able to find one, and likely, if I did their idea of what 'good Forth code practices' are would be a world away from mine. And in a way that is what makes Forth as interesting as it is, it's like that vest with a hundred pockets that has everything there just the way you like it. But for someone else that vest would not work at all, simply because they are not you.
https://news.ycombinator.com/item?id=21822840
Here's the interview with Mitch Bradley saved on archive.org:
https://web.archive.org/web/20120118132847/http://howsoftwar...
I've previously posted some stuff about Mitch Bradley -- I have used various versions of his ForthMacs / CForth / OpenFirmware systems, and I was his summer intern at Sun in '87!
Mitch is an EXTREMELY productive FORTH programmer! He explains that FORTH is a "Glass Box": you just have to memorize its relatively simple set of standard words, and then you can have a complete understanding and full visibility into exactly how every part of the system works: there is no mysterious "magic", you can grok and extend every part of the system all the way down to the metal. It's especially nice when you have a good decompiler / dissassembler ("SEE") like ForthMacs, CForth, and OpenFirmware do.
https://news.ycombinator.com/item?id=9271644
>DonHopkins on Mar 26, 2015 | parent | favorite | on: The Elusive Universal Web Bytecode
>The other "universal bytecode" that came out of Sun and actually has seen a lot of use is Mitch Bradley's Open Firmware Forth based boot ROMs, used by Suns' 68k, SPARC and x86 boxes, Apple's PPC Macs, IBM, ARM, OLCP XO-1, and many other systems.
>http://en.wikipedia.org/wiki/Open_Firmware
https://news.ycombinator.com/item?id=12240478
DonHopkins on Aug 7, 2016 | parent | favorite | on: “EFI? Intel has been trying to shove that down ou...
>Mitch Bradley originally developed a Forth system at Sun for use diagnosing and developing hardware, by burning it into ROM and running it via a serial port.
>It was based on Langston and Perry's Forth-83, and had a meta compiler that could target different word sizes and architectures. He made it even more architecture and word size independent, implemented interactive top level loops and conditionals, emacs-like line editing, all kinds of low level device drivers and testers that ran in stand-alone mode, and many other features, including full 16 and 32 bit support with a vocabulary for writing word size and endian independent code.
>He ported Sun Forth to 68K and SPARC Sun workstations, as well as the Amiga and other systems. It ran in both stand-alone mode (from disk, tftp or ROM), or under Unix. Under Unix, it could dynamically relocate and link in Unix libraries, and you could call back and forth between Forth and C.
>Sun Forth eventually evolved and standardized into the Open Firmware [1], whose purpose was to support machine independent byte code [2], so plug-in hardware cards could include ROMs with Forth byte code drivers that ran on 68K, SPARC, x86 and other systems.
>Sun shipped it with the SPARC workstations, Apple adopted it and shipped it on their PowerPC Macs, IBM shipped with their POWER servers, and Mitch worked directly with the OLPC project extending OpenFirmware to support the OLPC XO-1 Children's Computer secure and power efficient hardware. [3]
>>OLPC Wiki: Open Firmware
>>Open Firmware is the hardware-independent firmware (computer software which loads the operating system) that the XO runs.
>>It was developed by Mitch Bradley at Sun Microsystems, and used in post-NuBus PowerPC-based Apple Macintosh computers (though it has been dropped with Apple's transition to Intel processors), Sun Microsystems SPARC based workstations and servers, IBM POWER systems, and PegasosPPC systems, among others. On those computers, Open Firmware fulfills the same tasks as BIOS does on PC computers.
>>For example Fedora and Debian use the YaBoot BootLoader for Open Firmware.
>>The Open Firmware user interface includes a FORTH-based shell interface. FORTH is a powerful high level language that is remarkably compact. A complete Forth development environment including compiler, decompiler, assembler, disassembler, source level debugger, and assembly language debugger is present in the XO boot ROM (SPI FLASH). With the Open Firmware Forth system, you can directly access all of the hardware devices on the XO, use built-in functions like selftest diagnostics and games, and even write complete applications, without needing any external tools. The bulk of Open Firmware is written in Forth, so the source level debugger can be used to debug Open Firmware itself.
>[1] http://www.openfirmware.info
>[2] http://www.openfirmware.info/FCODE_suite
>[3] http://wiki.laptop.org/go/Open_Firmware
https://news.ycombinator.com/item?id=15040859
>DonHopkins on Aug 17, 2017 [-]
>Emacs qualifies as a window manager in my book! ;)
>That code you linked to is from Mitch Bradley's "Forthmacs", which ran on Sun workstations including 68k i86 and SPARC, and also Atari ST, Mac and other systems. He developed it into the "Open Boot ROM" architecture, which was used in Sun workstations and Apple PowerPC Macs as well as the OLPC children's laptop.
>https://github.com/ForthHub/ForthFreak/blob/master/Forthmacs
>https://en.wikipedia.org/wiki/Open_Firmware
>http://wiki.laptop.org/go/Open_Firmware
>On SunOS, Forthmacs had a library clink.f with the ability to dynamically relocate and link Unix libraries so that you could call them from Forthmacs, pass arguments on the stack, etc. SunOS didn't actually support shared libraries or dynamic address relocating at that time, so Forthmacs simply ran the Unix linker utility to create a file with the library relocated to the desired address space in the FORTH dictionary, and then read that file into memory, define its symbols in the FORTH dictionary, and let you access its variables and call its functions directly from FORTH!
>That's how Mitch originally integrated MicroEmacs with Forth to make Forthmacs, and how I later integrated "uwm" into FORTH: I refactored uwm so instead of having an event loop in the main function, it was a library that could be called by FORTH, which would link the library in and run the main loop itself, calling into the library as needed to initialize and handle specific events (_uwm_init, _uwm_poop).
http://www.donhopkins.com/home/archive/piemenu/uwm1/fuwm-mai...
>Here's the glue that links in the uwm library from fuwm.out:
http://www.donhopkins.com/home/archive/piemenu/uwm1/load-fuw...
.( Loading...) cr
requires tasking.f
requires uwm.f
requires clink.f
.( Linking...) cr
"" fuwm.out clink
.( Linked!) cr
https://news.ycombinator.com/item?id=17480298>DonHopkins on July 7, 2018 | parent | favorite | on: Tali Forth 2 for the 6502
>Cool! Does it include a FORTH 6502 assembler written in FORTH? I love writing assembly code in RPN with Forth macros!
>You can write FORTH code with loops and conditionals and any kind of logic and parameters, that dynamically assembles machine code! Much better than your typical macro assembler.
>Here's some 6502 assembler for an Apple ][ SUPDUP terminal emulator that does ram card bank switching:
>http://www.donhopkins.com/home/archive/forth/supdup.f
>Here's some Forth 68k assembler that draws lines on a weird Sun-2 CGONE graphics board.
>http://www.donhopkins.com/home/archive/forth/cg/bline.f
>Mitch Bradley's 68k forth lets you use interactive conditionals and loops in the top level outer interpreter!
>I think he wrote a paper about that feature, which I might be able to dig up ... Here's something related he wrote about refactoring the outer interpreter, but not what I'm thinking of:
https://groups.google.com/forum/#!topic/comp.lang.forth/lKQj...
>avhon1 on July 7, 2018 [-]
>> Does it include a FORTH 6502 assembler written in FORTH?
https://github.com/scotws/TaliForth2/blob/master/docs/manual...
>>Currently, there is no assembler included. The plan is to include a simple assembler based on Simpler Assembler Notation (SAN).
>It does include a disassembler: https://github.com/scotws/TaliForth2/blob/master/docs/ch_dis...
>The author has written a 6502 assembler in gforth: https://github.com/scotws/tasm65c02
>Here is a document describing the notation: https://docs.google.com/document/d/16Sv3Y-3rHPXyxT1J3zLBVq4r...
>DonHopkins on July 7, 2018 [-]
>I got a quick reply from Mitch Bradley!
>Yes I wrote a paper but I probably can't find it. The easiest place to look would be in the Open Firmware source.
>https://github.com/MitchBradley/openfirmware/blob/master/for...
>The magic is all in +level and -level. Search for those in kernel.fth to see other places they are used to achieve a similar effect, e.g. in abort"
>For an alternative but effectively equivalent formulation, see:
>https://github.com/MitchBradley/cforth/blob/master/src/cfort...
>and
>https://github.com/MitchBradley/cforth/blob/master/src/cfort...
lukego on Dec 18, 2019 [–]
I love your posts about this stuff :)
I was also an "intern" of sorts for Mitch as recently as 2009 or so. I wrote the audio driver for OLPC XO 1.5 and went to Taipei to help with the bringup. I was amazed to watch Mitch using Forth to interactively tweak the DDR memory settings, find bugs in the motherboard, and find bugs in the CPU which was a godawful x86 from VIA that had seemingly only been debugged enough to boot windows :)
DonHopkins on Dec 18, 2019 | parent [–]
That must have been a fun and unique opportunity! His programming and debugging process has to be seen to be believed. OpenFirmware is definitely a highly polished work of love. Its well-commented and meticulously organized source code reads like fine literature or classical music! Stuff like the metacompiler and kernel, for example:
https://github.com/MitchBradley/openfirmware/blob/master/for...
https://github.com/MitchBradley/openfirmware/blob/master/for...
FORTH ?KNOW IF
HONK!
ELSE
FORTH LEARN!
THEN FORTH KNOW
HONK
FORTH LEARN
IFELSE/PostScript Know? { Honk! } { /PostScript Learn! } ifelse
FORTH doesn't have an IFELSE unless you define it yourself of course, but it would have no way of telling which part of your code was the conditional, part to do if true, or part to do if false, since white space and line breaks have no meaning to it, except for a few cases like \ comments. The IF comes between the conditional and the part to do if true, the ELSE comes between the part to do if true and the part to do if false, and the THEN comes at the end.
The structure of PostScript code, conditionals, and flow control is homoiconic, made of nested arrays, like polymorphic JSON arrays, where FORTH code is flat untyped arrays of threaded pointers with relative branching.
Forth has an "inner interpreter" called NEXT that threads from one pointer to the next (sometimes implemented as one machine language instruction, or just a few), and also an "outer interpreter" or compiler that translates text into threaded code for the inner interpreter.
https://en.wikipedia.org/wiki/Polymorphism_(computer_science...
https://en.wikipedia.org/wiki/Homoiconicity
https://en.wikipedia.org/wiki/Threaded_code
Here's Mitch Bradley's implementation of interactive control structures (IF, ELSE, THEN, BEGIN, UNTIL, AGAIN, REPEAT, WHILE, DO, LOOP, etc) in the outer interpreter of his FORTH system, which actually allows you to use conditionals and loops at the interactive top level of the interpreter, not just in compiled words (which solves a traditional and frustrating limitation of classic FORTH).
https://github.com/MitchBradley/openfirmware/blob/master/for...
Here is an alternative but equivalent implementation of interactive Forth control structures in his CForth (Forth implemented in C, of course):
https://github.com/MitchBradley/cforth/blob/master/src/cfort...
Here's some more of Mitch's beautiful code from OpenFirmware, his Forth kernel meta-compiler written in Forth, which supports 8, 16, 32, an 64 bit, big-endian and little-endian architectures, as well as direct, indirect, and token threaded code:
https://github.com/MitchBradley/openfirmware/blob/master/for...
https://en.wikipedia.org/wiki/Threaded_code#Direct_threading
https://en.wikipedia.org/wiki/Threaded_code#Indirect_threadi...
I can't find any reference to this in ANS Forth 1994, other than appendix C. 3 Hardware Implementations of Forth which says: "In the mid-1980’s Zilog developed the z8800 (Super8) which offered ENTER (nest), EXIT (unnest) and NEXT in microcode." (which is interesting, by the way).
https://github.com/nornagon/jonesforth/blob/master/jonesfort...
This is fairly typical.
Interesting; it's "like a return" because it's a form of continuation: a tail call to the next thing.
I wonder if this could be done in C with function pointers? If we end a function like this:
typedef void (*fptr_t)(); // old-style, on purpose
void primitive(fptr_t *ppSelf) // pointer into array of fptr_t's
{
// ... perform primitive
(*++ppSelf)(); // increment to NEXT primitive and call
}
Will modern C compilers turn this indirect call in tail position into a tail call, like a direct call.Alternatively, you could implement your own data stack and use the regular stack for control flow, but this would incur a performance penalty.
See those () at the end of your 'next' are exactly what you don't want, they will mess up the stack. Now you have to start the definition of every word with something that eats up that return address and the stack frame set up at the beginning of the word definition again. You don't really need either of those. But you do need a data stack.
The C compiler typically compiles that code with the big switch statement into an efficient jump table, behind the scenes.
https://github.com/MitchBradley/cforth/blob/master/src/cfort...
Properly speaking, that's a token threaded interpreter, since it switches on token numbers in the code field, instead of indirecting function through pointers to the C equivalent of "code" words.
https://en.wikipedia.org/wiki/Threaded_code#Token_threading
Compiled user defined Forth colon definitions, <builds and does> definitions, etc, do thread through code field address pointers though -- see the default case of the switch statement:
https://github.com/MitchBradley/cforth/blob/master/src/cfort...
At the other end of the spectrum, there's the Novix Forth Engine!
https://news.ycombinator.com/item?id=8860786
>DonHopkins on Jan 9, 2015 | parent | context | favorite | on: Design of Lisp-Based Processors Or, LAMBDA: The Ul...
>The Novix FORTH chip was a pretty cool implementation of FORTH in hardware -- it had separate data and return stacks, which it could push or pop at the same time, so the compiler could combine several FORTH words into one opcode.
http://users.ece.cmu.edu/~koopman/stack_computers/sec4_4.htm...
>The Novix NC4016, formerly called the NC4000, is a 16-bit stack based microprocessor designed to execute primitives of the Forth programming language. It was the first single-chip Forth computer to be built, and originated many of the features found on subsequent designs. Intended applications are real time control and high speed execution of the Forth language for general purpose programming.
>The NC4016 uses dedicated off-chip stack memories for the Data Stack and the Return Stack. Since three separate groups of pins connect the two stacks and the RAM data bus to the NC4016, it can execute most instructions in a single clock cycle.
https://web.archive.org/web/20160402032358/http://www.forth....
>The NC4000P is a single chip FORTH Engine based upon minimum hardware concepts developed by Mr. Charles H. Moore. This highly parallel machine architecture directly executes FORTH primitives in a single clock cycle. The initial implementation of this device is based upon a 4000 gate CMOS semicustom integrated circuit operating at an 8 MHz clock rate.
But I'm preaching to the choir, Jacques! ;) Dadadatablblblblbl!
https://news.ycombinator.com/item?id=3814155
>jacquesm on April 8, 2012 | parent | context | favorite | on: A Forth Story...
>Quite a story, and it seems it does not have a happy ending, but for all the wrong reasons. About 2/3rds in (past the 'read more') the Novix rates a mention. I think that that is possibly the most underrated CPU design that ever saw the light of day, at the time it was so out of the ordinary that only very few people knew what to do with it.
>A high level language (forth is by most definitions a high level language) directly executed by the CPU.
>At the time I worked for a company called dadadata in the Netherlands, they were in the process of developing a bunch of real time software to process video images for classification and recognition (1988 or thereabouts). The Novix chip arrived and would have definitely blown the socks of anything that I could have done with a regular PC at the time, if not for one small problem: someone dropped a dime into the power supply and the whole development kit was toast. A couple of all nighters later we had a working reproduction of the code in 'C' and that was used for the customer demonstrations. Still, the power of that little chip is something I'll never forget and it is a pity that the Novix and its successor which iirc was called shboom never made real headway. The forth code for the novix was probably only about 10% or so in size of the equivalent C code. The head forth honcho there called C sneeringly a 'great' language.
>There is still hope, even today that one day that power will finally be available in some package that sees wide distribution, the heritage of Novix lives on in the greenarrays line (which is now shipping dev boards and chips).
http://www.greenarraychips.com/
>To kill forth and the concepts behind it permanently will take a lot of garlic and stakes, I think it will always have its champions.
DonHopkins 6 months ago | parent | context | favorite | on: Moving Forth (1993)
>Some FORTH systems even have a "metacompiler" that lets one FORTH system compile another FORTH system for the same or different CPU, word size, byte order, threading technique, with or without a built-in compiler, etc, from the same source code!
>OpenFirmware (the FORTH burnt into boot roms of SPARC, PowerPC, OLPC, and other systems) is a great highly refined example that supports many different architectures:
>openfirmware/forth/kernel/metacompile.fth
https://github.com/openbios/openfirmware/blob/master/forth/k...
>openfirmware/forth/kernel/meta1.fth
https://github.com/openbios/openfirmware/blob/master/forth/k...
The OpenFirmware kernel is a Forth meta-compiler, which can compile itself on any architecture, and also cross-compile for different target architectures.
It has cross-architecture extensions to FORTH (like \16 \32 comments and /n /n* generically typed words) that make it possible to write platform, word size, byte order, and threading independent code, and compile images (stripped or with headers) for embedded systems (like the OLPC boot ROMs) and new CPU architectures (like Sun's transition from 68K to SPARC), and share code with a more powerful development environments.
https://en.wikipedia.org/wiki/Compiler-compiler#Forth_metaco...
>Many advocates of the language Forth call the process of creating a new implementation of Forth a meta-compilation and that it constitutes a metacompiler. The Forth definition of metacompiler is:
>"A metacompiler is a compiler which processes its own source code, resulting in an executable version of itself."
>This Forth use of the term metacompiler is disputed in mainstream computer science. See Forth (programming language) and History of compiler construction. The actual Forth process of compiling itself is a combination of a Forth being a self-hosting extensible programming language and sometimes cross compilation, long established terminology in computer science. Metacompilers are a general compiler writing system. Besides the Forth metacompiler concept being indistinguishable from self-hosting and extensible language. The actual process acts at a lower level defining a minimum subset of forth words, that can be used to define additional forth words, A full Forth implementation can then be defined from the base set. This sounds like a bootstrap process. The problem is that almost every general purpose language compiler also fits the Forth metacompiler description.
>When (self-hosting compiler) X processes its own source code, resulting in an executable version of itself, X is a metacompiler.
>Just replace X with any common language, C, C++, Pascal, COBOL, Fortran, Ada, Modula-2, etc. And X would be a metacompiler according to the Forth usage of metacompiler. A metacompiler operates at an abstraction level above the compiler it compiles. It only operates at the same (self-hosting compiler) level when compiling itself. One has to see the problem with this definition of metacompiler. It can be applied to most any language.
>However, on examining the concept of programming in Forth, adding new words to the dictionary, extending the language in this way is metaprogramming. It is this metaprogramming in Forth that makes it a metacompiler.
>Programming in Forth is adding new words to the language. Changing the language in this way is metaprogramming. Forth is a metacompiler because Forth is a language specifically designed for metaprogramming. Programming in Forth is extending Forth adding words to the Forth vocabulary creates a new Forth dialect. Forth is a specialized metacompiler for Forth language dialects.
Mitch's OpenFirmware code is one end of the readability spectrum. But for shock value, here are some beautiful but inscrutable FORTH code excerpts that define cellular automata rules with lots of deeply nested conditionals around mysterious but exquisitely indented BEEPS and BOOPS and line noise that makes Perl look clean and elegant. ;)
https://donhopkins.com/home/code/tomt-users-forth-scr.txt
( A-BOMB) 24 LOAD
: KN C0 X0 Y0 Z0 + + + C1 X1 Y1 Z1 + + + * 0> ;
: KC C0 C1 * X0 X1 * Y0 Y1 * Z0 Z1 * + + + 0> ;
: EXPL X1 Y1 + X1 Y1 * - ;
: RULE0 C0 KN IF DROP 0 THEN KC IF DROP 0 THEN
C0 C1 * 1 = IF DROP 1 THEN ;
: RULE1 Z1 KN IF DROP EXPL THEN KC IF DROP 0 THEN
C0 C1 * 1 = IF DROP 1 THEN ;
( CASEN ) FORGET TASK : TASK ;
: NSUM NORTH SOUTH EAST WEST N.WEST N.EAST S.WEST
S.EAST CENTER + + + + + + + + ;
: CASEN NSUM 0 = IF 0 ELSE
NSUM 1 = IF 0 ELSE
NSUM 2 = IF 1 ELSE
NSUM 3 = IF 0 ELSE
NSUM 4 = IF 0 ELSE
NSUM 5 = IF 0 ELSE
NSUM 6 = IF 0 ELSE
NSUM 7 = IF 0 ELSE
NSUM 8 = IF 0 ELSE
NSUM 9 = IF 0 ELSE
THEN THEN THEN THEN THEN THEN THEN THEN THEN
THEN ; <T>
( BRAIN ) 36 LOAD
: CENTERS CENTER1 2 * CENTER + ;
: FEEP CENTERS 0 = IF 1 ELSE
CENTERS 1 = IF 0 ELSE
CENTERS 2 = IF 0 ELSE
CENTERS 3 = IF 0 ELSE THEN THEN THEN THEN ;
: RULE CASEN FEEP AND ;
<T> f1
BBM01
( READY ) FORGET TASK : TASK ;
: CENTERS CENTER1 2 * CENTER + ;
: READY CENTERS 0 = IF 1 ELSE
CENTERS 1 = IF 0 ELSE
CENTERS 2 = IF 0 ELSE
CENTERS 3 = IF 0 ELSE THEN THEN THEN THEN ;
<T>
( PUCCIO1) 24 LOAD
: K7 C0 C1 * X0 X1 * Y0 Y1 * Z0 Z1 * + + + 0<> ;
: K71 C0 C1 X0 1 X1 Y0 Y1 Z0 Z1 + + + + + * * * 1 = ;
: K72 X0 X1 Z0 1 C0 C1 Y0 Y1 Z1 + + + + + * * * 1 = ;
: K73 Z0 Z1 Y0 1 Y1 C0 C1 X0 X1 + + + + + * * * 1 = ;
: K74 Y0 Y1 C0 1 C1 X0 X1 Z0 Z1 + + + + + * * * 1 = ;
: K81 X0 X1 Y0 1 C0 C1 Z0 Z1 Y1 + + + + + * * * 1 = ;
: K82 Z0 Z1 C0 1 X0 X1 Y0 Y1 C1 + + + + + * * * 1 = ;
: K83 Y0 Y1 X0 1 Z0 Z1 C0 C1 X1 + + + + + * * * 1 = ;
: K84 C0 C1 Z0 1 Y0 Y1 X0 X1 Z1 + + + + + * * * 1 = ;
-->
: RULE0 Y1 (
X1 Z1 + Z1 Y1 + Y1 C1 + * * 1 = IF DROP C1 THEN )
K7 IF DROP Z0 THEN K71 IF DROP 0 THEN K72 IF DROP 1 THEN
K73 IF DROP 0 THEN K74 IF DROP 1 THEN K81 IF DROP 0 THEN
K82 IF DROP 1 THEN K83 IF DROP 1 THEN K84 IF DROP 0 THEN
;
( DOUBLE GAS etoile on P0 and P1) 24 LOAD
: KK C0 X0 Y0 Z0 + + + 1+ C1 X1 Y1 Z1 + + + 1+ * 5 = ;
( rotate right/left w/collisions )
: RULE0 KC0 IF C0 ELSE
T0 0= IF Y0 ELSE X0 THEN
THEN
KK IF DROP C1 THEN ;
( diagonal gas, w/collisions)
: RULE1 KC1 IF
X1 ELSE
Z1 THEN
KK IF DROP C0 THEN ;
BBM01
https://donhopkins.com/home/code/tomt-cam-forth-scr.txt ( MENU of keys ) VARIABLE UNFLG
: ?UNDEF UNFLG @ IF OUT @ SWAP $. OUT @ - 6 + SPACES
." is undefined" ELSE DROP THEN ;
: K. ( string.addr --) FIND IF OUT @ OVER >NAME .NAME
OUT @ - 6 + SPACES >BODY BEGIN
DUP @ ['] ;S <> WHILE
DUP @ >NAME .NAME 2+ REPEAT
DROP ELSE ?UNDEF
THEN ;
( == creates fast code words for picking out bits of variable X)
VARIABLE X CODE X! AX POP X , AX MOV NEXT, END-CODE
CODE X@ AX, X MOV AX PUSH NEXT, END-CODE
CREATE ZPUSH ASSEMBLER 1$ JNZ AX, # 0 MOV AX PUSH NEXT,
1$: AX, # 1 MOV AX PUSH NEXT,
: X? ( mask byt#-) ASSEMBLER AL, X + MOV AL, # TEST ZPUSH JMP ;
0 CARRAY 2^N 1 C, 2 C, 4 C, 8 C, 10 C, 20 C, 40 C, 80 C,
: == ( bit# --) ( ---- name ) >R [COMPILE] CODE
R> 8 /MOD SWAP 2^N C@ SWAP X? ASSEMBLER [COMPILE] END-CODE ;
1 == NORTH 3 == WEST 5 == N.WEST 7 == S.WEST 9 == CENTER1
2 == SOUTH 4 == EAST 6 == N.EAST 8 == S.EAST 0 == CENTER
( eg. NORTH will return bit #1 of X when executed ) -->
: #DX! ASSEMBLER DX, # MOV ; : #AL! ASSEMBLER AL, # MOV ;
: AL.IN ASSEMBLER AL, DX IN ; : AL.OUT ASSEMBLER DX, AL OUT ;
: SRCE BEGIN ?STEPPING @ (?TERMINAL) NOT AND WHILE STEPPING
REPEAT (?TERMINAL) DLAST @ AND DNUM @ 0= OR
SRCE.SEG SPOINT @ @L 0= OR IF
SAVE.INPUT KSAV ELSE
SRCE.SEG SPOINT GET DUP KPUT DUP DLAST C! THEN ;
Forth programs tend to have a pretty distinct style, closely related to whoever wrote them. Some see this as an advantage, for others it is a huge drawback because they can't or won't put themselves into a mental model that is non-obvious at first reading. This is however not a defect, it is pretty much the intention: Forth is a language to create DSLs, the words you define make up that new language and that is the language that you will ultimately solve your problem in. I haven't done any serious Forth coding in over two decades but when I did I loved working with it. But if I had to do it today my gripes would not be with the language as such but with how hard it would be to make a Forth project into a team effort.
Forth is an artisans tool, it is for making jewelry, not for making apartment buildings.