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

someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: květen 17
Pohlaví: Muž
Stav:
Offline

Vlastní interpret

Příspěvekod someoneFromSomewhere » 23 kvě 2017 19:00

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!

Reklama
Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: Vlastní interpret

Příspěvekod CZechBoY » 23 kvě 2017 19:19

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: květen 17
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod someoneFromSomewhere » 23 kvě 2017 19:24

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: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: Vlastní interpret

Příspěvekod CZechBoY » 23 kvě 2017 19:29

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: květen 17
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod someoneFromSomewhere » 23 kvě 2017 19:33

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: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: Vlastní interpret

Příspěvekod CZechBoY » 23 kvě 2017 19:36

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: 7356
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod faraon » 23 kvě 2017 20:27

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: květen 17
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod someoneFromSomewhere » 25 kvě 2017 16:25

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: 7356
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod faraon » 25 kvě 2017 16:47

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: březen 17
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod jsemzpet » 25 kvě 2017 17:04

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

someoneFromSomewhere
nováček
Příspěvky: 20
Registrován: květen 17
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod someoneFromSomewhere » 26 kvě 2017 13:01

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: 7356
Registrován: prosinec 10
Pohlaví: Muž
Stav:
Offline

Re: Vlastní interpret

Příspěvekod faraon » 26 kvě 2017 16:14

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)


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

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 7 hostů