Stránka 1 z 1

Vlastní interpret

Napsal: 23 kvě 2017 19:00
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:

Re: Vlastní interpret

Napsal: 23 kvě 2017 19:19
od CZechBoY
no a co znamena nacist data? to je moc obecny na to aby to fungovalo vzdy...

Re: Vlastní interpret

Napsal: 23 kvě 2017 19:24
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

Re: Vlastní interpret

Napsal: 23 kvě 2017 19:29
od CZechBoY
tak proste nacti radek a vyparsuj si ho sam...

Re: Vlastní interpret

Napsal: 23 kvě 2017 19:33
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.

Re: Vlastní interpret

Napsal: 23 kvě 2017 19:36
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)

Re: Vlastní interpret

Napsal: 23 kvě 2017 20:27
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...

Re: Vlastní interpret

Napsal: 25 kvě 2017 16:25
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.

Re: Vlastní interpret

Napsal: 25 kvě 2017 16:47
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...)

Re: Vlastní interpret

Napsal: 25 kvě 2017 17:04
od jsemzpet
Uniká mi smysl. Proč děláš vlastní "interpret", který navíc ani neumí skoky?

Re: Vlastní interpret

Napsal: 26 kvě 2017 13:01
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

Re: Vlastní interpret

Napsal: 26 kvě 2017 16:14
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.