Ahoj Pavle. Popravdě jsem čekal, že zmíníš Smalltalk a jeho minimalistickou VM. To je skoro doslova pár instrukcí ne?
(mimochodem - trošku plánuju reiteraci TinyBasicu s poli nativně pro AArch64. Tím, že je ta VM maličkatá, by se mohl obejít problém s I-cache (celý VM by byl na pár cache line), takže uvidíme.
Tak minimalistická, abych si to dovolil, zase není ;-)
Spíš bych v tomto případě šel jinou cestou. Když se podíváš na Self, funguje flastně jako systém vzájemně provázaných Forthovských slovníků s pozdní vazbou, které mezi sebou delegují vyhledávání. Když by se ve Forthu udělal jednoduchý GC a některá slova se používala jako selektory pro sloty s kódovým slovem provádějícím delegaci, mohl by se Selfovský objektový systém velice elegantně bootstrapnout.
Jedná se spíše jen o úhel pohledu.
Když se vyhledává slovo ve Forthu, tak se začne postupně procházet spojový seznam slovníku slov a porovnává se hledaný řetězec se jménem slova, dokud se nenarazí na konec. Pro jednoduchost předpokládejme, že Forth má slovník jen jeden. Pokud se slovo kompiluje, pak se do programu zapíše příslušný code pointer (early binding).
Teď si představ, že budeš chtít Forth upravit tak, abys měl možnost mít libovolný počet slovníků a v každém z nich žádný, jeden nebo více odkazů na další slovníky. Jakmile se nenajde slovo v příslušném slovníku, deleguje se hledání slova na rodičovský slovník. Pokud chceš mít možnost odkazy na rodičovské slovníky dynamicky měnit, pak ti nezbyde nic jiného, než se rozloučit s early binding a použít pozdní vazbu (pomineme-li různé možnsti optimalizací). Když navíc takové slovníky uložíš do paměti s automatickou správou, získáš něco, co jako by z oka vypadlo objektovému modelu Selfu.
Když už objekty v Selfu fungují principiálně podobně jako Forthovské slovníky, pak se na Forth můžeš dívat jako na Self s jedním objektem. A obráceně. Dalo by se tedy možná začít s Forthem jako základem pro bootstrapping Selfu. V Selfu potřebuješ něco jako symboly nebo kanonické řetězce pro efektivní hledání slotu, abys nemusel porovnávat jména slotů jako řetězce, ale jen rychle porovnáním identity. Pak potřebuješ nějakou tabulku symbolů, ke které má přístup virtuální stroj, a nějakým způsobem ji spravovat. Nabízí se v tomto případě přímo použít slovník Forthu. Jméno Forthovského slova by obsahovalo text symbolu a code pointer by odkazova na rutinu, která by prováděla vyhledání slova a případnou delegaci na další slovníky. Přitom bys stále měl možnost používat běžná slova Forthu, která by ze Selfovského pohledu hrála něco jako roli primitiv.
Pokud by takto vytvořený rozšířený Forth skutečně fungoval, dal by se nad ním postavit jednoduchý parser, který by Forthovský kód posypal trochou syntaktického Selfovského cukru, ale měl bys systém, který je jasně bootstrapovatelný, docela rychlý, jednoduchý a mající stále možnost, kdykoliv je to nutné, používat Forthovskou základnu.
Neuvěřitelná tvárnost Forthu k takovým úvahám svádí. Ale pokud jde o mě, tak když jsem se s tím dostatečně vyřádil, začal jsem zase spíš couvat, omezovat i nadužívání DOES>, pole si definuji přes CREATE místo zavádění nějakých svých vlastních definujících slov, místo různých vlastních CASE použiju jednoduše tabulku xt-ček... Ten jazyk je prostě dokonalý tak, jak je, tak proč z něj dělat nějaký objektový nebo kdo ví jaký. Tu jeho flexibilitu je nejlepší využít jako nástroj k tvorbě konkrétního DSL a ne k vytvoření další abstraktní univerzální vrstvy. To je můj názor po mnoha letech programování ve Forthu (pro mikrořadiče).
Je to na dobré cestě: https://gigatron.io/?p=1198
Jenom se v tom bude asi trochu blbě psát kompilátor Céčka.
Nebyl by lepší Magic-1?
Já už TinyBasic pro Gigatron TTL zkoušel alespoň v emulátoru a fungovalo to hezky: https://github.com/PhilThomas/gigatron/pull/2
Ale psát kompilátor C jsem v tom nezkoušel ;-)
Možná by bylo lepší začít assemblerem, něco jako https://www.asm80.com/ :)