Adjust abc-interpreter to new array representations

Explanation from Camil:

Oorspronkelijk waren arrays als volgt geïmplementeerd:

[ARRAY | (ptr)]
           `----> [_ARRAY_ | size | desc | values]

ARRAY is een node die je kan vergelijken met:

:: ARRAY = ARRAY !_ARRAY_

Deze node heeft één argument van type _ARRAY_ en is voor het runtime systeem niet bijzonder. _ARRAY_ is een speciale node, omdat de grootte van de node niet afhangt van de ariteit van de descriptor (de constructor). Zie https://top-software.gitlab.io/clean-lang/rts/introduction/#node-layout. `desc` kan 0 zijn voor {} en {!} (boxed arrays waarbij de elementen pointers zijn), of een descriptor voor unboxed arrays, bijvoorbeeld INT voor {#Int}, of een record descriptor voor {#R}. Het runtime systeem heeft die informatie nodig om deze nodes goed te behandelen bij garbage collection. Bijvoorbeeld, als je een unboxed array van :: R = {x :: !Int, y :: !Int} hebt met n elementen, dan weet je dat je 2*n woorden als `values` hebt (n keer `x` en n keer `y`). En GraphCopy moet hier op eenzelfde manier rekening mee houden bij het kopiëren van arrays.

Er was altijd al een speciale representatie voor strings:

[ARRAY | (ptr)]
           `----> [_STRING_ | size | values]

De `desc` hier zou CHAR zijn, maar omdat dit geval vaak voorkomt is _STRING_ als shorthand handig. Dit is nu uitgebreid naar _ARRAY_INT(32)_, _ARRAY_REAL(32)_, _ARRAY_BOOL_, en _ARRAY_R_ voor unboxed record arrays.

In de ABC interpreter zit natuurlijk een garbage collector, en ook code die lijkt op de functionaliteit van GraphCopy maar werkt voor kopiëren tussen native Clean en C interpreter, native Clean en Wasm interpreter, en Wasm interpreter en JavaScript. Om dit te laten werken moet je dus eerst de representatie van arrays in de interpreter aanpassen (dus de implementatie van instructies als `create_array`) en de garbage collector aanpassen. Dan zouden de tests in test/interpreter moeten werken. Daarna kun je de GraphCopy functionaliteit gaan aanpassen.

Concreet:

1. Representatie van arrays aanpassen:

1a. Native interpreter:
   - interpret.c: naast __ARRAY__ en __STRING__ gevallen __ARRAY_INT__ etc. toevoegen (dit is wat voor native Clean bovenaan _system.abc staat; de definitie van de builtin descriptors)
   - interpret.h: die descriptors exporteren
   - bytecode.c, print_label: gevallen toevoegen voor nieuwe descriptors
   - debug_curses.c, debugger_show_node_as_tree_: idem
   - parse.c: je hoeft niets met DESCS_RELATIVE_TO_ARRAY te doen; dit is voor systemen als MACHO_64 en 32-bit Linux waar we altijd position-independent executables hebben, waardoor descriptors ge-offset moeten worden tegen een bekende waarde; hiervoor wordt _ARRAY_ als de eerste descriptor gebruikt. Er is wel een aanroep van `preseed_symbol_matcher` en een check op de naam `"__ARRAY__"` die gekopieerd moeten worden voor de nieuwe descriptors.
   - strip.c, export_label: de nieuwe descriptors moeten net als __ARRAY__ en __STRING__ altijd geëxporteerd worden
   - debug_find_nodes.c, evaluate_grey_nodes: hier checkt de if-clause voor __ARRAY__s van INT, REAL, en BOOL; dit worden dus checks voor __ARRAY_INT__ (etc.) een niveau hoger
   - gc.c, 2x: soortgelijke conditionals voor de `desc` van __ARRAY__

   - tools/interpretergen.icl: de interpreter heeft aparte versies voor `create_array` afhankelijk van de descriptor (bv. `create_elementINT`). In de implementatie van die speciale gevallen zou je dus niet `ARRAY__ptr` maar een nieuwe `ARRAY_INT__ptr` moeten gebruiken, en hoef je niet meer de descriptor (`INT_ptr`) op `Hp @ 2` te zetten (vergelijk `create_arrayCHAR`). Alle voorkomens van ARRAY__ptr moeten hiervoor gecontroleerd worden.

