Vlastní interpret

Místo pro dotazy a rady ohledně programovacích jazyků (C++, C#, PHP, ASP, Javascript, VBS..) a tvorby webových stránek

Moderátor: Mods_senior

Odpovědět
someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: 12 kvě 2017 15:17

Vlastní interpret

Příspěvek od someoneFromSomewhere »

Název moc neřekne, ale jedná se o toto: Vytvořit v příkazové řádce 'interpret' vlastního jazyka, který bude pracovat pomocí dvou struktur (stack pro data, queue pro instrukce). Není potřeba používat ochranu vstupu atp., chyby se nečekají.

Vymyslel jsem to tak, že člověk zadá postupně po řádcích jakýsi svůj program a ten se bude rozdělovat do stacku a queue podle typu zápisu.
Vstup by pak mohl vypadat nějak takto:

Kód: Vybrat vše

$123 - proměnná 1
$456 - proměnná 2
$789 - proměnná 3
254   - instrukce (od teď čísla ukládat zpět na vrch stacku)
$3   - proměnná 4 (počet proměnných k součtu)
11   - instrukce (součet čísel)
10   - instrukce (výpis vršku stacku)
255   - instrukce (spustit zadaný program & vyprázdnit frontu s instrukcema)
255   - instrukce (zavřít konzoli -> protože ve frontě pro instrukce nic není)


V podstatě, všechna čísla která mají před sebou $, jsou data, která se vkládají do zásobníku, zbytek jsou příkazy.

Program mám zhruba hotov, jenom mi chybí nějak dokutit ten vstup.
Pseudo-kód:

Kód: Vybrat vše

dokud (1):
   nacist vstup
   pokud (vstup jsou data)
      pridat do stacku
   jinak pokud (vstup jsou instrukce)
      pokud (instrukce je 255)
         pokud (fronta neni prazdna)
            spustit program
         jinak
            ukoncit
      jinak
         pridat do stacku instrukci


Interpret běží tak jak by měl, akorát mám problém s tím vstupem.
Udělal jsem pomocí scanf() ať se načítá znak a číslo, ale problém je že nechci vždycky načítat obojí.
Jakože používat jeden znak $ pro data a třeba & pro instrukce (v případě že to není možné se s tím smířím).

Zadání se mi doma válí už nějakou tu chvilku, tak sem si řekl že na to konečně vrhnu :shifty:
std::endl není nový řádek!
Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: 20 srp 2008 14:02
Bydliště: Brno
Kontaktovat uživatele:

Re: Vlastní interpret

Příspěvek od CZechBoY »

no a co znamena nacist data? to je moc obecny na to aby to fungovalo vzdy...
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: 12 kvě 2017 15:17

Re: Vlastní interpret

Příspěvek od someoneFromSomewhere »

To je částečně ten problém, já potřebuju totiž načítat 'výrazy' ve dvou stylech. Buď ten výraz bude jen číslo (instrukce) a nebo to bude znak $ následován číslem (nějaké data).

Protože teď musím vždycky dodat nějaký jiný znak (než $) i před instrukci aby to fungovalo, takže třeba takhle:

Kód: Vybrat vše

$123456789 // data
&111111111 // instrukce


A já bych to potřeboval takto:

Kód: Vybrat vše

$123456789 // data
111111111   // instrukce


Momentálně to vypadá nějako toto to načítání:

Kód: Vybrat vše

   
   char c = 'E';
   int command = 0;
   while (scanf(" %c %d", &c, &command) >= 1) {
      if (c == '$') data.emplace(command);
      else if (c == '&') {
         if (command == 0xFF) {
            if (inst.empty()) break;
            else run(data, inst);
         } else inst.emplace(command);
      }
   }
   


Taky by bylo skvělé kdyby to umělo u instrukcí i HEX zápis (stačí i jen hex)

Kód: Vybrat vše

$123456789 // data
F4AB           // instrukce
std::endl není nový řádek!
Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: 20 srp 2008 14:02
Bydliště: Brno
Kontaktovat uživatele:

Re: Vlastní interpret

Příspěvek od CZechBoY »

tak proste nacti radek a vyparsuj si ho sam...
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: 12 kvě 2017 15:17

Re: Vlastní interpret

Příspěvek od someoneFromSomewhere »

To je taky možnost no, tomu sem se chtěl ale vyhnout.

Bych musel do stringu načíst, kouknout na první znak a potom do istringstreamu a pak to jen vytahnout po objektech ...

Je nějaká lepší možnost ? Bych se podíval, ale nemůžu.
std::endl není nový řádek!
Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: 20 srp 2008 14:02
Bydliště: Brno
Kontaktovat uživatele:

Re: Vlastní interpret

Příspěvek od CZechBoY »

no zkus nacist prvni znak a kdyz to je $ tak nacti cislo a kdyz pismeno tak nacti pismena (jeste musis na zacatek toho vysledku nacpat ten prvni znak rucne)
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7404
Registrován: 23 pro 2010 09:23

Re: Vlastní interpret

Příspěvek od faraon »

Znáš Forth? Pokud ne, doporučuji důkladně prostudovat ;-)

