Nie jestem pewien, czy nazwa jest odpowiednia, lecz już przedstawiam o co chodzi:
Witam!
Otóż chciałbym do mojego języka dodać obsługę konstrukcji:
var<int[]> tablica = {1, 2, 3, 4};
I stanąłem na pewnym 'problemie'. Otóż opcode służący dodawaniu pojedynczego elementu do tablicy wygląda następująco:
arset (referencja do tablicy, ilość wymiarów, wartość)
Może być to nieco niejasne, lecz na przykładzie - jeżeli chcielibyśmy wartość trzeciego indeksu tablicy, która znajduje się w rejestrze er1
ustawić na "Hello World!"
, prezentowałoby się to tak:
push(3)
arset(er1, 1, "Hello World!")
No więc powyższy przykład to byłoby aż osiem (lub dziesięć, licząc przydzielenie tablicy pamięci) opcodów!
push(0)
arset(tablica, 1, 1)
push(1)
arset(tablica, 1, 2)
push(2)
arset(tablica, 1, 3)
push(3)
arset(tablica, 1, 4)
To podejście byłoby najprostsze to implementacji, lecz wydajnościowo właściwie najgorsze.
Zatem pomyślałem nad stworzeniem opcodu w rodzaju:
arinit (referencja do tablicy, numer wymiaru, wartość indeksu 0, wartość indeksu 1, wartość indeksu 2 itd.)
Wtedy prezentowałoby się to tak:
arinit(tablica, 1, 1, 2, 3, 4)
I to byłoby najwydajniejsze - z 8 opcodów zeszliśmy do jednego, lecz z kolei problem byłby, gdyby te wartości nie były stałymi:
var<int[]> tab = {a+1, b+2, c+3, d+4, e+5};
=> arinit(tablica, 1, ei1, ei2, ei3, ei4... ups, nie ma więcej rejestrów na trzymanie rvalue-ów!)
I tak źle, i tak niedobrze :/
Pytanie właściwe: w jaki najlepszy sposób można by - z poziomu VM-ki oraz kompilatora - zaimplementować ten ficzer? Nie chodzi mi koniecznie o podanie jakiegoś gotowego sposobu, tylko np.schemat, jak miałoby to wyglądać.
Póki co trzymam się jedynie tego pierwszego rozwiązania, lecz jest ono dosyć słabe...
W razie czego mogę ofc.podać więcej informacji or something, bo stoję w kropce ;c