Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Zdeno Sekerák 01. 11. 2019, 21:47:38
-
Dostal se mi do rukou jeden interpreter. Konkrétne tento http://www.hansamanuals.com. Je v nej už neco naprogramováno a já řeším úpravy. Pro debug jsou akorát alert okna nebo zápis do *.log souboru. No je to náročné. Tak vymýšlím jestli bych neudelal jednoduchý debuger. Neco jako vem řádek, vykonej, a ukaž všechny vnitřní promenné.
Rešil nekdo z vás neco podobné jinde?
-
Neřešil. Ale je to zajímavé téma.
Co třeba umožnit registrovat pozorovatele ve stylu AOP. Tedy můžeš si zaregistrovat jednu nebo více funkcí na místo určené selektorem. Něco jako breakpoint. Když kód přijde na to místo, tak té funkci předá aktuální stav (nutné deepclone). To by nešlo?
Samozřejmě když by si chtěl sledovat všechno, tedy plnohodnotný debuger, tak by se dal selektor na hvězdičku.
-
Teda nevím, ale za dob, kdy jsem programoval v PHP jsem si vystačil s příkazem print_r a die. Bez debuggeru.
Zápis do log souboru je požehnaný debugovací nástroj.
-
Dostal se mi do rukou jeden interpreter. Konkrétne tento http://www.hansamanuals.com. Je v nej už neco naprogramováno a já řeším úpravy. Pro debug jsou akorát alert okna nebo zápis do *.log souboru. No je to náročné. Tak vymýšlím jestli bych neudelal jednoduchý debuger. Neco jako vem řádek, vykonej, a ukaž všechny vnitřní promenné.
Rešil nekdo z vás neco podobné jinde?
Eh... cože? :-)
Obecná odpověď = chcete vyrobit source-level debugger pro nějaký interpretovaný jazyk. To by znamenalo jednu ze dvou možností:
A) nemáte zdrojáky od toho interpretru. V tom případě byste musel reimplementovat cca celý ten interpreter, pokud se má jednat o source-level debugging. A potažmo pak neladíte korektnost programu v proprietárním interpretru, ale ve Vašem reimplementovaném prostředí...
B) máte zdrojáky od toho interpretru. V tom případě se zanořte do vnitřností, a dopište do runtime prostředí nějaké ladící okno, které Vám bude ukazovat např. celý namespace (nebo těch několik dílčích namespaces = globální, lokální, co já vím), bude sledovat "aktuální pozici v programu" (něco jako instruction pointer) a umožní Vám se ve vnitřnostech toho interpretru hrabat. Pokud je to interpretované přímo řádku po řádce, je to ta jednodušší varianta. Nebo ještě pokud se to zkompiluje do "mezipodoby" = do nějakého stromu binárních objektů, jako to dělá Perl 5 - to by taky ještě šlo. Pokud se to zkompiluje do nějakého bytekódu ala Java (pro register-based virtual machine = ztratí se původní struktura programu), tak byste v tom bytekódu musel mít "ladící informace" (odkazy na řádky zdrojáku).
Konkrétně pokud se týče HansaWorld... to je celý nějaký ERP balík!? K tomu nebudou zdrojáky... Podle mého je to celé halucinace. Ledaže byste se dopátral, že má ten runtime nebo IDE nějaké dokumentované ladící API, proti kterému si můžete něco svého doprogramovat...
To je zajímavé. Býval bych si u Vás tipnul, že si tuhle odpověď dáte dohromady sám. Pořád koukám, kde jsem špatně pochopil otázku...
-
Neřešil. Ale je to zajímavé téma.
Co třeba umožnit registrovat pozorovatele ve stylu AOP. Tedy můžeš si zaregistrovat jednu nebo více funkcí na místo určené selektorem. Něco jako breakpoint. Když kód přijde na to místo, tak té funkci předá aktuální stav (nutné deepclone). To by nešlo?
Samozřejmě když by si chtěl sledovat všechno, tedy plnohodnotný debuger, tak by se dal selektor na hvězdičku.
jestli je to interpret, breakpoint jde realizovat eval smyckou
-
Neřešil. Ale je to zajímavé téma.
Co třeba umožnit registrovat pozorovatele ve stylu AOP. Tedy můžeš si zaregistrovat jednu nebo více funkcí na místo určené selektorem. Něco jako breakpoint. Když kód přijde na to místo, tak té funkci předá aktuální stav (nutné deepclone). To by nešlo?
Samozřejmě když by si chtěl sledovat všechno, tedy plnohodnotný debuger, tak by se dal selektor na hvězdičku.
jestli je to interpret, breakpoint jde realizovat eval smyckou
Přesně tak, mohlo by jít místo načtení kódu ze souboru jej načítat interaktivně z nějaké konzole. Tak to lze leckdy odladit interaktivněji, než pouhým logem do souboru.
-
Místo debugu zkus raději testy jednotek. Aspoň to nebudeš muset ladit ručně.
-
OT: Psal už někdo z vás vlastní interpret?
Například pro Basic, Pascal, Lua nebo něco podobného?
Docela rád bych si jeden takový napsal (taková specialitka) a pár rad by se hodilo.
-
Neřešil. Ale je to zajímavé téma.
Co třeba umožnit registrovat pozorovatele ve stylu AOP. Tedy můžeš si zaregistrovat jednu nebo více funkcí na místo určené selektorem. Něco jako breakpoint. Když kód přijde na to místo, tak té funkci předá aktuální stav (nutné deepclone). To by nešlo?
Samozřejmě když by si chtěl sledovat všechno, tedy plnohodnotný debuger, tak by se dal selektor na hvězdičku.
jestli je to interpret, breakpoint jde realizovat eval smyckou
Přesně tak, mohlo by jít místo načtení kódu ze souboru jej načítat interaktivně z nějaké konzole. Tak to lze leckdy odladit interaktivněji, než pouhým logem do souboru.
já to myslel naopak, vložit eval smyčku do bodu breakpointu.
v pythonu neco takoveho
while True:
s = input()
if s == 'c':
break
print(eval(s))
ale je k nicemu, lepsi pouzit pdb
-
OT: Psal už někdo z vás vlastní interpret?
Například pro Basic, Pascal, Lua nebo něco podobného?
Docela rád bych si jeden takový napsal (taková specialitka) a pár rad by se hodilo.
in-house vyvýjené interprety jsou zlo, jak ukazuje tato diskuze.
-
OT: Psal už někdo z vás vlastní interpret?
Například pro Basic, Pascal, Lua nebo něco podobného?
Docela rád bych si jeden takový napsal (taková specialitka) a pár rad by se hodilo.
in-house vyvýjené interprety jsou zlo, jak ukazuje tato diskuze.
To se týká jen univerzálních interpretů. Pokud jsou však doménově specifické, mohou být velmi praktické a užitečné.
-
To se týká jen univerzálních interpretů. Pokud jsou však doménově specifické, mohou být velmi praktické a užitečné.
nemohou, nikdy se nedostanete na úroveň zavedených interpretů, co se týče dokumentace, odladěnosti, podpory v nástrojích třetích stran
-
OT: Psal už někdo z vás vlastní interpret?
Ano, psal. Ono to není nic složitého, implementovat parser a interpretaci je primitivní, složitější může být sofistikovaná sémantická analýza apod., ale ta se dá dělat iterativně nebo dopsat později.
-
To se týká jen univerzálních interpretů. Pokud jsou však doménově specifické, mohou být velmi praktické a užitečné.
nemohou, nikdy se nedostanete na úroveň zavedených interpretů, co se týče dokumentace, odladěnosti, podpory v nástrojích třetích stran
Pokud zavedené interprety nesplňují mé doménové požadavky, tak mi nezbývá nic jiného, než si napsat vlastní. Není to tak složité, jak to vypadá. Pár desítek či stovek řádek se dá napsat třeba i za hodinu.
-
Neřešil. Ale je to zajímavé téma. Co třeba umožnit registrovat pozorovatele ve stylu AOP. Tedy můžeš si zaregistrovat jednu nebo více funkcí na místo určené selektorem. Něco jako breakpoint. Když kód přijde na to místo, tak té funkci předá aktuální stav (nutné deepclone). To by nešlo?
Samozřejmě když by si chtěl sledovat všechno, tedy plnohodnotný debuger, tak by se dal selektor na hvězdičku.
jestli je to interpret, breakpoint jde realizovat eval smyckou
Přesně tak, mohlo by jít místo načtení kódu ze souboru jej načítat interaktivně z nějaké konzole. Tak to lze leckdy odladit interaktivněji, než pouhým logem do souboru.
já to myslel naopak, vložit eval smyčku do bodu breakpointu. V pythonu neco takoveho
while True:
s = input()
if s == 'c':
break
print(eval(s))
Nebo tak. Pokud se někam zapisují skripty, které pak aplikace vyhodnocuje, může ten skript sám provádět eval. Ale je to jen rychlý hack který nemusí vždy vyhovovat...
-
Pánové děkuji za uvedení mého kategorického odsudku na pravou míru. Pokud ten interpreter zná eval(), a nebrání tomu nějaká další omezení, příležitost k partyzánské činnosti existuje :-)
-
než si napsat vlastní. Není to tak složité, jak to vypadá. Pár desítek či stovek řádek se dá napsat třeba i za hodinu.
Ano, psal. Ono to není nic složitého, implementovat parser a interpretaci je primitivní
Nejprve: Parser není problém, data si stejně musím umět nejprve rozparsovat ručně, parser neřešme.
Velmi zajímavé! Jak byste na to šli?
Vytvořením virtuálního procesoru?
Pokud zkusím připravit virtuální procesor, znamená to, se postarat i o správu paměti.
Příklad, kdybych si chtěl napsat vlastní interpret "BASICU", resp. ten jazyk by se dal nazvat dialektem BASICu, ale chci používat velmi specifické vlastnosti, které nemají odpovídající paradigma (funkcionální, procedurální...atd).
Tak třeba primitivní: Print "Blah Blah",$F
To ovšem vyžaduje mít někde uloženou proměnnou F$, čili potřebuji spravovat paměť.
Opět primitivní: FOR $X=1 TO 100
V zásadě si potřebuji někde držet proměnnou X, resp. informace o ní, protože potřebuji typovou bezpečnost (což není u BASICU běžné, ale...)
To opět není problém....
Hm....
Jinými slovy,díky typové bezpečnosti, tj. každá proměnná musí být předem definovaná, se nemusím za chodu starat o přidělování paměti.
Tedy v zásadě je zbytečné emulovat funkce procesoru.
Spíš jít cestou, kdy emulovaná instrukce vyvolá odpovídající instrukci nativního jazyka.
Fakticky se tak musím starat jen o přidělení adres proměnných a posílání těchto proměnných do odpovídajících funkcí ::)
Nebo se na to dívám špatně?
-
než si napsat vlastní. Není to tak složité, jak to vypadá. Pár desítek či stovek řádek se dá napsat třeba i za hodinu.
Ano, psal. Ono to není nic složitého, implementovat parser a interpretaci je primitivní
Nejprve: Parser není problém, data si stejně musím umět nejprve rozparsovat ručně, parser neřešme.
Velmi zajímavé! Jak byste na to šli?
Vytvořením virtuálního procesoru?
Pokud zkusím připravit virtuální procesor, znamená to, se postarat i o správu paměti.
Příklad, kdybych si chtěl napsat vlastní interpret "BASICU", resp. ten jazyk by se dal nazvat dialektem BASICu, ale chci používat velmi specifické vlastnosti, které nemají odpovídající paradigma (funkcionální, procedurální...atd).
Tak třeba primitivní: Print "Blah Blah",$F
To ovšem vyžaduje mít někde uloženou proměnnou F$, čili potřebuji spravovat paměť.
Opět primitivní: FOR $X=1 TO 100
V zásadě si potřebuji někde držet proměnnou X, resp. informace o ní, protože potřebuji typovou bezpečnost (což není u BASICU běžné, ale...)
To opět není problém....
Hm....
Jinými slovy,díky typové bezpečnosti, tj. každá proměnná musí být předem definovaná, se nemusím za chodu starat o přidělování paměti.
Tedy v zásadě je zbytečné emulovat funkce procesoru.
Spíš jít cestou, kdy emulovaná instrukce vyvolá odpovídající instrukci nativního jazyka.
Fakticky se tak musím starat jen o přidělení adres proměnných a posílání těchto proměnných do odpovídajících funkcí ::)
Nebo se na to dívám špatně?
Jakmile parser (třeba LR) vytvoří AST, stačí jej interpretovat procházením. Proměnné se drží v kontextu, v nejjednodušším případě to je asociativní pole, akorát pozor na shadowing.
-
Velmi zajímavé! Jak byste na to šli?
Upřímně, já jsem na to šel cestou transpileru. Vezmu zdroják, zpracuju do tokenů, a pak ho vybuldím do cílové platformy. Osobně se domnívám, že v době Lui prostě nemá smysl dělat vlastní interpret. Jako bonus pak mám možnost buildit do javascriptu pro potřeby webu. Získaný čas a energii soustředím na blbosti kolem (typy, knihovny, ...).
Pokud opravdu to musí být čistokrevný interpret, co třeba toto (https://www.zdrojak.cz/clanky/piseme-interpret-v-javascriptu/)?
Proměnné nejsou problém. To si prostě na to vytvoříš objekt řešící scope, uchovávající lokální proměnné (v případě neexistence dohledáváš v nadřazeném, etc). Mnohem větší pruda speciální formy IF, FOR, WHILE...
K seznámením s problématikou extrémně doporučuji přečíst toto (https://phoenix.inf.upol.cz/esf/ucebni/pp1a.pdf). Dozvíš se i co nechceš. Ale popisujou tam všechny podrazy (interpretu).
Ale stejně bych šel spíš do transpileru :-)
-
Velmi zajímavé! Jak byste na to šli?
Vytvořením virtuálního procesoru?
Pokud zkusím připravit virtuální procesor, znamená to, se postarat i o správu paměti.
Příklad, kdybych si chtěl napsat vlastní interpret "BASICU", resp. ten jazyk by se dal nazvat dialektem BASICu, ale chci používat velmi specifické vlastnosti, které nemají odpovídající paradigma (funkcionální, procedurální...atd).
Především se zbav potřeby univerzálního jazyka. Na to je dostatek interpretů, ze kterých si vybereš, dopíšeš pár knihoven nebo si uděláš framework a jedeš.
Pak jsou ještě doménově specifické jazyky, které jsou mnohem jednodušší a takový interpret splácáš za chvíli. Přečteš řádek a podle prvního slova vyhodnotíš, co s tím zbytkem uděláš a jak změníš stav. Můžeš to udělat jako Moorův nebo Mealyho automat. Cykly neřešíš, o správu paměti se postará hostitelský jazyk, ve kterém si uděláš asociativní pole (slovník).
Taková blbinka se dá slepit třeba v AWK na pěti řádcích, ale můžeš si vybrat takový jazyk, který ti pro daný účel vyhoví nejlépe.
-
Proměnné nejsou problém. To si prostě na to vytvoříš objekt řešící scope, uchovávající lokální proměnné (v případě neexistence dohledáváš v nadřazeném, etc). Mnohem větší pruda speciální formy IF, FOR, WHILE...
Přesně. Rozhodování, skoky, cykly, podprogramy, funkce. Pokud bych měl něco takového dělat v míře větší než malé, použiji hotový jazyk, ke kterému jen napíši nějaký doplněk. Jinak riskuji, že mi to bude trvat zbytečně dlouho a stejně ten výsledek nebude odpovídat vynaloženému úsilí.
-
a) Jednoduchy parser mam zvladnuty. Kvoli inemu problemu a to ze nekontroluje syntax external funkcii. Tak jsem si udelal parser ktery to odkontroluje v celem projektu.
b) Moje myslenka je ze udalam jednoduchy injektor. Tedy za kazdy prikaz dam volani me funkce ktera bude cist nejaky TXT soubor ve kterem bude mit prikazy. Jako vycti obsah, promennych, pokracuj na dalsi breakpoint, udelej jeden krok. V Editoru by jsem zobrazoval kod neinjektovany.