Stejně důkladně prostuduj možnosti formátovacího řetězce funkce scanf(), protože v učebnicích se uvádí jen nepatrná podmnožina toho co dokáže! A pohraj si s tímhle:

Kód: Vybrat vše

#include <stdio.h>



int main(void)
    {
    int pocet,cislo=0;
    char znak='\0';

    printf("Zadej kód: ");
    pocet=scanf("%1[$]%d",&znak,&cislo);
    if (!pocet) pocet=scanf("%d",&cislo);
    printf("%d\t%c\t%d\n",pocet,znak,cislo);

    return 0;
    }


Možná tě z těch výpisů napadne že i ta kontrola chybného vstupu by tam šla velmi snadno implementovat, a jak.

Mimochodem, scanf() je Céčková funkce, a není úplně zdravé míchat C a C++, jsou to velmi odlišné jazyky...
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: 12 kvě 2017 15:17

Re: Vlastní interpret

Příspěvek od someoneFromSomewhere »

Ach ano, Forth znám.

Na ten scanf sem se díval, ale tohle mě nenapadlo. :D Musel jsem udělat pár úprav, ale už jsem všechno rozchodil tak jak by mělo. Pro teď to nechám tím scanf-em, potom to předělám na 'modernější' způsob, ale to není tak důležíté.

Kód: Vybrat vše

$2 $1 $9 0x04 0xFF $10 0x11 0xA0 0xFF

^ tohle je momentálně výpočet 2 ^ 10 :D

Teď už jenom přijít na to, jak vypočítat faktoriál - asi nějakou spešl instrukci :D
Mám momentálně k dispozici kopírování X dat, sčítání X dat a násobení X dat, a snažím se přijít na to, jak vyrobit cykly.

Napadlo mě něco jako

Kód: Vybrat vše

$A $B 0xCC

kde A je počet instrukci které se mají opakovat, B počet cyklů a 0xCC je samotná instrukce.
A nakopírovat ty instrukce do fronty.

edit č.40054565456:
Málem bych zapoměl: samotné instrukce nesmí obsahovat cykly (ani for, ani while), takže se musí instrukce klonovat do fronty kolikrát je potřeba.
std::endl není nový řádek!
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7404
Registrován: 23 pro 2010 09:23

Re: Vlastní interpret

Příspěvek od faraon »

Však scanf() je úžasná věc, a umí neuvěřitelné věci. Jenom na načítání řetězců se fakt nehodí, to tam je kvůli kompatibilitě s printf(). Ovšem existuje i moc zajímavá funkce sscanf() ;-)

Faktoriál můžeš počítat buď cyklem, nebo rekurzí. Cyklus je rychlejší.

Jenže pokud máš rekurzi, máš zároveň i cyklus, a když zapracuješ na tail-call optimalizaci, může to být cyklus nekonečný!

Tím pádem můžeš takovou rekurzi zrychlit a nezasírat zbytečně zásobník, potom se při výpočtu faktoriálu vyrovná tomu cyklu.

Forth znáš, takže se ještě mrkni na LISP, protože tímhle se mu malinko blížíš. (A jestli na tomhle projektu budeš opravdu tvrdě makat, tak časem zjistíš že už v roce 1958 byli o milion světelných let dál než jsi se dostal ty...)
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
jsemzpet
Level 1
Level 1
Příspěvky: 74
Registrován: 27 bře 2017 15:16

Re: Vlastní interpret

Příspěvek od jsemzpet »

Uniká mi smysl. Proč děláš vlastní "interpret", který navíc ani neumí skoky?
someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: 12 kvě 2017 15:17

Re: Vlastní interpret

Příspěvek od someoneFromSomewhere »

jsemzpet píše:Uniká mi smysl. Proč děláš vlastní "interpret", který navíc ani neumí skoky?


A neuniká ti jenom to ...

Hodí se: PŘEČÍST SI TO VLÁKNO
std::endl není nový řádek!
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7404
Registrován: 23 pro 2010 09:23

Re: Vlastní interpret

Příspěvek od faraon »

jsemzpet: Třeba proto aby se něco naučil? Ty jsi něco takového nikdy nezkusil? ;-)

Například já jsem si navrhl a už pár roků po chvilkách a po kouscích konstruuji vlastní počítač, ve stylu přelomu padesátých a šedesátých let. Zatím jsou to jen stovky listů papíru pokreslených logickými schématy, ale dalo mi to možná víc než čtvrt století programování! Začal jsem instrukční sadou, potom zapojením jednotlivých částí procesoru, k tomu jsem vymýšlel assembler a vhodné programovací techniky...

Martin Malý píše:Kdysi jsem překládal článek pro programátory. Bylo to o návrhu programovacích jazyků a autor psal: „Zkuste si to, navrhněte si vlastní jazyk, k němu překladač, knihovny, ekosystém… Skoro určitě s ním nikdy neprorazíte, ale bude to pro vás skvělá škola.“


A co máš s těmi skoky? Ty vůbec nejsou potřeba, dobře navržený jazyk správně zvolené koncepce se bez nich úplně krásně obejde.
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
Odpovědět

Zpět na „Programování a tvorba webu“