Kezdőoldal » Számítástechnika » Programozás » A bytecode interpreterek hogy...

A bytecode interpreterek hogy kezelik a típusokat?

Figyelt kérdés

Egy interpretert írok egy egyszerű szkriptnyelvhez. A szkriptnyelvben dinamikus típusok vannak (lennének). Tehát nem kell típust specifikálnom. Példa:

a = 3.0 // Tudja hogy ez float lesz

a = true // Most már boolean


Még egy példa ami fontos a problémám szempontjából:

function foo(x, y, z)

{

return x + y + z

}

foo(1, 2, 3) // 6-ot ad vissza

foo("a", "b", "c") // "abc"-t ad vissza


Ami megvan, az a lexikális analízis, az elemzés és van egy szintaxisfám. Most csinálhatnék egy TreeWalker-t és lenne egy kész interpreterem, de ez nagyon lassú. Szeretném bytecode-ra fordítani. Hogy stack vagy regiszter alapú, az szerintem a probléma szempontjából lényegtelen (amúgy regiszter alapú lenne).

Szóval lennének alacsonyabb szintű parancsok. Minden különböző művelethez egy. Külön 2 float, 2 int, 2 string, stb.. összeadásához/kivonásához/stb... . Például ez a kód:

2 + 3

Ezt a kódot generálná:

ILOAD reg1, 2 ; első regiszterbe betölti a 2-t (intként)

ILOAD reg2, 3 ; 3-mat

IADD reg3, reg1, reg2 ; összead 2 integert amelyek a reg1 és 2-ben vannak és berakja reg3-ba.

Példa 2:

1 + 4.0

Ezt generálná:

ILOAD reg1, 1

ITOF reg2, reg1 ; Float-tá alakítja a reg1-ben lévő intet és reg2-be teszi

FLOAD reg3, 4.0

FADD reg3, reg1, reg2


Szóval minden műveletnek megvan a maga típusa, illetve konverziók is vannak. Természetesen ez még mind a fordításnál történik. Na most egy ilyet:

function foo(x, y)

{

return x + y

}


Hogyan fordítsak le? A dinamikus típusok miatt nem tudom kikövetkeztetni hogy milyen paraméterekkel hívják meg. Kell-e castelni, stb...

Hívhatják így:

foo(1, 2)

és így:

foo("a", "b")

sőt így is:

foo("a", 2)

stb...


Lehet hogy nagyon egyszerű a válasz, de nem jövök rá hogy ezt fordítási időben hogyan oldjam meg. Sajnos egyetemen olyan órám nem volt, ahol compilerekkel foglalkoztunk volna (csak 17 vagyok..).

Köszönök minden segítséget!


2015. júl. 22. 21:26
 1/6 anonim ***** válasza:

Fordíthatsz több körben, mármint előbb áttolhatsz egy elemzés, ami típusozással látja el az ilyen részeket pl.


Vagy fordítás közben magát a hívott helyen kibontod a függvényt az adott típusokra.

2015. júl. 22. 21:50
Hasznos számodra ez a válasz?
 2/6 A kérdező kommentje:

"Vagy fordítás közben magát a hívott helyen kibontod a függvényt az adott típusokra."


Még olvasgatok pár helyen, hogy hol hogyan oldották meg, de ez tűnik eddig a legkézenfekvőbbnek. Köszönöm!

2015. júl. 22. 22:06
 3/6 anonim ***** válasza:
76%

A Python-ban egy objektumba burkolják az összeset. Így működnek rajta a műveletek. Én nem szeretem a ducktyping-ot, de az így működik.


Ha típus kikövetkeztetést használsz, akkor viszont nem lehetséges a példád, ez:


a = 3.0 // Tudja hogy ez float lesz

a = true // Most már boolean

2015. júl. 23. 19:14
Hasznos számodra ez a válasz?
 4/6 A kérdező kommentje:

"Ha típus kikövetkeztetést használsz, akkor viszont nem lehetséges a példád, ez:


a = 3.0 // Tudja hogy ez float lesz

a = true // Most már boolean"


Dehogynem. Ez éppen lehetséges. Van egy symbol table-m, amiben jegyzem hogy aktuálisan milyen típusú a változó és az alapján fordítom hozzá a bytecode-ot.

2015. júl. 23. 22:54
 5/6 anonim ***** válasza:
100%

@21:50

A típus dinamikusan változhat. Akkor mit csinálsz ha fordítási időbe nem ismert a típusa?


@19:14

Nem egy objektumba hanem egy-egy objektumba. Implementáció szempontjából egy-egy osztályba.


Nem árt tisztába lenni az objektum és osztály fogalmával. Az objektumorientáltsággal.


Ezeket úgy szokás megoldani, hogy objektumorientált paradigma szerint tekintjünk a problémára.

x + y műveletet dinamikus tipusoknál (is), hogy x és y egy-egy objektumként tekintjük és a + operátort hajtjuk végre x és y-ra. Az x küld egy "+" üzenetet y-nak. Dehát minden objektumhoz tartozik operátor eljárás hogy hogy kell értelmezni rajta a + operátort. Kézenfekvő az operátor eljárásokat a típusokra tárolni és nem minden objektumhoz külön-külön tárolni. A "színfalak" mögött a következő történik (egy lehetséges megoldás): Fontos követelmény hogy minden objektum tudja önmagáról, hogy milyen típusú. Létrehozáskor pl egy struktúrába tároljuk a tárolt értéket és a típust. Aztán egy 3 kulcsból álló adatszerkezetből kiolvassuk a megfelelő operátor eljárást mely egy függvénypointert tartalmaz, melyet meghívunk x és y paraméterrel, a függvény létrehoz az x és y objektumból egy harmadik objektumot. 3 kulcs azért kell mert kell az hogy melyik tipusú objetkumhoz tartozó melyik másik típusú objektumhoz tartozó melyik függvénypointert keressük. Pl ha x egy integer akkor egy integerhez tartozó függvénypointert (operátor eljárást) keresünk, y az pl egy string akkor fuggvenytabla[integer,string,'+'] értékét keressük. Ennek az adatszerkezetnek gyorsnak kell lennie, azaz konstans elérési idejűnek. Továbbá lehet optimalizálni fordítási időben statikus kódelemzéssel, automatikus típuskikövetkeztetést tenni (meg egyéb optimalizációkat), ahol fordítási időben biztosra ismert a típus azt futási időt leszámítva vele ekvivalens optimalizáltabb kódra cserélni, de ilyen optimalizáció bőven ráér meg elég bonyolult is.(Persze tudnám még bonyolítani.)

2015. júl. 23. 23:01
Hasznos számodra ez a válasz?
 6/6 A kérdező kommentje:

Végül is hasonlóképpen oldottam meg mint anno a Lua-ban tették. Az adatokat így tárolom:

typedef struct

{

union

{

int ival;

float fval;

...

} RawVal;

uint8_t type;

} Value;


Az operátoraim elvontak (nem adott típusokra építkeznek), és hogy kicsit gyorsítsak, a string összefűzéseknek külön operátort adtam. Így a runtime type check és típuskonverzió nem vesz el túl sok időt.

2015. júl. 24. 13:48

Kapcsolódó kérdések:




Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!