fusee-framework 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -3
- package/app/benchmark/vite.config.js +23 -0
- package/auto-imports.d.ts +4 -0
- package/framework/auto-import-preset.js +3 -1
- package/framework/core/async-context.js +27 -0
- package/framework/core/compiler/ast.js +167 -0
- package/framework/core/compiler/errors-list.js +47 -0
- package/framework/core/compiler/errors.js +107 -0
- package/framework/core/compiler/generator.js +363 -0
- package/framework/core/compiler/lexer.js +347 -0
- package/framework/core/compiler/main-compiler.js +115 -0
- package/framework/core/compiler/parser.js +414 -0
- package/framework/core/compiler/plugins/actions-plugin.js +263 -0
- package/framework/core/compiler/plugins/compiler-plugin.d.ts +5 -0
- package/framework/core/compiler/plugins/compiler-plugin.js +45 -0
- package/framework/core/compiler/plugins/file-router-plugin.js +301 -0
- package/framework/core/compiler/plugins/router-plugin.js +196 -0
- package/framework/core/compiler/transformer.js +398 -0
- package/framework/core/component.js +34 -10
- package/framework/core/evaluator.js +1 -1
- package/framework/core/h.js +430 -0
- package/framework/core/hydration.js +83 -0
- package/framework/core/signal.js +17 -15
- package/framework/server/actions.js +173 -0
- package/framework/server/actions.server.js +88 -0
- package/framework/server/index.js +18 -0
- package/framework/types/actions.d.ts +50 -0
- package/framework/types/actions.server.d.ts +36 -0
- package/framework/types/compiler/ast.d.ts +166 -0
- package/framework/types/compiler/errors-codes.d.ts +23 -0
- package/framework/types/compiler/errors.d.ts +43 -0
- package/framework/types/compiler/generator.d.ts +8 -0
- package/framework/types/compiler/h.d.ts +46 -0
- package/framework/types/compiler/lexer.d.ts +27 -0
- package/framework/types/compiler/main-compiler.d.ts +60 -0
- package/framework/types/compiler/parser.d.ts +4 -0
- package/framework/types/compiler/plugins/actions.d.ts +30 -0
- package/framework/types/compiler/plugins/compiler-plugin.d.ts +5 -0
- package/framework/types/compiler/plugins/file-router-plugins.d.ts +32 -0
- package/framework/types/compiler/plugins/router-plugin.d.ts +24 -0
- package/framework/types/compiler/transformer.d.ts +28 -0
- package/framework/types/hydration.d.ts +30 -0
- package/framework/types/index.d.ts +6 -0
- package/framework/types/server.d.ts +11 -0
- package/framework/types/signal.d.ts +2 -7
- package/ghid_go_fusee_integrat_go1_26.txt +276 -0
- package/ghid_rust_fusee_rust_1_95_0.txt +1118 -0
- package/package.json +44 -36
- package/vite.config.js +65 -53
|
@@ -0,0 +1,1118 @@
|
|
|
1
|
+
GHID COMPLET RUST 1.95.0 PENTRU FUSEE
|
|
2
|
+
De la 0 la un compilator JS/Rust/WASM pentru un framework cu fine-grained reactivity
|
|
3
|
+
|
|
4
|
+
Autor: ChatLLM
|
|
5
|
+
Limba: Romana
|
|
6
|
+
Format: ghid practic, orientat spre arhitectura, bune practici si evitarea greselilor tipice
|
|
7
|
+
|
|
8
|
+
============================================================
|
|
9
|
+
0. SCOPUL GHIDULUI
|
|
10
|
+
============================================================
|
|
11
|
+
|
|
12
|
+
Acest document este gandit pentru cazul tau concret:
|
|
13
|
+
- esti student la CS;
|
|
14
|
+
- construiesti Fusee, un framework JS inspirat in principal din Solid si Vue;
|
|
15
|
+
- ai in vedere fine-grained reactivity;
|
|
16
|
+
- vrei mai intai un compilator/procesor AST scris in JavaScript;
|
|
17
|
+
- apoi vrei o versiune scrisa in Rust care compileaza la WASM si ruleaza in browser;
|
|
18
|
+
- vrei un ghid bun si realist, nu un text generic despre Rust.
|
|
19
|
+
|
|
20
|
+
Obiectivul acestui ghid este dublu:
|
|
21
|
+
1) sa te invete Rust de la fundamente pana la un nivel suficient pentru a construi infrastructura serioasa de compilator;
|
|
22
|
+
2) sa functioneze si ca “document de orientare” pentru un editor AI, astfel incat acesta sa nu faca greseli lamentabile cand scrie Rust pentru proiectul tau.
|
|
23
|
+
|
|
24
|
+
Acesta nu este doar un curs de sintaxa. Este o harta de drum pentru a trece de la “invata Rust” la “proiectez componente de compilator si WASM fara sa imi sabotez arhitectura”.
|
|
25
|
+
|
|
26
|
+
============================================================
|
|
27
|
+
1. DE CE RUST PENTRU FUSEE
|
|
28
|
+
============================================================
|
|
29
|
+
|
|
30
|
+
Rust este o alegere foarte buna pentru partea a doua a proiectului tau din cateva motive:
|
|
31
|
+
|
|
32
|
+
1. Performanta predictibila
|
|
33
|
+
- fara GC de runtime;
|
|
34
|
+
- fara pauze de colectare;
|
|
35
|
+
- foarte bun pentru parsare, analiza semantica, transformari si codegen.
|
|
36
|
+
|
|
37
|
+
2. Siguranta memoriei
|
|
38
|
+
- extrem de importanta pentru compilatoare si infrastructura care proceseaza multe structuri de date;
|
|
39
|
+
- reduce clase intregi de bug-uri fata de C/C++.
|
|
40
|
+
|
|
41
|
+
3. Model excelent pentru toolchain-uri
|
|
42
|
+
- CLI-uri rapide;
|
|
43
|
+
- biblioteci usor de compus;
|
|
44
|
+
- integrare buna cu WASM;
|
|
45
|
+
- ecosistem matur pentru parsare, erori, testare si profiling.
|
|
46
|
+
|
|
47
|
+
4. Potrivire buna cu un compilator modern de frontend
|
|
48
|
+
- poti scrie un parser nativ foarte rapid;
|
|
49
|
+
- poti compila partea “grea” la WASM si o poti rula in browser;
|
|
50
|
+
- poti separa clar frontend API-ul JS de motorul de compilare din Rust.
|
|
51
|
+
|
|
52
|
+
5. Se potriveste cu tipul de arhitectura vazut in industrie
|
|
53
|
+
Modelele care merita studiate conceptual sunt:
|
|
54
|
+
- Babel: flexibilitate mare, ecosistem de transformari, model AST-centric in JS;
|
|
55
|
+
- TypeScript compiler: pipeline clar parser -> binder -> checker -> emitter;
|
|
56
|
+
- SWC: viteza si separare clara intre parse/transform/codegen;
|
|
57
|
+
- Biome: infrastructura foarte disciplinata pentru parser, formatter, linter;
|
|
58
|
+
- Oxc: accent pe performanta si toolchain JS modern in Rust;
|
|
59
|
+
- Vue compiler: split clar intre template parse, transform si codegen;
|
|
60
|
+
- Solid compiler: transformari orientate pe semantica reactivitatii si granularitate fina.
|
|
61
|
+
|
|
62
|
+
Pentru Fusee, ideea buna nu este sa copiezi 1:1 un proiect, ci sa combini:
|
|
63
|
+
- ergonomia si pipeline-ul configurabil din Babel/Vue;
|
|
64
|
+
- disciplina de date si performanta din SWC/Biome/Oxc;
|
|
65
|
+
- gandirea orientata pe reactivitate fina din Solid.
|
|
66
|
+
|
|
67
|
+
============================================================
|
|
68
|
+
2. CE TREBUIE SA STIE UN EDITOR AI DESPRE RUST, CA SA NU TE INCURCE
|
|
69
|
+
============================================================
|
|
70
|
+
|
|
71
|
+
Aceasta sectiune este foarte importanta. Daca dai acest document unui editor AI, el ar trebui sa respecte regulile de mai jos.
|
|
72
|
+
|
|
73
|
+
2.1. Reguli nenegociabile
|
|
74
|
+
|
|
75
|
+
1) Sa nu propuna unsafe fara motiv serios.
|
|
76
|
+
- Infrastructura de compilator se poate scrie foarte bine in safe Rust.
|
|
77
|
+
- unsafe este ultima optiune, nu prima.
|
|
78
|
+
|
|
79
|
+
2) Sa nu foloseasca clone() ca plasture universal.
|
|
80
|
+
- clone() peste tot ascunde defecte de design.
|
|
81
|
+
- Mai intai se cauta imprumuturi (&T), slice-uri, indici, interner-e sau ownership clar.
|
|
82
|
+
|
|
83
|
+
3) Sa nu foloseasca Rc<RefCell<T>> ca default.
|
|
84
|
+
- Este tentant pentru cine vine din JS, dar adesea strica designul.
|
|
85
|
+
- Pentru AST si pipeline de compilare, modele mai bune sunt:
|
|
86
|
+
- ownership pe arbore;
|
|
87
|
+
- arena allocation mai tarziu, daca chiar ajuta;
|
|
88
|
+
- ID-uri stabile in loc de grafuri cu ownership circular.
|
|
89
|
+
|
|
90
|
+
4) Sa prefere enum-uri si match in loc de ierarhii artificiale de clase.
|
|
91
|
+
- Rust exceleaza cu algebraic data types.
|
|
92
|
+
- AST-ul si diagnosticele trebuie modelate natural cu enum + struct.
|
|
93
|
+
|
|
94
|
+
5) Sa trateze Result si Option explicit.
|
|
95
|
+
- Fara unwrap() in cod de productie pe input de utilizator.
|
|
96
|
+
- In parser si compiler, erorile fac parte din produs.
|
|
97
|
+
|
|
98
|
+
6) Sa nu supra-generalizeze prea devreme.
|
|
99
|
+
- Nu introduce trait-uri, generic overload si macro-uri doar ca “sa fie elegant”.
|
|
100
|
+
- Un compilator bun incepe adesea concret si devine generic doar unde exista nevoie reala.
|
|
101
|
+
|
|
102
|
+
7) Sa nu amestece tipurile pentru faze diferite.
|
|
103
|
+
- Token != AST node != HIR node != diagnostic != generated output.
|
|
104
|
+
- Fiecare faza trebuie sa aiba structuri clare.
|
|
105
|
+
|
|
106
|
+
8) Sa nu inventeze API-uri de crate-uri.
|
|
107
|
+
- Daca foloseste o librarie externa, trebuie sa verifice API-ul real.
|
|
108
|
+
- Daca nu e sigur, mai bine propune pseudocod sau cere validare.
|
|
109
|
+
|
|
110
|
+
9) Sa nu introduca async daca nu exista nevoie reala.
|
|
111
|
+
- Parsing, transformare, codegen si WASM bindings nu cer automat async.
|
|
112
|
+
- Async inutil complica tipurile si debugging-ul.
|
|
113
|
+
|
|
114
|
+
10) Sa favorizeze designul orientat pe date.
|
|
115
|
+
- Pentru compilatoare, structurile compacte, spans, ID-uri si tabele sunt adesea mai bune decat obiecte “smart”.
|
|
116
|
+
|
|
117
|
+
2.2. Cum ar trebui sa gandeasca un editor AI cand scrie Rust pentru Fusee
|
|
118
|
+
|
|
119
|
+
Ordinea corecta de gandire este:
|
|
120
|
+
1) care e modelul de date?
|
|
121
|
+
2) care este ownership-ul?
|
|
122
|
+
3) care sunt input-urile si output-urile fazei?
|
|
123
|
+
4) cum se raporteaza erorile?
|
|
124
|
+
5) care sunt invariantiile?
|
|
125
|
+
6) unde devine utila optimizarea?
|
|
126
|
+
|
|
127
|
+
Ordinea gresita este:
|
|
128
|
+
1) hai sa facem tot generic;
|
|
129
|
+
2) hai sa folosim macros si lifetimes complicate;
|
|
130
|
+
3) hai sa bagam Rc<RefCell<...>>;
|
|
131
|
+
4) hai sa rezolvam borrow checker-ul cu clone();
|
|
132
|
+
5) hai sa optimizam inainte sa existe benchmark.
|
|
133
|
+
|
|
134
|
+
2.3. Prompt intern bun pentru AI
|
|
135
|
+
|
|
136
|
+
Cand il pui pe AI sa scrie Rust pentru Fusee, vrei sa il fortezi sa respecte idei de tipul:
|
|
137
|
+
- modeleaza datele intai;
|
|
138
|
+
- prefera enum + struct;
|
|
139
|
+
- evita clone inutile;
|
|
140
|
+
- evita unsafe;
|
|
141
|
+
- returneaza Result cu erori explicite;
|
|
142
|
+
- foloseste spans pentru noduri parse-uite;
|
|
143
|
+
- separa parsing de semantic analysis si codegen;
|
|
144
|
+
- nu presupune API-uri neverificate.
|
|
145
|
+
|
|
146
|
+
============================================================
|
|
147
|
+
3. ROADMAP RECOMANDAT PENTRU TINE
|
|
148
|
+
============================================================
|
|
149
|
+
|
|
150
|
+
Faza A. Invata Rust corect
|
|
151
|
+
- ownership;
|
|
152
|
+
- borrowing;
|
|
153
|
+
- lifetimes la nivel practic;
|
|
154
|
+
- enum, match, traits, iterators, modules, tests.
|
|
155
|
+
|
|
156
|
+
Faza B. Scrie unelte mici
|
|
157
|
+
- tokenizer simplu;
|
|
158
|
+
- parser pentru expresii;
|
|
159
|
+
- evaluator mic;
|
|
160
|
+
- CLI cu fisiere si erori.
|
|
161
|
+
|
|
162
|
+
Faza C. Scrie un parser/transformer in JavaScript
|
|
163
|
+
- defineste AST-ul Fusee;
|
|
164
|
+
- stabileste pipeline-ul;
|
|
165
|
+
- valideaza designul limbajului si al transformarii.
|
|
166
|
+
|
|
167
|
+
Faza D. Rescrie parserul si infrastructura critica in Rust
|
|
168
|
+
- lexer;
|
|
169
|
+
- parser;
|
|
170
|
+
- spans;
|
|
171
|
+
- diagnostics;
|
|
172
|
+
- AST/HIR;
|
|
173
|
+
- codegen minim.
|
|
174
|
+
|
|
175
|
+
Faza E. Compileaza la WASM
|
|
176
|
+
- expune un API mic si stabil catre JS;
|
|
177
|
+
- ruleaza parserul/compilatorul in browser;
|
|
178
|
+
- evita sa treci volume mari de date peste granita JS/WASM.
|
|
179
|
+
|
|
180
|
+
Faza F. Optimizeaza pe baza de benchmark
|
|
181
|
+
- parser throughput;
|
|
182
|
+
- memorie;
|
|
183
|
+
- code size WASM;
|
|
184
|
+
- latenta in browser.
|
|
185
|
+
|
|
186
|
+
============================================================
|
|
187
|
+
4. SETUP MODERN RUST 1.95.0
|
|
188
|
+
============================================================
|
|
189
|
+
|
|
190
|
+
Pe baza anuntului oficial Rust 1.95.0, versiunea a fost lansata pe 16 aprilie 2026.
|
|
191
|
+
|
|
192
|
+
Instalare si update:
|
|
193
|
+
- instaleaza prin rustup;
|
|
194
|
+
- update la stable cu: rustup update stable
|
|
195
|
+
|
|
196
|
+
Practic, pentru proiectul tau:
|
|
197
|
+
- foloseste stable, nu nightly, ca baza;
|
|
198
|
+
- daca experimentezi, izoleaza clar orice dependenta pe nightly;
|
|
199
|
+
- seteaza edition = "2024" in Cargo.toml pentru proiectele noi;
|
|
200
|
+
- defineste un MSRV clar doar daca vei publica librarii serioase pentru altii.
|
|
201
|
+
|
|
202
|
+
Un setup sanatos:
|
|
203
|
+
- rustup
|
|
204
|
+
- cargo
|
|
205
|
+
- rustfmt
|
|
206
|
+
- clippy
|
|
207
|
+
- target WASM cand ajungi acolo
|
|
208
|
+
- optional: cargo-nextest, criterion, wasm-pack, wasm-bindgen-cli daca ai nevoie de flux explicit
|
|
209
|
+
|
|
210
|
+
Comenzi utile:
|
|
211
|
+
- rustup update stable
|
|
212
|
+
- cargo new fusee-playground
|
|
213
|
+
- cargo test
|
|
214
|
+
- cargo fmt
|
|
215
|
+
- cargo clippy --all-targets --all-features -- -D warnings
|
|
216
|
+
- cargo doc --open
|
|
217
|
+
|
|
218
|
+
Politica recomandata:
|
|
219
|
+
- fmt obligatoriu;
|
|
220
|
+
- clippy obligatoriu in CI;
|
|
221
|
+
- testele sa ruleze la fiecare schimbare importanta;
|
|
222
|
+
- fara warnings tolerate la nesfarsit.
|
|
223
|
+
|
|
224
|
+
============================================================
|
|
225
|
+
5. FUNDAMENTELE RUST PE CARE TREBUIE SA LE STAPANESTI
|
|
226
|
+
============================================================
|
|
227
|
+
|
|
228
|
+
5.1. Ownership
|
|
229
|
+
|
|
230
|
+
Ideea centrala:
|
|
231
|
+
- fiecare valoare are un proprietar;
|
|
232
|
+
- cand proprietarul dispare din scope, valoarea este eliberata;
|
|
233
|
+
- mutarea ownership-ului este explicita prin semantica limbajului.
|
|
234
|
+
|
|
235
|
+
De ce conteaza pentru compilatoare:
|
|
236
|
+
- AST-uri, token streams, string-uri si buffer-e trebuie mutate sau imprumutate constient;
|
|
237
|
+
- daca nu stapanesti ownership, vei “lupta” cu borrow checker-ul in loc sa il folosesti.
|
|
238
|
+
|
|
239
|
+
Ce sa inveti practic:
|
|
240
|
+
- mutare vs copiere;
|
|
241
|
+
- tipuri Copy vs non-Copy;
|
|
242
|
+
- cand sa detii String si cand sa folosesti &str.
|
|
243
|
+
|
|
244
|
+
Regula practica:
|
|
245
|
+
- la granita API-ului, detine datele cand are sens;
|
|
246
|
+
- intern, imprumuta cat poti, dar nu exagera cu lifetimes complexe daca un ownership clar este mai simplu.
|
|
247
|
+
|
|
248
|
+
5.2. Borrowing
|
|
249
|
+
|
|
250
|
+
Borrowing inseamna acces temporar la o valoare fara transfer de ownership.
|
|
251
|
+
- &T = imprumut imutabil;
|
|
252
|
+
- &mut T = imprumut mutabil.
|
|
253
|
+
|
|
254
|
+
Regula de baza:
|
|
255
|
+
- poti avea multe imprumuturi imutabile sau unul mutabil, nu ambele simultan.
|
|
256
|
+
|
|
257
|
+
Pentru Fusee:
|
|
258
|
+
- parserul poate imprumuta sursa de intrare;
|
|
259
|
+
- diagnosticele pot referi spans, nu neaparat copii de substring-uri;
|
|
260
|
+
- transformatorii ar trebui proiectati sa evite aliasing mutabil complicat.
|
|
261
|
+
|
|
262
|
+
5.3. Lifetimes
|
|
263
|
+
|
|
264
|
+
Nu trebuie sa devii fanatic al lifetime-urilor de la inceput.
|
|
265
|
+
Trebuie doar sa intelegi:
|
|
266
|
+
- lifetime-ul descrie cat timp o referinta este valida;
|
|
267
|
+
- multe lifetime-uri sunt inferate;
|
|
268
|
+
- lifetime-urile explicite devin relevante cand returnezi referinte sau cand legi mai multe referinte intre ele.
|
|
269
|
+
|
|
270
|
+
Recomandare pentru incepator in compilatoare:
|
|
271
|
+
- nu construi AST-ul initial ca o padure de referinte &str peste tot;
|
|
272
|
+
- mai simplu este adesea:
|
|
273
|
+
- input-ul ramane un String sau Arc<str> la nivel de fisier;
|
|
274
|
+
- nodurile tin spans / offset-uri;
|
|
275
|
+
- extragerea textului original se face la nevoie.
|
|
276
|
+
|
|
277
|
+
Aceasta strategie reduce dramatic complexitatea lifetime-urilor.
|
|
278
|
+
|
|
279
|
+
5.4. Struct si enum
|
|
280
|
+
|
|
281
|
+
Acestea sunt fundamentul pentru orice compilator serios in Rust.
|
|
282
|
+
|
|
283
|
+
Exemplu mental:
|
|
284
|
+
- TokenKind = enum;
|
|
285
|
+
- Token = struct { kind, span };
|
|
286
|
+
- Expr = enum cu variante precum Identifier, Call, Binary, Literal;
|
|
287
|
+
- Module = struct cu lista de itemi.
|
|
288
|
+
|
|
289
|
+
De ce enum este atat de bun:
|
|
290
|
+
- modelare precisa a limbajului;
|
|
291
|
+
- exhaustivitate la match;
|
|
292
|
+
- mai putine bug-uri ascunse.
|
|
293
|
+
|
|
294
|
+
5.5. Pattern matching
|
|
295
|
+
|
|
296
|
+
match este una dintre cele mai importante unelte din Rust.
|
|
297
|
+
Pentru parsare si analiza:
|
|
298
|
+
- pe token kinds;
|
|
299
|
+
- pe node kinds;
|
|
300
|
+
- pe erori;
|
|
301
|
+
- pe stari de compilare.
|
|
302
|
+
|
|
303
|
+
Rust 1.95.0 aduce if-let guards in match, ceea ce este util pentru logica mai expresiva in ramurile de match. Este o imbunatatire reala, dar nu trebuie abuzata: lizibilitatea ramane prioritatea.
|
|
304
|
+
|
|
305
|
+
5.6. Option si Result
|
|
306
|
+
|
|
307
|
+
Option<T>
|
|
308
|
+
- exista sau nu exista o valoare.
|
|
309
|
+
|
|
310
|
+
Result<T, E>
|
|
311
|
+
- operatie reusita sau eroare.
|
|
312
|
+
|
|
313
|
+
Pentru compilatoare:
|
|
314
|
+
- parserul rar este “doar bool”; el trebuie sa produca fie noduri, fie erori sau recoveries;
|
|
315
|
+
- diagnostics-urile si error recovery sunt mult mai importante decat in multe alte tipuri de aplicatii.
|
|
316
|
+
|
|
317
|
+
Buna practica:
|
|
318
|
+
- foloseste tipuri de eroare dedicate;
|
|
319
|
+
- nu face panic! pe input invalid al utilizatorului;
|
|
320
|
+
- foloseste context clar in erori.
|
|
321
|
+
|
|
322
|
+
5.7. Traits
|
|
323
|
+
|
|
324
|
+
Trait-urile sunt asemanatoare interfetelor conceptual, dar mai puternice.
|
|
325
|
+
Le vei folosi pentru:
|
|
326
|
+
- visitors;
|
|
327
|
+
- pretty printers;
|
|
328
|
+
- abstrahii de codegen;
|
|
329
|
+
- conversii controlate;
|
|
330
|
+
- helper-e generice.
|
|
331
|
+
|
|
332
|
+
Avertisment:
|
|
333
|
+
- nu transforma totul in trait din prima saptamana;
|
|
334
|
+
- in compilatoare, structuri concrete + functii clare sunt adesea mai bune la inceput.
|
|
335
|
+
|
|
336
|
+
5.8. Iterators si colectii
|
|
337
|
+
|
|
338
|
+
Trebuie sa stii bine:
|
|
339
|
+
- Vec<T>
|
|
340
|
+
- String
|
|
341
|
+
- HashMap<K, V>
|
|
342
|
+
- BTreeMap<K, V>
|
|
343
|
+
- slices
|
|
344
|
+
- iter(), iter_mut(), into_iter()
|
|
345
|
+
|
|
346
|
+
Buna practica:
|
|
347
|
+
- foloseste Vec ca structura de baza implicita;
|
|
348
|
+
- optimizezi ulterior doar dupa benchmark;
|
|
349
|
+
- pentru tabele de simboluri, HashMap este suficient la inceput.
|
|
350
|
+
|
|
351
|
+
5.9. Module si crate-uri
|
|
352
|
+
|
|
353
|
+
Un proiect sanatos in Rust are separare buna in module.
|
|
354
|
+
Nu vrei un singur fisier cu 5000 linii.
|
|
355
|
+
|
|
356
|
+
Structura minima buna:
|
|
357
|
+
- lexer.rs
|
|
358
|
+
- parser.rs
|
|
359
|
+
- ast.rs
|
|
360
|
+
- span.rs
|
|
361
|
+
- diagnostics.rs
|
|
362
|
+
- lib.rs
|
|
363
|
+
- main.rs sau bindings wasm separat
|
|
364
|
+
|
|
365
|
+
============================================================
|
|
366
|
+
6. BUNE PRACTICI DE RUST CARE CONTEAZA INTR-UN COMPILATOR
|
|
367
|
+
============================================================
|
|
368
|
+
|
|
369
|
+
1) Favorizeaza tipuri mici si clare.
|
|
370
|
+
2) Tine spans peste tot unde input-ul provine din sursa.
|
|
371
|
+
3) Evita string-uri duplicate inutil.
|
|
372
|
+
4) Fii explicit cu invariantiile.
|
|
373
|
+
5) Scrie teste pe fiecare faza.
|
|
374
|
+
6) Separa parsing de validare semantica.
|
|
375
|
+
7) Fii atent la API-ul public al crate-urilor.
|
|
376
|
+
8) Nu expune internals gratuit.
|
|
377
|
+
9) Foloseste documentatie si exemple scurte pe functiile publice.
|
|
378
|
+
10) Masoara inainte de a micro-optimiza.
|
|
379
|
+
|
|
380
|
+
Idiom-uri bune:
|
|
381
|
+
- functii mici cu nume clare;
|
|
382
|
+
- newtype-uri pentru ID-uri semnificative;
|
|
383
|
+
- From/TryFrom unde conversiile sunt naturale;
|
|
384
|
+
- Default doar unde are sens semantic;
|
|
385
|
+
- Display pentru mesaje user-facing, Debug pentru dezvoltare.
|
|
386
|
+
|
|
387
|
+
Idiom-uri rele:
|
|
388
|
+
- bool-uri ambigue in loc de enum;
|
|
389
|
+
- functii care returneaza tuple misterioase cu 4 campuri;
|
|
390
|
+
- unwrap in cod care proceseaza fisiere reale;
|
|
391
|
+
- macro-uri inutile pentru a ascunde logica.
|
|
392
|
+
|
|
393
|
+
============================================================
|
|
394
|
+
7. UNELTE SI CRATE-URI PE CARE MERITA SA LE AI IN VEDERE
|
|
395
|
+
============================================================
|
|
396
|
+
|
|
397
|
+
Nu trebuie sa le folosesti pe toate din prima.
|
|
398
|
+
Le grupez pe rol.
|
|
399
|
+
|
|
400
|
+
Pentru baza:
|
|
401
|
+
- thiserror pentru tipuri de eroare ergonomice;
|
|
402
|
+
- anyhow doar pentru binare/CLI la margine, nu neaparat in miezul compilatorului;
|
|
403
|
+
- serde / serde_json pentru serializare, debug sau interop;
|
|
404
|
+
- tracing si tracing-subscriber pentru logging serios.
|
|
405
|
+
|
|
406
|
+
Pentru diagnostice:
|
|
407
|
+
- miette sau codespan-reporting, daca vrei mesaje si spans frumoase;
|
|
408
|
+
- alternativ, sistem propriu minimal la inceput.
|
|
409
|
+
|
|
410
|
+
Pentru testare/benchmark:
|
|
411
|
+
- cargo test;
|
|
412
|
+
- criterion pentru benchmark-uri serioase.
|
|
413
|
+
|
|
414
|
+
Pentru WASM:
|
|
415
|
+
- wasm-bindgen;
|
|
416
|
+
- wasm-pack;
|
|
417
|
+
- web-sys sau js-sys doar daca ai nevoie de interop mai bogat cu browserul.
|
|
418
|
+
|
|
419
|
+
Pentru performanta ulterioara:
|
|
420
|
+
- bumpalo sau alte arene, dar doar dupa profilare;
|
|
421
|
+
- rustc-hash sau indexmap daca ai motive concrete.
|
|
422
|
+
|
|
423
|
+
Recomandare importanta:
|
|
424
|
+
- incepe cu standard library cat mai mult;
|
|
425
|
+
- adauga crate-uri dupa ce intelegi exact ce problema rezolva.
|
|
426
|
+
|
|
427
|
+
============================================================
|
|
428
|
+
8. CUM SA ITI STRUCTUREZI PROIECTUL FUSEE IN RUST
|
|
429
|
+
============================================================
|
|
430
|
+
|
|
431
|
+
8.1. Varianta simpla pentru inceput
|
|
432
|
+
|
|
433
|
+
Incepe cu un singur crate de librarie si eventual un crate binar.
|
|
434
|
+
De exemplu:
|
|
435
|
+
- fusee_compiler/
|
|
436
|
+
- src/ast.rs
|
|
437
|
+
- src/span.rs
|
|
438
|
+
- src/token.rs
|
|
439
|
+
- src/lexer.rs
|
|
440
|
+
- src/parser.rs
|
|
441
|
+
- src/diagnostics.rs
|
|
442
|
+
- src/codegen.rs
|
|
443
|
+
- src/lib.rs
|
|
444
|
+
- src/main.rs
|
|
445
|
+
|
|
446
|
+
Avantaje:
|
|
447
|
+
- viteza mare de invatare;
|
|
448
|
+
- mai putina frictiune organizatorica;
|
|
449
|
+
- simplu de refactorizat la inceput.
|
|
450
|
+
|
|
451
|
+
8.2. Varianta buna dupa ce proiectul creste
|
|
452
|
+
|
|
453
|
+
Muti intr-un workspace cu crate-uri separate.
|
|
454
|
+
Sugestie rezonabila:
|
|
455
|
+
- fusee-span
|
|
456
|
+
- fusee-diagnostics
|
|
457
|
+
- fusee-token
|
|
458
|
+
- fusee-lexer
|
|
459
|
+
- fusee-ast
|
|
460
|
+
- fusee-parser
|
|
461
|
+
- fusee-hir
|
|
462
|
+
- fusee-codegen-js
|
|
463
|
+
- fusee-wasm
|
|
464
|
+
- fusee-cli
|
|
465
|
+
|
|
466
|
+
Nu trebuie sa faci asta in ziua 1.
|
|
467
|
+
Workspace-ul devine valoros dupa ce ai claritate pe faze.
|
|
468
|
+
|
|
469
|
+
8.3. Principiu de arhitectura
|
|
470
|
+
|
|
471
|
+
Fiecare faza trebuie sa aiba:
|
|
472
|
+
- input clar;
|
|
473
|
+
- output clar;
|
|
474
|
+
- tipuri proprii;
|
|
475
|
+
- erori clare;
|
|
476
|
+
- teste independente.
|
|
477
|
+
|
|
478
|
+
Exemplu:
|
|
479
|
+
- lexer: &str -> Vec<Token> + diagnostics
|
|
480
|
+
- parser: &[Token] -> AST + diagnostics
|
|
481
|
+
- analyzer: AST -> HIR + diagnostics
|
|
482
|
+
- transform: HIR -> HIR optimizat / IR
|
|
483
|
+
- codegen: IR/HIR -> JS/WASM-adjacent output
|
|
484
|
+
|
|
485
|
+
============================================================
|
|
486
|
+
9. DESIGNUL AST-ULUI PENTRU FUSEE
|
|
487
|
+
============================================================
|
|
488
|
+
|
|
489
|
+
Aici se fac multe greseli de incepator. Principiile bune:
|
|
490
|
+
|
|
491
|
+
9.1. Fiecare nod trebuie sa aiba span
|
|
492
|
+
|
|
493
|
+
Nu sari peste spans.
|
|
494
|
+
Span-ul este crucial pentru:
|
|
495
|
+
- erori;
|
|
496
|
+
- source maps;
|
|
497
|
+
- debug;
|
|
498
|
+
- tooling;
|
|
499
|
+
- IDE integration ulterioara.
|
|
500
|
+
|
|
501
|
+
Model simplu:
|
|
502
|
+
- Span { start: u32, end: u32 }
|
|
503
|
+
|
|
504
|
+
9.2. Separa sintaxa de semantica
|
|
505
|
+
|
|
506
|
+
AST-ul este despre forma sursei.
|
|
507
|
+
HIR-ul sau o forma intermediara semantica este despre sens dupa rezolvari si validari.
|
|
508
|
+
|
|
509
|
+
Nu baga direct in AST informatii precum:
|
|
510
|
+
- simbol rezolvat final;
|
|
511
|
+
- slot de runtime;
|
|
512
|
+
- optimizari de codegen.
|
|
513
|
+
|
|
514
|
+
9.3. Nu aglomera nodurile cu date duplicate
|
|
515
|
+
|
|
516
|
+
Exemplu prost:
|
|
517
|
+
- Identifier tine si string, si substring, si index, si span, si varianta lowercased, si pointer spre symbol.
|
|
518
|
+
|
|
519
|
+
Exemplu bun:
|
|
520
|
+
- Identifier tine text internat sau String/SmolStr si span;
|
|
521
|
+
- resolverul produce mapping spre SymbolId separat.
|
|
522
|
+
|
|
523
|
+
9.4. Fa node kinds clare
|
|
524
|
+
|
|
525
|
+
Pentru un limbaj/framework cu template sau JSX-like syntax, separa bine:
|
|
526
|
+
- expression nodes;
|
|
527
|
+
- statement nodes;
|
|
528
|
+
- declarations;
|
|
529
|
+
- template nodes / DOM-ish nodes daca limbajul tau le are;
|
|
530
|
+
- directives/annotations daca ai transformari reactive speciale.
|
|
531
|
+
|
|
532
|
+
9.5. Gandeste AST-ul pentru recoverability
|
|
533
|
+
|
|
534
|
+
Parserul pentru unelte de dezvoltare nu trebuie doar sa “esueze”.
|
|
535
|
+
Trebuie sa poata recupera partial, astfel incat:
|
|
536
|
+
- sa raporteze mai multe erori;
|
|
537
|
+
- sa permita tooling incremental;
|
|
538
|
+
- sa nu cada la primul caracter gresit.
|
|
539
|
+
|
|
540
|
+
============================================================
|
|
541
|
+
10. LEXER + PARSER: PRIMA IMPLEMENTARE SERIOASA
|
|
542
|
+
============================================================
|
|
543
|
+
|
|
544
|
+
10.1. Lexer
|
|
545
|
+
|
|
546
|
+
Rol:
|
|
547
|
+
- transforma textul in tokeni.
|
|
548
|
+
|
|
549
|
+
Ce trebuie sa produca:
|
|
550
|
+
- TokenKind;
|
|
551
|
+
- span;
|
|
552
|
+
- optional trivia separata sau tratata distinct.
|
|
553
|
+
|
|
554
|
+
Decizie importanta:
|
|
555
|
+
- daca vrei formatter/linter serios in viitor, trivia (whitespace/comments) conteaza.
|
|
556
|
+
- daca vrei doar compilator minim, poti incepe fara modelare elaborata a trivia.
|
|
557
|
+
|
|
558
|
+
10.2. Parser
|
|
559
|
+
|
|
560
|
+
Rol:
|
|
561
|
+
- construieste AST-ul din tokeni.
|
|
562
|
+
|
|
563
|
+
Recomandare:
|
|
564
|
+
- incepe cu recursive descent pentru claritate;
|
|
565
|
+
- foloseste Pratt parser pentru expresii daca ai operatori cu precedenta.
|
|
566
|
+
|
|
567
|
+
Pentru limbaje de frontend si DSL-uri de template, asta este o alegere foarte practica.
|
|
568
|
+
|
|
569
|
+
10.3. Error recovery
|
|
570
|
+
|
|
571
|
+
Trebuie sa ai o strategie de sincronizare.
|
|
572
|
+
Exemple:
|
|
573
|
+
- sari pana la ;
|
|
574
|
+
- sari pana la }
|
|
575
|
+
- sari pana la sfarsit de linie in anumite contexte
|
|
576
|
+
|
|
577
|
+
Fara error recovery, experienta de developer va fi slaba.
|
|
578
|
+
|
|
579
|
+
10.4. Parser API bun
|
|
580
|
+
|
|
581
|
+
Un API bun evita sa expuna prea mult din internals.
|
|
582
|
+
Exemplu conceptual:
|
|
583
|
+
- parse_module(source: &str) -> ParseResult<Module>
|
|
584
|
+
|
|
585
|
+
Unde ParseResult poate contine:
|
|
586
|
+
- root AST;
|
|
587
|
+
- diagnostics;
|
|
588
|
+
- eventual flag de success partial.
|
|
589
|
+
|
|
590
|
+
============================================================
|
|
591
|
+
11. DIAGNOSTICE BUNE: DIFERENTA DINTRE O JUCARIE SI UN TOOL SERIOS
|
|
592
|
+
============================================================
|
|
593
|
+
|
|
594
|
+
Daca vrei ca Fusee sa fie respectabil, trateaza diagnosticele ca produs.
|
|
595
|
+
|
|
596
|
+
Un diagnostic bun include:
|
|
597
|
+
- severitate: error/warning/note;
|
|
598
|
+
- mesaj principal clar;
|
|
599
|
+
- span principal;
|
|
600
|
+
- mesaje secundare sau labels unde ajuta;
|
|
601
|
+
- sugestie de fix unde este posibil.
|
|
602
|
+
|
|
603
|
+
Principii:
|
|
604
|
+
- mesajele trebuie sa explice problema, nu doar sa repete starea interna;
|
|
605
|
+
- evita jargonul intern fara sens pentru utilizator;
|
|
606
|
+
- pastreaza consistenta de wording.
|
|
607
|
+
|
|
608
|
+
Exemplu bun:
|
|
609
|
+
- “Atributul reactive:each asteapta o expresie iterabila.”
|
|
610
|
+
Nu:
|
|
611
|
+
- “Invalid node in transform pass.”
|
|
612
|
+
|
|
613
|
+
============================================================
|
|
614
|
+
12. ANALIZA SEMANTICA SI REACTIVITATEA FINA
|
|
615
|
+
============================================================
|
|
616
|
+
|
|
617
|
+
Aici proiectul tau devine interesant conceptual.
|
|
618
|
+
Pentru un framework inspirat de Solid/Vue, compilatorul nu doar parseaza; el decide ce parti sunt reactive, ce dependinte exista si cum generezi output eficient.
|
|
619
|
+
|
|
620
|
+
Intrebari de arhitectura pe care trebuie sa le fixezi devreme:
|
|
621
|
+
- ce este o sursa reactiva in Fusee?
|
|
622
|
+
- cum detectezi citiri reactive?
|
|
623
|
+
- cum separi evaluarea la compile-time de runtime?
|
|
624
|
+
- cand generezi subscriptions, effects sau memo-uri?
|
|
625
|
+
- cum tratezi template expressions, closures si nested scopes?
|
|
626
|
+
|
|
627
|
+
Recomandare puternica:
|
|
628
|
+
- nu incerca sa pui toata semantica direct in parser;
|
|
629
|
+
- parserul construieste forma;
|
|
630
|
+
- analyzerul semantic decide intentia reactiva.
|
|
631
|
+
|
|
632
|
+
Pentru acest pas, o forma intermediara HIR este foarte utila.
|
|
633
|
+
HIR-ul poate normaliza:
|
|
634
|
+
- sugar sintactic;
|
|
635
|
+
- directii reactive;
|
|
636
|
+
- forme speciale de template;
|
|
637
|
+
- binding-uri si scoping.
|
|
638
|
+
|
|
639
|
+
============================================================
|
|
640
|
+
13. CODEGEN: JS INTAI, APOI RUST/WASM
|
|
641
|
+
============================================================
|
|
642
|
+
|
|
643
|
+
13.1. Etapa JS
|
|
644
|
+
|
|
645
|
+
Primul compilator in JS iti valideaza limbajul si transformarile.
|
|
646
|
+
Asta e foarte bine. Il poti folosi ca laborator de semantica.
|
|
647
|
+
|
|
648
|
+
Obiectivul in faza JS nu este viteza maxima, ci:
|
|
649
|
+
- sa validezi AST-ul;
|
|
650
|
+
- sa validezi transformarea reactiva;
|
|
651
|
+
- sa validezi output-ul;
|
|
652
|
+
- sa descoperi edge case-uri.
|
|
653
|
+
|
|
654
|
+
13.2. Etapa Rust
|
|
655
|
+
|
|
656
|
+
Cand treci la Rust, idealul nu este sa rescrii haotic totul.
|
|
657
|
+
Trebuie sa porti o specificatie stabilizata:
|
|
658
|
+
- aceleasi node kinds;
|
|
659
|
+
- aceeasi semantica observabila;
|
|
660
|
+
- teste de snapshot compatibile;
|
|
661
|
+
- output comparabil.
|
|
662
|
+
|
|
663
|
+
13.3. Codegen bun
|
|
664
|
+
|
|
665
|
+
Un codegen bun:
|
|
666
|
+
- nu concateneaza string-uri haotic;
|
|
667
|
+
- are structuri intermediare clare;
|
|
668
|
+
- separa emiterea de logica semantica;
|
|
669
|
+
- pastreaza mapping pentru source map daca vei avea nevoie.
|
|
670
|
+
|
|
671
|
+
Strategie simpla:
|
|
672
|
+
- emiti intr-un String buffer cu helper-e de indentare;
|
|
673
|
+
- mai tarziu poti trece la writer mai disciplinat sau IR textual.
|
|
674
|
+
|
|
675
|
+
============================================================
|
|
676
|
+
14. RUST -> WASM IN BROWSER
|
|
677
|
+
============================================================
|
|
678
|
+
|
|
679
|
+
Aici sunt cateva decizii importante.
|
|
680
|
+
|
|
681
|
+
14.1. Ce compilezi la WASM
|
|
682
|
+
|
|
683
|
+
Nu tot proiectul trebuie automat dus in WASM.
|
|
684
|
+
Candidati buni:
|
|
685
|
+
- lexer;
|
|
686
|
+
- parser;
|
|
687
|
+
- analyzer;
|
|
688
|
+
- compilare de string sursa -> output.
|
|
689
|
+
|
|
690
|
+
Candidati mai putin buni initial:
|
|
691
|
+
- integrarea UI;
|
|
692
|
+
- orchestrare de bundler;
|
|
693
|
+
- logica mare de filesystem.
|
|
694
|
+
|
|
695
|
+
14.2. Granita JS/WASM
|
|
696
|
+
|
|
697
|
+
Granita trebuie sa fie mica si stabila.
|
|
698
|
+
API bun:
|
|
699
|
+
- compile(source: string, options: object) -> result object
|
|
700
|
+
|
|
701
|
+
API prost:
|
|
702
|
+
- sute de apeluri fine-grained intre JS si WASM pentru fiecare nod.
|
|
703
|
+
|
|
704
|
+
Regula importanta:
|
|
705
|
+
- crossing-ul JS/WASM are cost;
|
|
706
|
+
- transfera putine obiecte, mai mari si bine definite.
|
|
707
|
+
|
|
708
|
+
14.3. Reprezentarea datelor peste granita
|
|
709
|
+
|
|
710
|
+
Ai trei variante practice:
|
|
711
|
+
1) string in, string/json out;
|
|
712
|
+
2) string in, obiecte JS prin wasm-bindgen/serde;
|
|
713
|
+
3) buffer-e binare mai compacte, mai tarziu.
|
|
714
|
+
|
|
715
|
+
Pentru inceput, varianta 1 sau 2 este cea mai sanatoasa.
|
|
716
|
+
|
|
717
|
+
14.4. Browser execution model
|
|
718
|
+
|
|
719
|
+
Daca compilarea poate deveni grea:
|
|
720
|
+
- ruleaza in Web Worker;
|
|
721
|
+
- evita blocarea thread-ului principal;
|
|
722
|
+
- masoara dimensiunea finala a .wasm.
|
|
723
|
+
|
|
724
|
+
14.5. Tooling comun
|
|
725
|
+
|
|
726
|
+
Conform documentatiei Rust/WASM si MDN, fluxul comun foloseste wasm-pack si wasm-bindgen pentru a construi pachete consumabile din web. Pentru un proiect ca Fusee, aceasta este ruta naturala la inceput.
|
|
727
|
+
|
|
728
|
+
============================================================
|
|
729
|
+
15. PLAN DE INVATARE RUST, DE LA ZERO LA FUSEE
|
|
730
|
+
============================================================
|
|
731
|
+
|
|
732
|
+
ETAPA 1: Primele 2-3 saptamani
|
|
733
|
+
Obiectiv: sa nu mai fii incepator total.
|
|
734
|
+
|
|
735
|
+
Invata si exerseaza:
|
|
736
|
+
- ownership;
|
|
737
|
+
- borrowing;
|
|
738
|
+
- structs, enums, match;
|
|
739
|
+
- Option/Result;
|
|
740
|
+
- Vec, String, HashMap;
|
|
741
|
+
- modules;
|
|
742
|
+
- tests.
|
|
743
|
+
|
|
744
|
+
Mini-proiecte:
|
|
745
|
+
- calculator CLI;
|
|
746
|
+
- parser de expresii simple;
|
|
747
|
+
- loader de fisiere cu erori bune.
|
|
748
|
+
|
|
749
|
+
ETAPA 2: Urmatoarele 2-4 saptamani
|
|
750
|
+
Obiectiv: sa poti scrie infrastructura decenta.
|
|
751
|
+
|
|
752
|
+
Invata:
|
|
753
|
+
- iterators;
|
|
754
|
+
- pattern matching serios;
|
|
755
|
+
- traits fara exces;
|
|
756
|
+
- error types;
|
|
757
|
+
- documentatie si testing discipline.
|
|
758
|
+
|
|
759
|
+
Mini-proiecte:
|
|
760
|
+
- lexer pentru un mini-limbaj;
|
|
761
|
+
- parser cu precedenta operatorilor;
|
|
762
|
+
- pretty-printer AST.
|
|
763
|
+
|
|
764
|
+
ETAPA 3: 1-2 luni
|
|
765
|
+
Obiectiv: sa poti construi un parser/compiler simplu.
|
|
766
|
+
|
|
767
|
+
Invata:
|
|
768
|
+
- spans si diagnostics;
|
|
769
|
+
- recursive descent / Pratt parsing;
|
|
770
|
+
- snapshot tests;
|
|
771
|
+
- profiling si benchmark minimal.
|
|
772
|
+
|
|
773
|
+
Mini-proiecte:
|
|
774
|
+
- mini transpiler;
|
|
775
|
+
- template parser;
|
|
776
|
+
- semantic analyzer pentru scope-uri.
|
|
777
|
+
|
|
778
|
+
ETAPA 4: proiect Fusee real
|
|
779
|
+
Obiectiv: migratie controlata spre Rust + WASM.
|
|
780
|
+
|
|
781
|
+
Construieste:
|
|
782
|
+
- lexer;
|
|
783
|
+
- parser;
|
|
784
|
+
- diagnostics;
|
|
785
|
+
- HIR;
|
|
786
|
+
- transformari reactive;
|
|
787
|
+
- codegen;
|
|
788
|
+
- wasm bindings.
|
|
789
|
+
|
|
790
|
+
============================================================
|
|
791
|
+
16. CHECKLIST PENTRU PARTEA DE JS AST PARSER INITIALA
|
|
792
|
+
============================================================
|
|
793
|
+
|
|
794
|
+
Inainte sa scrii parserul Rust, valideaza aceste lucruri in implementarea JS:
|
|
795
|
+
|
|
796
|
+
1) AST-ul are spans peste tot?
|
|
797
|
+
2) Ai separare intre parse si transform?
|
|
798
|
+
3) Ai teste pe input invalid?
|
|
799
|
+
4) Ai output snapshots?
|
|
800
|
+
5) Ai definit clar node kinds pentru sintaxa speciala Fusee?
|
|
801
|
+
6) Ai o semantica clara pentru reactivitate?
|
|
802
|
+
7) Ai identificat ce date trebuie pastrate pentru codegen?
|
|
803
|
+
8) Ai delimitat ce apartine compilatorului vs runtime-ului?
|
|
804
|
+
|
|
805
|
+
Daca raspunsul este “nu” la multe dintre acestea, nu te grabi la portarea in Rust.
|
|
806
|
+
Rust nu repara neclaritatea de design; doar o face mai evidenta.
|
|
807
|
+
|
|
808
|
+
============================================================
|
|
809
|
+
17. CHECKLIST PENTRU MIGRAREA DIN JS IN RUST
|
|
810
|
+
============================================================
|
|
811
|
+
|
|
812
|
+
1) Exista o specificatie stabila a AST-ului?
|
|
813
|
+
2) Exista corpus de teste si snapshot-uri?
|
|
814
|
+
3) Exista exemple edge-case?
|
|
815
|
+
4) Exista claritate asupra error recovery?
|
|
816
|
+
5) Exista claritate asupra output-ului observabil?
|
|
817
|
+
6) Exista o separare clara intre parser si transformari?
|
|
818
|
+
7) Exista un minim API public pe care il vei expune in WASM?
|
|
819
|
+
|
|
820
|
+
Migratia buna este:
|
|
821
|
+
- intai parser compatibil;
|
|
822
|
+
- apoi diagnostics compatibile;
|
|
823
|
+
- apoi codegen compatibil;
|
|
824
|
+
- apoi optimizari.
|
|
825
|
+
|
|
826
|
+
============================================================
|
|
827
|
+
18. ANTI-PATTERN-URI PE CARE SA LE EVITI
|
|
828
|
+
============================================================
|
|
829
|
+
|
|
830
|
+
1) Rescrierea totala prea devreme
|
|
831
|
+
- Nu rescrie parserul JS in Rust inainte sa stii exact ce limbaj ai.
|
|
832
|
+
|
|
833
|
+
2) Optimizare prematura
|
|
834
|
+
- Arena allocation, string interning sofisticat, hashers speciali: toate vin dupa benchmark.
|
|
835
|
+
|
|
836
|
+
3) AST prea “OO”
|
|
837
|
+
- Rust nu e Java/C#; evita simularea ierarhiilor de clase cand enum rezolva natural problema.
|
|
838
|
+
|
|
839
|
+
4) RefCell peste tot
|
|
840
|
+
- Deseori semn ca ownership-ul nu e bine gandit.
|
|
841
|
+
|
|
842
|
+
5) Lifetimes peste tot in AST
|
|
843
|
+
- Pentru inceput, tine spans si input separat; iti simplifica enorm viata.
|
|
844
|
+
|
|
845
|
+
6) Codegen amestecat cu semantic analysis
|
|
846
|
+
- duce la cod greu de mentinut si testat.
|
|
847
|
+
|
|
848
|
+
7) API WASM prea fin-grained
|
|
849
|
+
- duce la overhead si design fragil.
|
|
850
|
+
|
|
851
|
+
8) Diagnostic slab
|
|
852
|
+
- face tool-ul sa para imatur chiar daca parserul e bun.
|
|
853
|
+
|
|
854
|
+
============================================================
|
|
855
|
+
19. STRATEGIE DE TESTARE
|
|
856
|
+
============================================================
|
|
857
|
+
|
|
858
|
+
Trebuie sa ai cel putin 5 tipuri de teste.
|
|
859
|
+
|
|
860
|
+
1) Unit tests
|
|
861
|
+
- pe lexer;
|
|
862
|
+
- pe parser helper-e;
|
|
863
|
+
- pe spans;
|
|
864
|
+
- pe functii de transformare mici.
|
|
865
|
+
|
|
866
|
+
2) Snapshot tests
|
|
867
|
+
- AST output;
|
|
868
|
+
- diagnostics;
|
|
869
|
+
- generated code.
|
|
870
|
+
|
|
871
|
+
3) Golden tests
|
|
872
|
+
- fisiere de intrare -> fisiere de iesire asteptata.
|
|
873
|
+
|
|
874
|
+
4) Error recovery tests
|
|
875
|
+
- input invalid care totusi produce partial AST si multiple diagnostics.
|
|
876
|
+
|
|
877
|
+
5) Differential tests (ideal mai tarziu)
|
|
878
|
+
- compari implementarea JS cu cea Rust pe acelasi corpus.
|
|
879
|
+
|
|
880
|
+
Asta este extrem de valoros pentru migrare.
|
|
881
|
+
|
|
882
|
+
============================================================
|
|
883
|
+
20. STRATEGIE DE PERFORMANTA
|
|
884
|
+
============================================================
|
|
885
|
+
|
|
886
|
+
Masori in ordine:
|
|
887
|
+
1) corectitudine;
|
|
888
|
+
2) ergonomie API;
|
|
889
|
+
3) throughput parser;
|
|
890
|
+
4) memorie;
|
|
891
|
+
5) code size WASM;
|
|
892
|
+
6) latenta in browser.
|
|
893
|
+
|
|
894
|
+
Ce sa optimizezi de obicei mai intai:
|
|
895
|
+
- allocatii excesive;
|
|
896
|
+
- string-uri duplicate;
|
|
897
|
+
- traversari redundante ale AST-ului;
|
|
898
|
+
- crossing JS/WASM inutil;
|
|
899
|
+
- serializare prea voluminoasa.
|
|
900
|
+
|
|
901
|
+
Ce sa NU optimizezi din instinct:
|
|
902
|
+
- fiecare bucla mica;
|
|
903
|
+
- fiecare clonare, daca nu e hot path;
|
|
904
|
+
- fiecare struct dupa “feeling”.
|
|
905
|
+
|
|
906
|
+
============================================================
|
|
907
|
+
21. CAND SA FOLOSESTI ARENE, INTERNING SI ID-URI
|
|
908
|
+
============================================================
|
|
909
|
+
|
|
910
|
+
Aceste tehnici sunt utile, dar vin cu cost conceptual.
|
|
911
|
+
|
|
912
|
+
Arene
|
|
913
|
+
- bune cand ai multe noduri cu durata similara de viata;
|
|
914
|
+
- bune pentru performanta si localitate;
|
|
915
|
+
- rele daca le introduci inainte sa stii unde este hot path-ul.
|
|
916
|
+
|
|
917
|
+
String interning
|
|
918
|
+
- bun pentru identificatori repetati;
|
|
919
|
+
- util in symbol tables si comparisons;
|
|
920
|
+
- nu obligatoriu in MVP.
|
|
921
|
+
|
|
922
|
+
ID-uri stabile
|
|
923
|
+
- foarte bune pentru a separa proprietatea datelor de referintele logice;
|
|
924
|
+
- de multe ori mai sanatos decat grafuri de referinte complexe.
|
|
925
|
+
|
|
926
|
+
Recomandare:
|
|
927
|
+
- pentru MVP: structuri simple;
|
|
928
|
+
- pentru versiuni serioase: ia in calcul SymbolId, NodeId si eventual internare selectiva.
|
|
929
|
+
|
|
930
|
+
============================================================
|
|
931
|
+
22. CUM SA ABORDEZI DESIGNUL REACTIV PENTRU FUSEE
|
|
932
|
+
============================================================
|
|
933
|
+
|
|
934
|
+
Din perspectiva compilatorului, fine-grained reactivity inseamna ca nu orice expresie trebuie tratata uniform.
|
|
935
|
+
Ai nevoie de clasificari clare.
|
|
936
|
+
|
|
937
|
+
De exemplu, vei vrea sa separi conceptual:
|
|
938
|
+
- expresii pur statice;
|
|
939
|
+
- expresii evaluate o singura data;
|
|
940
|
+
- expresii reactive dependente de semnale/store-uri;
|
|
941
|
+
- efecte cu side effects;
|
|
942
|
+
- memo-uri / derivari;
|
|
943
|
+
- bindings DOM care cer update punctual.
|
|
944
|
+
|
|
945
|
+
Aici un analyzer semantic bun te ajuta mai mult decat un parser sofisticat.
|
|
946
|
+
|
|
947
|
+
Intrebari de proiectare:
|
|
948
|
+
- exista primitive dedicate in limbaj pentru reactivitate sau inferenta din usage?
|
|
949
|
+
- reactivitatea este implicita sau explicita?
|
|
950
|
+
- cum tratezi capturile in closure?
|
|
951
|
+
- cum detectezi invalidarea minima?
|
|
952
|
+
|
|
953
|
+
Aceste intrebari trebuie rezolvate la nivel de semantica si transform, nu doar la nivel de sintaxa.
|
|
954
|
+
|
|
955
|
+
============================================================
|
|
956
|
+
23. EXEMPLU DE ARHITECTURA MINIMA BUNA PENTRU FUSEE
|
|
957
|
+
============================================================
|
|
958
|
+
|
|
959
|
+
Pas 1: JS reference compiler
|
|
960
|
+
- parser JS;
|
|
961
|
+
- AST clar;
|
|
962
|
+
- transform reactive;
|
|
963
|
+
- codegen JS;
|
|
964
|
+
- snapshot tests.
|
|
965
|
+
|
|
966
|
+
Pas 2: Rust core library
|
|
967
|
+
- lexer;
|
|
968
|
+
- parser;
|
|
969
|
+
- diagnostics;
|
|
970
|
+
- AST;
|
|
971
|
+
- parse API.
|
|
972
|
+
|
|
973
|
+
Pas 3: semantic layer
|
|
974
|
+
- scopes;
|
|
975
|
+
- symbol resolution;
|
|
976
|
+
- HIR;
|
|
977
|
+
- clasificare reactiva.
|
|
978
|
+
|
|
979
|
+
Pas 4: codegen parity
|
|
980
|
+
- output compatibil cu implementarea JS de referinta.
|
|
981
|
+
|
|
982
|
+
Pas 5: wasm package
|
|
983
|
+
- compile(source, options) -> result;
|
|
984
|
+
- worker integration;
|
|
985
|
+
- pachet npm.
|
|
986
|
+
|
|
987
|
+
Pas 6: optimizari si tooling
|
|
988
|
+
- incremental ideas;
|
|
989
|
+
- formatter/linter eventual;
|
|
990
|
+
- source maps;
|
|
991
|
+
- IDE support.
|
|
992
|
+
|
|
993
|
+
============================================================
|
|
994
|
+
24. NOTE SPECIFICE RUST 1.95.0 RELEVANTE PENTRU TINE
|
|
995
|
+
============================================================
|
|
996
|
+
|
|
997
|
+
Verificat din anuntul oficial Rust 1.95.0:
|
|
998
|
+
- cfg_select! este stabilizat;
|
|
999
|
+
- if-let guards in match sunt disponibile;
|
|
1000
|
+
- exista API-uri standard noi precum Vec::push_mut / insert_mut si analogi pentru VecDeque/LinkedList;
|
|
1001
|
+
- JSON target specs au fost destabilizate pe stable.
|
|
1002
|
+
|
|
1003
|
+
Cum traduci asta practic pentru Fusee:
|
|
1004
|
+
- ramai pe stable cat poti;
|
|
1005
|
+
- evita dependenta pe configuratii exotice de target pe stable;
|
|
1006
|
+
- foloseste noile facilitati doar daca imbunatatesc claritatea, nu ca noutate cosmetica;
|
|
1007
|
+
- nu construi arhitectura pe detalii prea recente daca nu iti aduc un castig real.
|
|
1008
|
+
|
|
1009
|
+
============================================================
|
|
1010
|
+
25. ORDINEA CORECTA A DECIZIILOR TEHNICE IN FUSEE
|
|
1011
|
+
============================================================
|
|
1012
|
+
|
|
1013
|
+
1) defineste limbajul;
|
|
1014
|
+
2) defineste AST-ul;
|
|
1015
|
+
3) defineste semantica reactiva;
|
|
1016
|
+
4) construieste parserul de referinta in JS;
|
|
1017
|
+
5) construieste corpusul de teste;
|
|
1018
|
+
6) portare parser/diagnostics in Rust;
|
|
1019
|
+
7) portare analyzer/codegen;
|
|
1020
|
+
8) expunere WASM;
|
|
1021
|
+
9) profilare;
|
|
1022
|
+
10) optimizare.
|
|
1023
|
+
|
|
1024
|
+
Daca inversezi aceasta ordine, te vei lovi de rescrieri dese.
|
|
1025
|
+
|
|
1026
|
+
============================================================
|
|
1027
|
+
26. CE AS FACE EU, CONCRET, DACA AS FI IN LOCUL TAU
|
|
1028
|
+
============================================================
|
|
1029
|
+
|
|
1030
|
+
Luna 1
|
|
1031
|
+
- invat Rust serios;
|
|
1032
|
+
- scriu 2-3 mini-proiecte;
|
|
1033
|
+
- imi definesc Span, Token, AST pentru Fusee.
|
|
1034
|
+
|
|
1035
|
+
Luna 2
|
|
1036
|
+
- termin parserul JS de referinta;
|
|
1037
|
+
- stabilesc output-ul si semantica reactiva minima;
|
|
1038
|
+
- scriu snapshot tests.
|
|
1039
|
+
|
|
1040
|
+
Luna 3
|
|
1041
|
+
- scriu lexer + parser in Rust;
|
|
1042
|
+
- fac diagnostice lizibile;
|
|
1043
|
+
- compar paritatea fata de JS.
|
|
1044
|
+
|
|
1045
|
+
Luna 4
|
|
1046
|
+
- adaug semantic analysis;
|
|
1047
|
+
- adaug codegen compatibil;
|
|
1048
|
+
- fac primele benchmark-uri.
|
|
1049
|
+
|
|
1050
|
+
Luna 5
|
|
1051
|
+
- compilez la WASM;
|
|
1052
|
+
- expun API minim pentru browser;
|
|
1053
|
+
- mut compilarea in worker daca e nevoie.
|
|
1054
|
+
|
|
1055
|
+
Luna 6+
|
|
1056
|
+
- optimizez;
|
|
1057
|
+
- introduc interning / arene doar unde benchmark-ul justifica;
|
|
1058
|
+
- pregatesc eventual tooling suplimentar.
|
|
1059
|
+
|
|
1060
|
+
============================================================
|
|
1061
|
+
27. REZUMAT EXECUTIV
|
|
1062
|
+
============================================================
|
|
1063
|
+
|
|
1064
|
+
Daca retii doar cateva idei, sa fie acestea:
|
|
1065
|
+
|
|
1066
|
+
1) Rust este excelent pentru partea de compilator si WASM din Fusee.
|
|
1067
|
+
2) Nu sari direct la Rust pana nu ai claritate suficienta asupra limbajului si a AST-ului.
|
|
1068
|
+
3) In Rust, designul de date si ownership-ul conteaza mai mult decat “trucurile”.
|
|
1069
|
+
4) Evita clone(), Rc<RefCell<...>> si unsafe ca solutii implicite.
|
|
1070
|
+
5) Pastreaza spans peste tot.
|
|
1071
|
+
6) Separa parserul de analiza semantica si de codegen.
|
|
1072
|
+
7) Tine granita JS/WASM mica.
|
|
1073
|
+
8) Testele si diagnosticele sunt parte din produs.
|
|
1074
|
+
9) Optimizeaza doar dupa benchmark.
|
|
1075
|
+
10) Foloseste implementarea JS ca specificatie executabila pentru portarea in Rust.
|
|
1076
|
+
|
|
1077
|
+
============================================================
|
|
1078
|
+
28. SURSE SI REPERE VERIFICATE
|
|
1079
|
+
============================================================
|
|
1080
|
+
|
|
1081
|
+
Surse oficiale / utile verificate pentru acest ghid:
|
|
1082
|
+
|
|
1083
|
+
1) Anunt oficial Rust 1.95.0
|
|
1084
|
+
https://blog.rust-lang.org/2026/04/16/Rust-1.95.0/
|
|
1085
|
+
|
|
1086
|
+
2) Release notes detaliate Rust 1.95.0
|
|
1087
|
+
https://doc.rust-lang.org/stable/releases.html#version-1950-2026-04-16
|
|
1088
|
+
|
|
1089
|
+
3) Rust and WebAssembly Book
|
|
1090
|
+
https://rustwasm.github.io/docs/book/
|
|
1091
|
+
|
|
1092
|
+
4) MDN - Compiling from Rust to WebAssembly
|
|
1093
|
+
https://developer.mozilla.org/en-US/docs/WebAssembly/Guides/Rust_to_Wasm
|
|
1094
|
+
|
|
1095
|
+
5) AST Explorer, util pentru inspectie AST si invatare comparativa intre parsere
|
|
1096
|
+
https://astexplorer.net/
|
|
1097
|
+
|
|
1098
|
+
6) Discutii si materiale introductive despre AST in JS, utile pentru perspectiva de ecosistem
|
|
1099
|
+
https://www.digitalocean.com/community/tutorials/js-traversing-ast
|
|
1100
|
+
https://stackoverflow.com/questions/16127985/what-is-javascript-ast-how-to-play-with-it
|
|
1101
|
+
|
|
1102
|
+
============================================================
|
|
1103
|
+
29. CONCLUZIE FINALA
|
|
1104
|
+
============================================================
|
|
1105
|
+
|
|
1106
|
+
Pentru Fusee, cea mai buna strategie nu este “scriu tot in Rust cat mai repede”, ci:
|
|
1107
|
+
- proiectez bine limbajul;
|
|
1108
|
+
- validez semantica in JS;
|
|
1109
|
+
- portez disciplinat in Rust;
|
|
1110
|
+
- expun nucleul prin WASM;
|
|
1111
|
+
- optimizez cand am masuratori.
|
|
1112
|
+
|
|
1113
|
+
Daca respecti aceasta ordine, ai sanse reale sa ajungi la un tool modern, credibil si extensibil.
|
|
1114
|
+
Daca o ignori, risti sa construiesti un parser rapid pentru o semantica inca neclara.
|
|
1115
|
+
|
|
1116
|
+
Rust te poate ajuta enorm, dar doar daca il folosesti ca instrument de claritate si disciplina, nu doar ca sursa de performanta.
|
|
1117
|
+
|
|
1118
|
+
Sfarsit.
|