Odkaz na gw-basic.com je poškozený.
Jen bych doplnil, že minimálně Sinclair Basic dodnes překonává prakticky všechny současné jazyky a IDE v tom, že při dosažení breakpointu je možné nejen prohlížet a měnit hodnoty hodnoty proměnných a vykonávat téměř libovolné příkazy, ale také upravit laděný program - včetně řádku, kde byl breakpoint vyvolán! A pak vesele pokračovat v přerušeném běhu programu.
Do jisté míry to umí některé implementace Common Lispu - a to velmi neelegantně a jen jako hack. U počítače ZX80 byla tato funkcionalita omezena tím, že neměl možnost použít více příkazů na řádek, ale vše ostatní dokázal i s 4kB ROM, ve které půl kB zabral font.
Víte o nějakém dalším jazyce, který to umí?
Hlavne se to neda srovnavat.
Se Z80 neni v podstate kompatibilni zadny "moderni" programovaci jazyk.
A moderni IDE nepobezi ani na systemu s 1000x vice pameti. Stale to bude malo.
A zadny moderni jazyk nezvladne pro Z80 ani cross compiling. Je pekne ze novy jazyk umi nejake vymozenosti, ale pokud nezvladne ani "Hello Word" tak je z hlediska 8 bitu uplne k nicemu...
Takze zbyva nejake projekty fanousku, jako z88dk, ale ty jsou 10x horsi nez co napise clovek v assembleru...
Se Z80 si rozumi jedine Forth, ten by Sinclair Basic porazil.
Jen tak nejak Forth nikoho nezajima... nebo se ho boji.
Kdyz se podivas na oznameni noveho Forthu, ktery umi i zpetne optimalizace kodu:
F8 Forth cross-compiler, featuring Succubus, native Z80 code writer
F8 is FAST cross-compiler for Forth language. instead of using an interpreter, as most Forth systems do, F8 generates native machine code, and inlines a lot of primitives on its way. my usual Erathostenes benchmark is ~8 times faster than with Abersoft Forth Recompiled (which is DTC, and already faster than the original Abersoft Forth).
to give you some numbers: Abersoft Recompiled takes about 9 seconds (slighly less) to finish the benchmark, and F8 is able to do it in ~800 msecs.
of course, for real programs the results will not be such impressive, but i still expect x2-x5 speedup for most Forth code.
yet everything has its price: the code generated by F8 is bigger than the usual Forth threaded code. and you won't have an interactive interpreter to play with. but F8 is able to trace your program, and include only words it used. i.e. you tell F8 what the "main" word is, and F8 includes only the code which was really used, throwing away everything else. it also throws away all word headers. so most of the time, F8 will be able to produce both smaller and faster programs.
i wrote F8 because i am planning to use it for writing my own software, so it's not Yet Another Toy Project. also, F8 comes with a freebe: native x86 Forth compiler for GNU/Linux (because this is the language F8 written in).
(ok, i must confess that it was started as R&D project for Succubus/Z80, and it is still highly experimental. but it works, and works even better than i expected.)
both compilers featuring Succubus — optimising native code writer. for x86, Succubus is able to generate machine code comparable with SPF4, and she prolly even able to beat some commercial Forth compilers. most of the time,
x86 code generated by Succubus is ~2 times slower than "gcc -O2". and she is able to do that in milliseconds! rebuilding the whole x86 system takes ~60 msecs, and this is more than 500 KB of Forth code!
when Succubus writing code for Z80, she is lightning fast too. even for huge Forth programs you will prolly not be able to notice the compiling itself. your Speccy emulator might start slower than Succubus finishing her job! ;-)
so you'll be able to instantly test your Forth code, almost like if you have an interactive interpreter!
https://spectrumcomputing.co.uk/forums/viewtopic.php?t=11373
tak uvidis nulovy ohlas.
Jak mas reagovat kdyz nekdo dokaze napsat vlastni programovaci jazyk, kompiler, ide a operacni system a jeste to dokaze konkurovat obrim projektum jako gcc?
To bude urcite silene a nebo na tohle nemam... ta kralici nora je prilis hluboka.
Já ale myslel moderní programovací jazyky, moderní IDE na moderním HW, které by dokázaly:
- zastavit na breakpointu
- ukázat stav proměnných a dovolit jejich změnu
- vykonávat další příkazy či kód (s vedlejšími efekty)
- změnit zdrojový kód breakpointem pozastavené funkce/metody/slova na řádku, kde byl breakpoint vyvolán
- pokračovat ve změněném programu
Otázka zní, jestli tohle jinde skutečně chceme/potřebujeme. A v čem je to lepší, než modularizovaný kód testovaný třeba v něčem jako Jupyter. Tyhle srandy zkoušené na interpretovaném jazyce, který má v proměnných jenom pár primitivních typů, podle mě dávají málo smyslu u jazyků, které umožňují vytvářet složité struktury s cyklickými závislostmi atd.
Mohu mluvit jen za sebe, ale vzhledem k tomu, že na denní bázi využívám všechny uvedené body krom možnosti modifikovat i řádek s breakpointem (což moje IDE neumí, umí jen restartovat celou metodu) a jedná se o jazyk se složitými strukturami a cyklickými závislostmi, tak mohu jednoznačně říct: chci a potřebuji.
Podle všeho Lazarus IDE založený na Free Pascalu by to měl umět.
Viz https://wiki.freepascal.org/Debugger_Status
Jinak IDE je k dispozici na https://www.lazarus-ide.org/
Já to nepoužívám, ale jsem si celkem jist, že třeba PlatformIO (Plugin do VSCode) tohle umí. A jsem si docela jist, že to není nijaká rarita - stačí se podívat, jak pro dané IDE použít třeba gdb pro nativní vývoj, pro STM-32 jsem to použil před pár (jednotkami) let. Moderní IDE je třeba i pro FPGA a tam to jde také (viděl jsem v IDE pro čínský GoWin, ale opět nepoužívám).
Ono by to chtělo něco jako Action! pro Atari. Action! je strukturovaný jazyk s procedurami, ale datové typy a asi i jazykové struktury jsou ohnuté tak aby překlad na 6502 byl bezproblémový a výsledný kód rychlý. Na 16 bitových procesorech už takový jazyk neměl smysl, protože podporovaly indexování na zásobníku a implementace Céčka už nebyla tak přes ruku jako na klasických 8 bitových CPU (teda snad s výjimkou 6809, ten umí taky index zásobníku).
Byl. Pamatuji si jak jsem přepisoval program tuším, že z časopisu VTM, na výpočet faktoriálu. Původní verze pro AtariBasic byla příšerně pomalá v TurboBasicu pomalá (i s vypnutím zobrazování) a chtěl jsem z mašiny dostat co nejvíce ať ukáže co umí. (Argument do svaté války, že Atari je přece lepší než nějaký Commodore nebo ZX !! :D)Volba padla na Action! protože v assembleru jsem zvládl jen jednoduché hrátky s DLI a krátké rutiny. V ACTION! bylo nutné vytvořit vlastní procedury na práci s čísly s plovoucí čárkou.
Ze zvědavosti, co myslíte tím "do určité míry", "neelegantně" a "jako hack"? Přijde mi, že sly (třeba se sbcl) to má docela příjemně, a to pro všechny signalizované conditions, nejen pro breaky.
The function FOO has a BREAK.
CL-USER 76 > (defun foo (a)
(+ (break) (sin a)))
FOO
CL-USER 77 > (foo 10)
Break.
1 (continue) Return from break.
2 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
We are in the break lets get a quick backtrace and move to the right stack frame:
CL-USER 78 : 1 > :bq INVOKE-DEBUGGER <- BREAK <- FOO <- EVAL <- CAPI::CAPI-TOP-LEVEL-FUNCTION <- CAPI::INTERACTIVE-PANE-TOP-LOOP <- MP::PROCESS-SG-FUNCTION CL-USER 79 : 1 > :n Call to INVOKE-DEBUGGER CL-USER 80 : 1 > :n Call to BREAK CL-USER 81 : 1 > :n Interpreted call to FOO
What is the current source?
CL-USER 82 : 1 > :lambda
(LAMBDA (A) (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 8220104A8B>)) (DECLARE (LAMBDA-NAME FOO)) (+ (BREAK) (SIN A)))
Let's change the code:
CL-USER 83 : 1 > (setf (third (fifth *)) '(* a 4)) (* A 4)
Let's see the new code.
CL-USER 84 : 1 > :lambda
(LAMBDA (A) (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 8220104A8B>)) (DECLARE (LAMBDA-NAME FOO)) (+ (BREAK) (* A 4)))
Move to the BREAK stack frame and return 2 from there:
CL-USER 85 : 1 > :p Call to BREAK CL-USER 86 : 1 > :ret 2 42
As you can see, we have changed the running source code, without the need to restart anything.
Ve sly mi to přijde jednodušší. Po (foo 10) se objeví takovýhle buffer [1]:
break
[Condition of type SIMPLE-CONDITION]
Restarts:
0: [CONTINUE] Return from BREAK.
1: [RETRY] Retry SLY mREPL evaluation request.
2: [*ABORT] Return to SLY's top level.
3: [ABORT] abort thread (#<THREAD tid=2490 "sly-channel-1-mrepl-remote-1" RUNNING {10000FEF83}>)
Backtrace:
0: (FOO 10)
Locals:
A = 10
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FOO 10) #<NULL-LEXENV>)
2: (EVAL (FOO 10))
3: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
--more--
s tím že řádek backtrace vybírám "normálně" pohybem kurzoru, "v" zobrazí zdrojový kód funkce včetně skoku na řádek s breakem, "r" frame restartuje (po případné redefinici funkce), "e" umožní evaluovat výraz v lexikálním kontextu frame, "R" se z rámce vrátí s hodnotou na kterou se systém doptá, atp. Plus vedle REPL a okna se zdrojáky, kde mohu překompilovávat a dělat další změny.
Místo psaní explicitních breaků v kódu se dá nastavit dočasný "sticker" který nezapleveluje kód.
[1] termín emacsu pro něco jako okno
Myslím, že popsané chování BASICu je "normální" pro interpretovaný BASIC té doby.
A když jsme u toho, (bacha, zase to vypadá na flame ;-)), Atari BASIC má příkaz TRAP, kterým můžete poslat běh na dané číslo řádku a pak něco s chybou udělat, třeba ji ignorovat. :-D
Jinak lze samozřejmě i v Atari BASICu dělat to co píšete.
Na Atari šla ale ještě obskurnější věc - programově (z BASICu) šel modifikovat kód BASICu za běhu. FUngovalo to tak, že na obrazovku jste vypsal třeba 10 GOTO 10, na další řádek POKE někam, něco, pak kurzor umístil nad text s GOTO, zapsal POKE někam, něco a ten text z obrazovky se zapsal do programu, jakoby byl zadán ručně. Dalo se to použít třeba pro generování řádků s DATA na základě dat z paměti.
samomodifikujuce programy fungovali takto:
od druheho riadku obrazovky sa vypisali riadky programu vo formate
cislo_riadku1 prikaz1
cislo_riadku2 prikaz2
cislo_riadku3 prikaz3
pod to sa vlozil prikaz CONT
kurzor sa umiestnil na prvy riadok
vykonal sa prikaz POKE 842,13
a za nim prikaz STOP
ten POKE prepol editor do stavu "mam stale stlacenu klavesu RETURN"
nasledne editor odoslal predtym pripravene prikazy aj s cislamim riadkov, tieto boli tokenizovane a vlozene do programu
nasledne prisiel prikad CONT ktory obnovil vykonavanie programu na nasledujucom riadku po prikaze STOP
tam bol POKE 842,12 co vyplo auto-enter mod editoru.
Viac into napr. na https://www.atariarchives.org/creativeatari/SelfModifying_Programs.php
Jasně, tohle a mnohem víc umí Smalltalk. Ten je v podstatě naprogramovaný tak, že v běžícím image obsahuje IDE, stdlib, parser jazyka, debugger atp. a to se už několik dekád upravuje za běhu. Pak se vždy jen image z RAM uloží do souboru a příště zase při spuštění načte :-) Aplikace je ve stejném image jako IDE, a deploy se dělá tak, že se IDE odstraní (nebo alespoň schová)