1b. Wasm interpreter:
   - src/bcprelink.c: voeg de descriptors in prelinker_preamble toe (onderaan deze array, omdat er hardcoded verwijzingen naar bestaan
   - tools/interpretergen-wasm/target.icl: voeg ARRAY_INT__ptr etc. toe, de waardes verwijzen naar de index in bcprelink.c
   - src-js/abc-interpreter-util.wat, gc & update-ref: soortgelijke structuren als in gc.c, maar hier zijn de descriptors constante integers in plaats van namen. Dus bijvoorbeeld 42 (op regel 1087) is de _STRING_ descriptor, nl. 5*8+2: 5 is de index in bcprelink.c; 8 is het aantal bytes in een woord; 2 geeft aan dat het een head normal form is. Dus als _ARRAY_INT_ op index 697 komt te staan krijg je 697*8+2, etc.

2. GraphCopy functionaliteit:

2a. Voor native Clean <> C interpreter (niet in iTasks gebruikt):
   - copy_host_to_interpreter.c & copy_interpreter_to_host.c: soortgelijke conditional structuren als je zag in de garbage collector. Zoek op _ARRAY_, en kijk naar het geval voor _STRING_ om te vergelijken. (Wederom kun je IF_DESCS_RELATIVE_TO_ARRAY negeren.)

2b. Voor native Clean <> Wasm interpreter:
   - ABC.Interpreter, serialize_for_prelinked_interpretation, predef_or_lookup_symbol: gevallen toevoegen voor de nieuwe descriptors (je kunt gewoon doornummeren; het gaat erom dat deze descriptors een negatieve waarde krijgen om ze te kunnen onderscheiden van niet-builtin descriptors)
   - ABC.Interpreter, serialize_for_prelinked_interpretation, replace_desc_numbers_by_descs: hier zit weer zo'n conditional structuur die moet worden geherstructureerd om _ARRAY_INT_ etc. hoger te vangen
   - ABC.Interpreter, deserialize_from_prelinked_interpreter, replace_descs: idem
   - ABC.Interpreter, deserialize_from_prelinked_interpreter, find_predef_desc: dit correspondeert aan predef_or_lookup_symbol; voeg gevallen toe voor nieuwe descriptoren
   - ABC.Interpreter, fixup_32_bit_graph, zowel new_size als copy: weer een conditional structuur die moet worden hergestructureerd
   - ABC.Interpreter, fixup_64_bit_graph: idem
   - ABC.Interpreter, get_descriptor_n_non_pointers_and_not_array_native: nieuwe gevallen toevoegen
   - ABC.Interpreter, get_descriptor_n_non_pointers_and_not_array_interpreter: nieuwe gevallen toevoegen; waardes corresponderen aan predef_or_lookup_symbol
   - src-js/abc-interpreter-util.wat, copy_from_string & copy_to_string & remove_forwarding_pointers_to_graph: de waarde -6 voor _ARRAY_ hier verwijst naar predef_or_lookup_symbol uit ABC.Interpreter; hier moet de conditional structuur weer worden aangepast

2c. Voor Wasm interpreter <> JavaScript:
   - Er is geen gToJS instantie voor arrays, dus geen aanpassingen voor Clean -> JavaScript
   - JavaScript arrays worden op boxed arrays gemapt in Clean, dus geen aanpassingen voor JavaScript -> Clean

Overigens ondersteunt de interpreter nog geen {32#Int} en {32#Real}, dus die zul je niet tegenkomen en hoeven niet te worden toegevoegd.
Edited by Camil Staps