Zkouška 31.1.2018

Základní kurs objektově orientovaného programování v C++. Třídy a objekty, zapouzdření, metody, plymorfismus. Abstraktní datové typy, přetěžování. Kontejnery, iterátory, algoritmy. Šablony, generické programování, kompilační polymorfismus. Výjimky. Bezpečné a přenositelné programování, vazby na OS.
Speedding
Matfyz(ák|ačka) level I
Příspěvky: 35
Registrován: 10. 1. 2017 19:32
Typ studia: Informatika Mgr.
Kontaktovat uživatele:

Zkouška 31.1.2018

Příspěvek od Speedding »

Dneska zadával Robert Husák a měli jsme za úkol napsat CLR pro .NET. Dobře no, tak teda ne - měli jsme napsat zjednodušený interpret nějakého mezikódu (CIL kód / bytecode).
Vstup
Argumenty programu
Při spuštění je programu předán seznam souborů, které má jeden po druhém spustit, např.: program kod1.txt kod2.txt kod3.txt

Vstupní soubor
Každý vstupní soubor musí být vyhodnocen odděleně od ostatních - tedy případný rozpracovaný stav po předchozím souboru je vždy potřeba před vyhodnocením dalšího uklidit. Syntaxe vstupního souboru je následující:

Každý řádek obsahuje nanejvýše jednu instrukci, ta se může skládat z jednoho a více slov oddělených mezerami nebo tabulátory (i více než jedním takovým znakem za sebou).
Pokud se kdekoliv na řádce objeví znak #, značí to začátek komentáře. Tento znak a všechny znaky po něm následující až do konce řádku musejí být ignorovány.
Před každou instrukcí se může nacházet nanejvýše jedno návěští. Jedná se o slovo končící na znak :
Instrukce
Veškeré výpočty v interpreteru probíhají na 32-bitových celých číslech se znaménkem. Interpreter má 10 lokálních proměnných indexovaných od 0, které musejí být před interpretací programu inicializované na hodnotu 0. Kromě toho používá vyhodnocovací zásobník, jehož velikost není omezená. Jednotlivé instrukce s tímto zásobníkem pracují různým způsobem:

ldconst C
Uloží na vrchol zásobníku celočíselnou konstantu C.
stloc I
Odebere z vrcholu zásobníku aktuální hodnotu a uloží ji do proměnné I.
ldloc I
Uloží na vrchol zásobníku aktuální hodnotu proměnné I.
pop
Odebere hodnotu z vrcholu zásobníku.
out
Vypíše aktuální hodnotu na vrcholu zásobníku a mezeru.
add
Odebere dvě hodnoty z vrcholu zásobníku a uloží na něj jejich součet.
mul
Odebere dvě hodnoty z vrcholu zásobníku a uloží na něj jejich součin.
sub
Odebere dvě hodnoty z vrcholu zásobníku a uloží na něj jejich rozdíl (číslo první odebrané ze zásobníku je pravý operand).
div
Odebere dvě hodnoty z vrcholu zásobníku a uloží na něj jejich podíl (číslo první odebrané ze zásobníku je pravý operand).
lt
Odebere dvě hodnoty z vrcholu zásobníku a uloží na něj číslo 1, pokud je druhé odebrané číslo menší než první odebrané, jinak 0.
gt
Odebere dvě hodnoty z vrcholu zásobníku a uloží na něj číslo 1, pokud je druhé odebrané číslo větší než první odebrané, jinak 0.
goto L
Nepodmíněný skok na instrukci s návěštím L.
brt L
Skok na instrukci s návěštím L, pokud je na vrcholu zásobníku číslo různé od 0.
brf L
Skok na instrukci s návěštím L, pokud je na vrcholu zásobníku 0.

Výstup
Pro každý vstupní soubor vypíše program jeho název, následně provede jeho vyhodnocení, které v sobě může zahrnovat i výstupy příkazu out.
Pokud dojde k nějaké chybě v programu, vypíše řádek syntax error (např. neexistující příkaz), resp. runtime error (např. při chybějících argumentech na zásobníku).
Například pro soubor fact5.txt
# $0 = 1
ldconst 1
stloc 0

# $1 = 1
ldconst 1
stloc 1

goto LOOPCOND

LOOPSTART: pop # result of $0 < 7

# $1 *= $0
ldloc 1
ldloc 0
mul
stloc 1

# $0 += 1
ldloc 0
ldconst 1
add
stloc 0

# echo $1
ldloc 1
out
pop

# $0 < 7
LOOPCOND: ldloc 0
ldconst 7
lt
brt LOOPSTART
měl být výstup
fact5.txt:
1 2 6 24 120 720
Měli jsme na to 4 hodiny, já odevzdával jako druhý po dvou hodinách, takže ani nevím, jaká byla úspěšnost.
Přikládám svoje zdrojáky, kde jedinou malinkou výtku měl zkoušející k funkci get_tokens_(const string&), že to jde udělat lépe přes stringstream (nějak jsem si to během zkoušky neuvědomil), ale ve finále mě pochválil, že jsem si naprogramoval něco low level :D Každopádně bylo to za 60 bodů a oproti minulé zkoušce byla tato úloha (dle mého) do značné míry jednodušší.
source.cpp
(899 bajtů) Staženo 358 x
interpreter.hpp
(6.05 KiB) Staženo 345 x
interpreter.cpp
(5.22 KiB) Staženo 357 x
Odpovědět

Zpět na „NPRG041 Programování v C++“