r/Forth 25d ago

UtaForth: 322-byte 16-bit Forth in Netwide Assembler (NASM)

https://github.com/Fuwn/UtaForth
22 Upvotes

10 comments sorted by

6

u/s1nical 25d ago edited 22d ago

UtaForth now registers at just 289 bytes.

https://github.com/Fuwn/UtaForth

2

u/ekipan85 24d ago edited 24d ago

You can save an easy 14-17 bytes by renaming most of your builtin words to 1-letter names. sp@ rp@ 0# nand key emit s@ could be p r z n k e s or something. If you care you could then recover the long names in Forth:

: key k ;
: emit e ;
\ etc
\ exit and rp@ would be a problem but you 
\ could decide to tolerate the short names

Also -1 has a much smaller and faster definition : -1 s@ 0# ; or with the above short names : -1 s z ;.

The ANS standard name for 0# is 0<>, I was curious why Milliforth chose the weird name when I wrote my own Milliforth fork.

1

u/s1nical 23d ago edited 22d ago

On the safer side, about 12 extra bytes could be saved just by renaming words, but I wanted to keep the word lineage intact by using the same words that milliForth, the inspiration for this project, used, which, in turn, employed similar words to those of sectorforth, an inspiration for milliForth.

In the meantime, I ended up shedding another 12 bytes, bringing it down to 291, so I've nearly compensated for it in spirit.

1

u/Imaginary-Deer4185 24d ago

Is it a correct observation that the parser doesn't understand integers?

1

u/s1nical 23d ago

Yes, that's correct. The core parser only tokenises whitespace-delimited words and looks them up in a dictionary; it has no path for numeric conversion. The sample bootstrap processes make numbers usable by defining tiny numeric words like 0, 1, 2, etc., and later by compiling literals with lit/, tricks. A bare 42 is not parsed as an integer unless 42 is a defined word.

1

u/minforth 22d ago

Personally, I wouldn't call it Forth then. It's more of a stack-based command interpreter, perhaps useful for launching other programs. This isn't a criticism of your work, but readers may have somewhat different expectations when they see the name โ€œForth.โ€ You don't have to go as far as the bare-bones CORE wordset of Standard Forth, but that's pretty much the gist of it.

1

u/s1nical 22d ago edited 22d ago

I appreciate the framing, but I'll push back on the substance: by that expectation, neither milliForth nor sectorforth, nor plenty of smaller (hobbyist, historical, application-specific) Forths, would be a Forth. That's kind of the beauty of Forth, actually, and I've attached some quotes I often look back on that remind me of it.

Chuck Moore: Forth is an extensible language. It has a basic structure of stacks and dictionary. Beyond that it can be augmented as required for any particular problem. (Chuck Moore on the Lost Art of Keeping It Simple )

...

The programmer can create structures that are just as efficient as those provided by the compiler. So all capabilities do not have to be anticipated and provided for. (About Forth)

Forth standards, such as ANS or Forth 2012, are opt-in by design. Forth Inc. explicitly states compliance is optional, and Chuck dismisses standardisation outright.

Chuck Moore: What can I say? Backus did not mention Forth in his lecture. He probably didn't know of it then. Yet Forth addresses many of his criticisms of conventional languages.

He thinks a language needs or benefits from a formal specification. I grew up worshiping Principia Mathematica 'till I learned how Goedel refuted it. The result is that I distrust formal representations. For example, the ANSI Forth standard does not describe Forth, but a language with the same name. (Chuck Moore Holds Forth)

1

u/ekipan85 22d ago edited 19d ago

If I understand correctly, it's also not interactive which IMO is much more fundamental to a Forth. It assembles into a DOS program that reads all of stdin once at startup, interprets it, then exits back to DOS.

Just like milliforth it has key and emit and enough builtins to build a numbers parser and control structures so you might be able to build an actual interactive Forth on top of it. Unlike milliforth it isn't a bootsector program, it's hosted by DOS.

My own milliforth fork completely guts the design, spending the saved bootsector bytes on decoupling the internals of the interpreter and making most of it reusable in a hypothetical stage 2 interpreter written in Forth, but I didn't go that far as I agree, none of these sectorforth offshoots are practical enough to be worth putting in effort to complete them. It was a damn fun optimization exercise though, and educational!

Maybe I should make a post proper for nictoforth. Edit: posted

1

u/minforth 21d ago

No objection. You can call it a car even when it is only the motor. ๐Ÿ˜‰

2

u/alberthemagician 20d ago

If you want to add numbers, you add #. It parses the following characters and compose it to a number.

I have used that in my ciforth for each of 1 2 3 4 5 6 7 8 9 and declare them a prefix, such that e.g. 7 is found in the dictionary not followed by blank space. This eleminates the special case for numbers.