Rev 9847 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7983 | leency | 1 | (* |
7597 | akron1 | 2 | BSD 2-Clause License |
3 | |||
9893 | akron1 | 4 | Copyright (c) 2018-2023, Anton Krotov |
7597 | akron1 | 5 | All rights reserved. |
6 | *) |
||
7 | |||
8 | MODULE PROG; |
||
9 | |||
8859 | leency | 10 | IMPORT SCAN, LISTS, ARITH, ERRORS, C := COLLECTIONS, IL, UTILS, TARGETS, STRINGS, PATHS; |
7597 | akron1 | 11 | |
12 | |||
13 | CONST |
||
14 | |||
15 | MAXARRDIM* = 5; |
||
16 | MAXSCOPE = 16; |
||
17 | MAXSYSVPARAM* = 26; |
||
18 | |||
19 | idNONE* = 0; idGUARD = 1; idMODULE* = 2; idCONST* = 3; |
||
20 | idTYPE* = 4; idSTFUNC* = 5; idSTPROC* = 6; idVAR* = 7; |
||
21 | idPROC* = 8; idVPAR* = 9; idPARAM* = 10; idSYSFUNC* = 11; |
||
22 | idSYSPROC* = 12; idIMP* = 13; |
||
23 | |||
24 | tINTEGER* = 1; tBYTE* = 2; tCHAR* = 3; tSET* = 4; |
||
25 | tBOOLEAN* = 5; tREAL* = 6; tARRAY* = 7; tRECORD* = 8; |
||
26 | tPOINTER* = 9; tPROCEDURE* = 10; tSTRING* = 11; tNIL* = 12; |
||
8097 | maxcodehac | 27 | tCARD32* = 13; tANYREC* = 14; tWCHAR* = 15; tNONE* = 16; |
7597 | akron1 | 28 | |
7696 | akron1 | 29 | BASICTYPES* = {tINTEGER, tBYTE, tCHAR, tSET, tBOOLEAN, tREAL, tCARD32, tWCHAR}; |
7597 | akron1 | 30 | |
31 | stABS* = 1; stASR* = 2; stCHR* = 3; stFLOOR* = 4; |
||
32 | stFLT* = 5; stLEN* = 6; stLSL* = 7; stODD* = 8; |
||
33 | stORD* = 9; stROR* = 10; stASSERT* = 11; stDEC* = 12; |
||
34 | stEXCL* = 13; stINC* = 14; stINCL* = 15; stNEW* = 16; |
||
35 | stPACK* = 17; stUNPK* = 18; sysADR* = 19; sysSIZE* = 20; |
||
36 | sysGET* = 21; sysPUT* = 22; |
||
37 | |||
8097 | maxcodehac | 38 | stDISPOSE* = 23; stLSR* = 24; stBITS* = 25; sysCODE* = 26; |
39 | sysMOVE* = 27; stLENGTH* = 28; stMIN* = 29; stMAX* = 30; |
||
40 | sysSADR* = 31; sysTYPEID* = 32; sysCOPY* = 33; sysINF* = 34; |
||
41 | sysPUT8* = 35; sysPUT16* = 36; stCOPY* = 37; stWCHR* = 38; |
||
42 | sysWSADR* = 39; sysPUT32* = 40; (*sysNOP* = 41; sysEINT* = 42; |
||
43 | sysDINT* = 43;*)sysGET8* = 44; sysGET16* = 45; sysGET32* = 46; |
||
9893 | akron1 | 44 | sysVAL* = 47; |
7597 | akron1 | 45 | |
8097 | maxcodehac | 46 | default32* = 2; _default32* = default32 + 1; |
7597 | akron1 | 47 | stdcall* = 4; _stdcall* = stdcall + 1; |
8859 | leency | 48 | cdecl* = 6; _cdecl* = cdecl + 1; |
49 | ccall* = 8; _ccall* = ccall + 1; |
||
7597 | akron1 | 50 | win64* = 10; _win64* = win64 + 1; |
8859 | leency | 51 | default64* = 12; _default64* = default64 + 1; |
52 | systemv* = 14; _systemv* = systemv + 1; |
||
53 | default16* = 16; _default16* = default16 + 1; |
||
54 | code* = 18; _code* = code + 1; |
||
9847 | akron1 | 55 | fastcall* = 20; _fastcall* = fastcall + 1; |
7597 | akron1 | 56 | |
7693 | akron1 | 57 | noalign* = 22; |
7597 | akron1 | 58 | |
9847 | akron1 | 59 | callee_clean_up* = {default32, _default32, stdcall, _stdcall, default64, _default64, fastcall, _fastcall}; |
7597 | akron1 | 60 | |
8859 | leency | 61 | sf_stdcall* = 0; sf_oberon* = 1; sf_cdecl* = 2; sf_ccall* = 3; |
62 | sf_win64* = 4; sf_systemv* = 5; sf_windows* = 6; sf_linux* = 7; |
||
9847 | akron1 | 63 | sf_code* = 8; sf_fastcall* = 9; |
64 | sf_noalign* = 10; |
||
7693 | akron1 | 65 | |
9847 | akron1 | 66 | proc_flags* = {sf_stdcall, sf_cdecl, sf_ccall, sf_win64, sf_systemv, sf_windows, sf_linux, sf_code, sf_oberon, sf_fastcall}; |
7693 | akron1 | 67 | rec_flags* = {sf_noalign}; |
68 | |||
7597 | akron1 | 69 | STACK_FRAME = 2; |
70 | |||
71 | |||
72 | TYPE |
||
73 | |||
7693 | akron1 | 74 | OPTIONS* = RECORD |
75 | |||
9177 | akron1 | 76 | version*, stack*, ram*, rom*, tab*: INTEGER; |
9579 | akron1 | 77 | pic*, lower*, uses*: BOOLEAN; |
7693 | akron1 | 78 | checking*: SET |
79 | |||
80 | END; |
||
81 | |||
7597 | akron1 | 82 | IDENT* = POINTER TO rIDENT; |
83 | |||
84 | UNIT* = POINTER TO rUNIT; |
||
85 | |||
8097 | maxcodehac | 86 | _TYPE* = POINTER TO rTYPE; |
7597 | akron1 | 87 | |
88 | FRWPTR* = POINTER TO RECORD (LISTS.ITEM) |
||
89 | |||
8097 | maxcodehac | 90 | _type: _TYPE; |
7597 | akron1 | 91 | baseIdent: SCAN.IDENT; |
92 | linked: BOOLEAN; |
||
93 | |||
94 | pos*: SCAN.POSITION; |
||
95 | notRecord*: BOOLEAN |
||
96 | |||
97 | END; |
||
98 | |||
99 | PROC* = POINTER TO RECORD (LISTS.ITEM) |
||
100 | |||
101 | label*: INTEGER; |
||
102 | used*: BOOLEAN; |
||
103 | processed*: BOOLEAN; |
||
8097 | maxcodehac | 104 | _import*: LISTS.ITEM; |
7597 | akron1 | 105 | using*: LISTS.LIST; |
106 | enter*, |
||
107 | leave*: LISTS.ITEM |
||
108 | |||
109 | END; |
||
110 | |||
111 | USED_PROC = POINTER TO RECORD (LISTS.ITEM) |
||
112 | |||
113 | proc: PROC |
||
114 | |||
115 | END; |
||
116 | |||
117 | rUNIT = RECORD (LISTS.ITEM) |
||
118 | |||
8859 | leency | 119 | fname*: PATHS.PATH; |
7597 | akron1 | 120 | name*: SCAN.IDENT; |
7693 | akron1 | 121 | idents*: LISTS.LIST; |
7597 | akron1 | 122 | frwPointers: LISTS.LIST; |
123 | gscope: IDENT; |
||
124 | closed*: BOOLEAN; |
||
125 | scopeLvl*: INTEGER; |
||
126 | sysimport*: BOOLEAN; |
||
7693 | akron1 | 127 | scopes*: ARRAY MAXSCOPE OF PROC |
7597 | akron1 | 128 | |
129 | END; |
||
130 | |||
131 | FIELD* = POINTER TO rFIELD; |
||
132 | |||
133 | PARAM* = POINTER TO rPARAM; |
||
134 | |||
8097 | maxcodehac | 135 | rTYPE = RECORD (LISTS.ITEM) |
7597 | akron1 | 136 | |
137 | typ*: INTEGER; |
||
138 | size*: INTEGER; |
||
7693 | akron1 | 139 | parSize*: INTEGER; |
7597 | akron1 | 140 | length*: INTEGER; |
141 | align*: INTEGER; |
||
8097 | maxcodehac | 142 | base*: _TYPE; |
7693 | akron1 | 143 | fields*: LISTS.LIST; |
144 | params*: LISTS.LIST; |
||
7597 | akron1 | 145 | unit*: UNIT; |
146 | closed*: BOOLEAN; |
||
147 | num*: INTEGER; |
||
148 | call*: INTEGER; |
||
8097 | maxcodehac | 149 | _import*: BOOLEAN; |
7597 | akron1 | 150 | noalign*: BOOLEAN |
151 | |||
152 | END; |
||
153 | |||
154 | rFIELD = RECORD (LISTS.ITEM) |
||
155 | |||
8097 | maxcodehac | 156 | _type*: _TYPE; |
7597 | akron1 | 157 | name*: SCAN.IDENT; |
158 | export*: BOOLEAN; |
||
159 | offset*: INTEGER |
||
160 | |||
161 | END; |
||
162 | |||
163 | rPARAM = RECORD (LISTS.ITEM) |
||
164 | |||
165 | name*: SCAN.IDENT; |
||
8097 | maxcodehac | 166 | _type*: _TYPE; |
7597 | akron1 | 167 | vPar*: BOOLEAN; |
168 | offset*: INTEGER |
||
169 | |||
170 | END; |
||
171 | |||
172 | rIDENT = RECORD (LISTS.ITEM) |
||
173 | |||
174 | name*: SCAN.IDENT; |
||
175 | typ*: INTEGER; |
||
176 | export*: BOOLEAN; |
||
8097 | maxcodehac | 177 | _import*: LISTS.ITEM; |
7597 | akron1 | 178 | unit*: UNIT; |
179 | value*: ARITH.VALUE; |
||
8097 | maxcodehac | 180 | _type*: _TYPE; |
7597 | akron1 | 181 | stproc*: INTEGER; |
182 | global*: BOOLEAN; |
||
183 | scopeLvl*: INTEGER; |
||
184 | offset*: INTEGER; |
||
185 | proc*: PROC; |
||
186 | pos*: SCAN.POSITION |
||
187 | |||
188 | END; |
||
189 | |||
8097 | maxcodehac | 190 | PROGRAM = RECORD |
7597 | akron1 | 191 | |
192 | recCount: INTEGER; |
||
7693 | akron1 | 193 | units*: LISTS.LIST; |
7597 | akron1 | 194 | types*: LISTS.LIST; |
195 | sysunit*: UNIT; |
||
196 | rtl*: UNIT; |
||
197 | bss*: INTEGER; |
||
198 | locsize*: INTEGER; |
||
199 | |||
200 | procs*: LISTS.LIST; |
||
201 | |||
7983 | leency | 202 | sysflags*: SET; |
203 | options*: OPTIONS; |
||
204 | |||
7693 | akron1 | 205 | stTypes*: RECORD |
7597 | akron1 | 206 | |
7693 | akron1 | 207 | tINTEGER*, tBYTE*, tCHAR*, tWCHAR*, tSET*, tBOOLEAN*, tREAL*, |
8097 | maxcodehac | 208 | tSTRING*, tNIL*, tCARD32*, tANYREC*, tNONE*: _TYPE |
7597 | akron1 | 209 | |
7693 | akron1 | 210 | END |
7597 | akron1 | 211 | |
212 | END; |
||
213 | |||
8097 | maxcodehac | 214 | DELIMPORT = PROCEDURE (_import: LISTS.ITEM); |
7597 | akron1 | 215 | |
216 | |||
217 | VAR |
||
218 | |||
8859 | leency | 219 | LowerCase*: BOOLEAN; |
7597 | akron1 | 220 | idents: C.COLLECTION; |
8097 | maxcodehac | 221 | program*: PROGRAM; |
7597 | akron1 | 222 | |
223 | |||
224 | PROCEDURE NewIdent (): IDENT; |
||
225 | VAR |
||
226 | ident: IDENT; |
||
227 | citem: C.ITEM; |
||
228 | |||
229 | BEGIN |
||
230 | citem := C.pop(idents); |
||
231 | IF citem = NIL THEN |
||
232 | NEW(ident) |
||
233 | ELSE |
||
234 | ident := citem(IDENT) |
||
235 | END |
||
236 | |||
237 | RETURN ident |
||
238 | END NewIdent; |
||
239 | |||
240 | |||
8097 | maxcodehac | 241 | PROCEDURE getOffset* (varIdent: IDENT): INTEGER; |
7597 | akron1 | 242 | VAR |
9893 | akron1 | 243 | size, glob_align: INTEGER; |
7597 | akron1 | 244 | |
245 | BEGIN |
||
246 | IF varIdent.offset = -1 THEN |
||
8097 | maxcodehac | 247 | size := varIdent._type.size; |
7597 | akron1 | 248 | IF varIdent.global THEN |
9893 | akron1 | 249 | IF TARGETS.WinLin THEN |
250 | glob_align := 16 |
||
251 | ELSE |
||
252 | glob_align := varIdent._type.align |
||
253 | END; |
||
254 | IF UTILS.Align(program.bss, glob_align) THEN |
||
7696 | akron1 | 255 | IF UTILS.maxint - program.bss >= size THEN |
7597 | akron1 | 256 | varIdent.offset := program.bss; |
7696 | akron1 | 257 | INC(program.bss, size) |
7597 | akron1 | 258 | END |
259 | END |
||
260 | ELSE |
||
7983 | leency | 261 | IF UTILS.Align(size, TARGETS.WordSize) THEN |
262 | size := size DIV TARGETS.WordSize; |
||
7597 | akron1 | 263 | IF UTILS.maxint - program.locsize >= size THEN |
264 | INC(program.locsize, size); |
||
7696 | akron1 | 265 | varIdent.offset := program.locsize |
7597 | akron1 | 266 | END |
267 | END |
||
7696 | akron1 | 268 | END; |
269 | |||
270 | IF varIdent.offset = -1 THEN |
||
271 | ERRORS.Error(204) |
||
7597 | akron1 | 272 | END |
273 | END |
||
274 | |||
275 | RETURN varIdent.offset |
||
276 | END getOffset; |
||
277 | |||
278 | |||
7693 | akron1 | 279 | PROCEDURE closeUnit* (unit: UNIT); |
7597 | akron1 | 280 | VAR |
281 | ident, prev: IDENT; |
||
282 | offset: INTEGER; |
||
283 | |||
284 | BEGIN |
||
285 | ident := unit.idents.last(IDENT); |
||
286 | WHILE (ident # NIL) & (ident.typ # idGUARD) DO |
||
287 | IF (ident.typ = idVAR) & (ident.offset = -1) THEN |
||
7693 | akron1 | 288 | ERRORS.HintMsg(ident.name.s, ident.pos.line, ident.pos.col, 0); |
7597 | akron1 | 289 | IF ident.export THEN |
8097 | maxcodehac | 290 | offset := getOffset(ident) |
7597 | akron1 | 291 | END |
292 | END; |
||
293 | ident := ident.prev(IDENT) |
||
294 | END; |
||
295 | |||
296 | ident := unit.idents.last(IDENT); |
||
297 | WHILE ident # NIL DO |
||
298 | prev := ident.prev(IDENT); |
||
299 | IF ~ident.export THEN |
||
300 | LISTS.delete(unit.idents, ident); |
||
301 | C.push(idents, ident) |
||
302 | END; |
||
303 | ident := prev |
||
304 | END; |
||
305 | |||
306 | unit.closed := TRUE |
||
7693 | akron1 | 307 | END closeUnit; |
7597 | akron1 | 308 | |
309 | |||
8859 | leency | 310 | PROCEDURE IdEq* (a, b: SCAN.IDENT): BOOLEAN; |
311 | RETURN (a.hash = b.hash) & (a.s = b.s) |
||
312 | END IdEq; |
||
313 | |||
314 | |||
7597 | akron1 | 315 | PROCEDURE unique (unit: UNIT; ident: SCAN.IDENT): BOOLEAN; |
316 | VAR |
||
317 | item: IDENT; |
||
318 | |||
319 | BEGIN |
||
320 | item := unit.idents.last(IDENT); |
||
8859 | leency | 321 | WHILE (item.typ # idGUARD) & ~IdEq(item.name, ident) DO |
7597 | akron1 | 322 | item := item.prev(IDENT) |
323 | END |
||
324 | |||
325 | RETURN item.typ = idGUARD |
||
326 | END unique; |
||
327 | |||
328 | |||
7693 | akron1 | 329 | PROCEDURE addIdent* (unit: UNIT; ident: SCAN.IDENT; typ: INTEGER): IDENT; |
7597 | akron1 | 330 | VAR |
7693 | akron1 | 331 | item: IDENT; |
332 | res: BOOLEAN; |
||
333 | proc: PROC; |
||
7597 | akron1 | 334 | |
335 | BEGIN |
||
336 | ASSERT(unit # NIL); |
||
337 | |||
338 | res := unique(unit, ident); |
||
339 | |||
340 | IF res THEN |
||
341 | item := NewIdent(); |
||
342 | |||
8097 | maxcodehac | 343 | item.name := ident; |
344 | item.typ := typ; |
||
345 | item.unit := NIL; |
||
346 | item.export := FALSE; |
||
347 | item._import := NIL; |
||
348 | item._type := NIL; |
||
7597 | akron1 | 349 | item.value.typ := 0; |
350 | item.stproc := 0; |
||
351 | |||
352 | item.global := unit.scopeLvl = 0; |
||
353 | item.scopeLvl := unit.scopeLvl; |
||
354 | item.offset := -1; |
||
355 | |||
356 | IF item.typ IN {idPROC, idIMP} THEN |
||
357 | NEW(proc); |
||
8097 | maxcodehac | 358 | proc._import := NIL; |
7597 | akron1 | 359 | proc.label := 0; |
360 | proc.used := FALSE; |
||
361 | proc.processed := FALSE; |
||
362 | proc.using := LISTS.create(NIL); |
||
8097 | maxcodehac | 363 | LISTS.push(program.procs, proc); |
7597 | akron1 | 364 | item.proc := proc |
365 | END; |
||
366 | |||
367 | LISTS.push(unit.idents, item) |
||
368 | ELSE |
||
369 | item := NIL |
||
370 | END |
||
371 | |||
372 | RETURN item |
||
373 | END addIdent; |
||
374 | |||
375 | |||
376 | PROCEDURE UseProc* (unit: UNIT; call_proc: PROC); |
||
377 | VAR |
||
7693 | akron1 | 378 | procs: LISTS.LIST; |
379 | cur: LISTS.ITEM; |
||
380 | proc: USED_PROC; |
||
7597 | akron1 | 381 | |
382 | BEGIN |
||
383 | IF unit.scopeLvl = 0 THEN |
||
384 | call_proc.used := TRUE |
||
385 | ELSE |
||
386 | procs := unit.scopes[unit.scopeLvl].using; |
||
387 | |||
388 | cur := procs.first; |
||
389 | WHILE (cur # NIL) & (cur(USED_PROC).proc # call_proc) DO |
||
390 | cur := cur.next |
||
391 | END; |
||
392 | |||
393 | IF cur = NIL THEN |
||
394 | NEW(proc); |
||
395 | proc.proc := call_proc; |
||
396 | LISTS.push(procs, proc) |
||
397 | END |
||
398 | END |
||
399 | END UseProc; |
||
400 | |||
401 | |||
8097 | maxcodehac | 402 | PROCEDURE setVarsType* (unit: UNIT; _type: _TYPE); |
7597 | akron1 | 403 | VAR |
404 | item: IDENT; |
||
405 | |||
406 | BEGIN |
||
8097 | maxcodehac | 407 | ASSERT(_type # NIL); |
7597 | akron1 | 408 | |
409 | item := unit.idents.last(IDENT); |
||
8097 | maxcodehac | 410 | WHILE (item # NIL) & (item.typ = idVAR) & (item._type = NIL) DO |
411 | item._type := _type; |
||
7597 | akron1 | 412 | item := item.prev(IDENT) |
413 | END |
||
7693 | akron1 | 414 | END setVarsType; |
7597 | akron1 | 415 | |
416 | |||
7693 | akron1 | 417 | PROCEDURE getIdent* (unit: UNIT; ident: SCAN.IDENT; currentScope: BOOLEAN): IDENT; |
7597 | akron1 | 418 | VAR |
419 | item: IDENT; |
||
420 | |||
421 | BEGIN |
||
422 | item := unit.idents.last(IDENT); |
||
423 | |||
7693 | akron1 | 424 | IF item # NIL THEN |
7597 | akron1 | 425 | |
7693 | akron1 | 426 | IF currentScope THEN |
8859 | leency | 427 | WHILE (item.typ # idGUARD) & ~IdEq(item.name, ident) DO |
7693 | akron1 | 428 | item := item.prev(IDENT) |
429 | END; |
||
8859 | leency | 430 | IF item.typ = idGUARD THEN |
7693 | akron1 | 431 | item := NIL |
432 | END |
||
433 | ELSE |
||
8859 | leency | 434 | WHILE (item # NIL) & ~IdEq(item.name, ident) DO |
7693 | akron1 | 435 | item := item.prev(IDENT) |
436 | END |
||
7597 | akron1 | 437 | END |
7693 | akron1 | 438 | |
7597 | akron1 | 439 | END |
440 | |||
441 | RETURN item |
||
442 | END getIdent; |
||
443 | |||
444 | |||
7693 | akron1 | 445 | PROCEDURE openScope* (unit: UNIT; proc: PROC): BOOLEAN; |
7597 | akron1 | 446 | VAR |
447 | item: IDENT; |
||
448 | res: BOOLEAN; |
||
449 | |||
450 | BEGIN |
||
451 | INC(unit.scopeLvl); |
||
452 | |||
453 | res := unit.scopeLvl < MAXSCOPE; |
||
454 | |||
455 | IF res THEN |
||
456 | |||
457 | unit.scopes[unit.scopeLvl] := proc; |
||
458 | |||
459 | NEW(item); |
||
460 | item := NewIdent(); |
||
461 | |||
8859 | leency | 462 | item.name.s := ""; |
463 | item.name.hash := 0; |
||
7597 | akron1 | 464 | item.typ := idGUARD; |
465 | |||
466 | LISTS.push(unit.idents, item) |
||
467 | END |
||
468 | |||
469 | RETURN res |
||
470 | END openScope; |
||
471 | |||
472 | |||
8859 | leency | 473 | PROCEDURE closeScope* (unit: UNIT); |
7597 | akron1 | 474 | VAR |
475 | item: IDENT; |
||
476 | del: IDENT; |
||
477 | |||
478 | BEGIN |
||
479 | item := unit.idents.last(IDENT); |
||
480 | |||
481 | WHILE (item # NIL) & (item.typ # idGUARD) DO |
||
482 | del := item; |
||
483 | item := item.prev(IDENT); |
||
484 | IF (del.typ = idVAR) & (del.offset = -1) THEN |
||
7693 | akron1 | 485 | ERRORS.HintMsg(del.name.s, del.pos.line, del.pos.col, 0) |
7597 | akron1 | 486 | END; |
487 | LISTS.delete(unit.idents, del); |
||
488 | C.push(idents, del) |
||
489 | END; |
||
490 | |||
491 | IF (item # NIL) & (item.typ = idGUARD) THEN |
||
492 | LISTS.delete(unit.idents, item); |
||
493 | C.push(idents, item) |
||
494 | END; |
||
495 | |||
496 | DEC(unit.scopeLvl) |
||
497 | END closeScope; |
||
498 | |||
499 | |||
8097 | maxcodehac | 500 | PROCEDURE frwPtr* (unit: UNIT; _type: _TYPE; baseIdent: SCAN.IDENT; pos: SCAN.POSITION); |
7597 | akron1 | 501 | VAR |
502 | newptr: FRWPTR; |
||
503 | |||
504 | BEGIN |
||
505 | ASSERT(unit # NIL); |
||
8097 | maxcodehac | 506 | ASSERT(_type # NIL); |
7597 | akron1 | 507 | |
508 | NEW(newptr); |
||
509 | |||
8097 | maxcodehac | 510 | newptr._type := _type; |
7693 | akron1 | 511 | newptr.baseIdent := baseIdent; |
512 | newptr.pos := pos; |
||
513 | newptr.linked := FALSE; |
||
514 | newptr.notRecord := FALSE; |
||
7597 | akron1 | 515 | |
516 | LISTS.push(unit.frwPointers, newptr) |
||
7693 | akron1 | 517 | END frwPtr; |
7597 | akron1 | 518 | |
519 | |||
7693 | akron1 | 520 | PROCEDURE linkPtr* (unit: UNIT): FRWPTR; |
7597 | akron1 | 521 | VAR |
522 | item: FRWPTR; |
||
523 | ident: IDENT; |
||
524 | res: FRWPTR; |
||
525 | |||
526 | BEGIN |
||
527 | res := NIL; |
||
528 | item := unit.frwPointers.last(FRWPTR); |
||
529 | |||
530 | WHILE (item # NIL) & ~item.linked & (res = NIL) DO |
||
7693 | akron1 | 531 | ident := getIdent(unit, item.baseIdent, TRUE); |
7597 | akron1 | 532 | |
533 | IF (ident # NIL) THEN |
||
8097 | maxcodehac | 534 | IF (ident.typ = idTYPE) & (ident._type.typ = tRECORD) THEN |
535 | item._type.base := ident._type; |
||
7597 | akron1 | 536 | item.linked := TRUE |
537 | ELSE |
||
538 | item.notRecord := TRUE; |
||
539 | res := item |
||
540 | END |
||
541 | ELSE |
||
542 | item.notRecord := FALSE; |
||
543 | res := item |
||
544 | END; |
||
545 | |||
546 | item := item.prev(FRWPTR) |
||
547 | END |
||
548 | |||
549 | RETURN res |
||
7693 | akron1 | 550 | END linkPtr; |
7597 | akron1 | 551 | |
552 | |||
8097 | maxcodehac | 553 | PROCEDURE isTypeEq* (t1, t2: _TYPE): BOOLEAN; |
7597 | akron1 | 554 | VAR |
555 | res: BOOLEAN; |
||
556 | param1, param2: LISTS.ITEM; |
||
557 | |||
558 | BEGIN |
||
559 | IF t1 = t2 THEN |
||
560 | res := TRUE |
||
561 | ELSIF (t1 = NIL) OR (t2 = NIL) THEN |
||
562 | res := FALSE |
||
563 | ELSIF (t1.typ = tPROCEDURE) & (t2.typ = tPROCEDURE) THEN |
||
564 | |||
565 | param1 := t1.params.first; |
||
566 | param2 := t2.params.first; |
||
567 | |||
7693 | akron1 | 568 | res := ((t1.call = t2.call) OR (t1.call IN {code, _code}) OR (t2.call IN {code, _code})) & ((param1 # NIL) = (param2 # NIL)); |
7597 | akron1 | 569 | |
570 | WHILE res & (param1 # NIL) & (param2 # NIL) DO |
||
8097 | maxcodehac | 571 | res := (param1(PARAM).vPar = param2(PARAM).vPar) & isTypeEq(param1(PARAM)._type, param2(PARAM)._type); |
7597 | akron1 | 572 | param1 := param1.next; |
573 | param2 := param2.next; |
||
574 | res := res & ((param1 # NIL) = (param2 # NIL)) |
||
575 | END; |
||
576 | |||
577 | res := res & isTypeEq(t1.base, t2.base) |
||
578 | |||
579 | ELSIF (t1.typ = tARRAY) & (t2.typ = tARRAY) THEN |
||
580 | res := (t1.length = 0) & (t2.length = 0) & isTypeEq(t1.base, t2.base) |
||
581 | ELSE |
||
582 | res := FALSE |
||
583 | END |
||
584 | |||
585 | RETURN res |
||
586 | END isTypeEq; |
||
587 | |||
588 | |||
8097 | maxcodehac | 589 | PROCEDURE isBaseOf* (t0, t1: _TYPE): BOOLEAN; |
7597 | akron1 | 590 | VAR |
591 | res: BOOLEAN; |
||
592 | |||
593 | BEGIN |
||
7693 | akron1 | 594 | res := (t0.typ = t1.typ) & (t0.typ IN {tPOINTER, tRECORD}); |
7597 | akron1 | 595 | |
7693 | akron1 | 596 | IF res & (t0.typ = tPOINTER) THEN |
7597 | akron1 | 597 | t0 := t0.base; |
598 | t1 := t1.base |
||
599 | END; |
||
600 | |||
7693 | akron1 | 601 | IF res THEN |
602 | WHILE (t1 # NIL) & (t1 # t0) DO |
||
603 | t1 := t1.base |
||
604 | END; |
||
605 | res := t1 # NIL |
||
7597 | akron1 | 606 | END |
607 | |||
7693 | akron1 | 608 | RETURN res |
7597 | akron1 | 609 | END isBaseOf; |
610 | |||
611 | |||
8097 | maxcodehac | 612 | PROCEDURE isOpenArray* (t: _TYPE): BOOLEAN; |
7597 | akron1 | 613 | RETURN (t.typ = tARRAY) & (t.length = 0) |
614 | END isOpenArray; |
||
615 | |||
616 | |||
8097 | maxcodehac | 617 | PROCEDURE arrcomp* (src, dst: _TYPE): BOOLEAN; |
7696 | akron1 | 618 | RETURN (dst.typ = tARRAY) & isOpenArray(src) & |
619 | ~isOpenArray(src.base) & ~isOpenArray(dst.base) & |
||
620 | isTypeEq(src.base, dst.base) |
||
621 | END arrcomp; |
||
622 | |||
623 | |||
8859 | leency | 624 | PROCEDURE getUnit* (name: PATHS.PATH): UNIT; |
7597 | akron1 | 625 | VAR |
626 | item: UNIT; |
||
627 | |||
628 | BEGIN |
||
7693 | akron1 | 629 | item := program.units.first(UNIT); |
7597 | akron1 | 630 | |
8859 | leency | 631 | WHILE (item # NIL) & (item.fname # name) DO |
7597 | akron1 | 632 | item := item.next(UNIT) |
633 | END; |
||
634 | |||
8859 | leency | 635 | IF (item = NIL) & ((name = "SYSTEM") OR LowerCase & (name = "system")) THEN |
7693 | akron1 | 636 | item := program.sysunit |
7597 | akron1 | 637 | END |
638 | |||
639 | RETURN item |
||
7693 | akron1 | 640 | END getUnit; |
7597 | akron1 | 641 | |
642 | |||
8097 | maxcodehac | 643 | PROCEDURE enterStTypes (unit: UNIT); |
7597 | akron1 | 644 | |
645 | |||
8859 | leency | 646 | PROCEDURE enter (unit: UNIT; nameStr: SCAN.IDSTR; _type: _TYPE); |
8097 | maxcodehac | 647 | VAR |
648 | ident: IDENT; |
||
8859 | leency | 649 | upper: SCAN.IDSTR; |
650 | name: SCAN.IDENT; |
||
7597 | akron1 | 651 | |
8097 | maxcodehac | 652 | BEGIN |
653 | IF LowerCase THEN |
||
8859 | leency | 654 | SCAN.setIdent(name, nameStr); |
655 | ident := addIdent(unit, name, idTYPE); |
||
8097 | maxcodehac | 656 | ident._type := _type |
657 | END; |
||
8859 | leency | 658 | upper := nameStr; |
8097 | maxcodehac | 659 | STRINGS.UpCase(upper); |
8859 | leency | 660 | SCAN.setIdent(name, upper); |
661 | ident := addIdent(unit, name, idTYPE); |
||
8097 | maxcodehac | 662 | ident._type := _type |
663 | END enter; |
||
7597 | akron1 | 664 | |
665 | |||
8097 | maxcodehac | 666 | BEGIN |
667 | enter(unit, "integer", program.stTypes.tINTEGER); |
||
668 | enter(unit, "byte", program.stTypes.tBYTE); |
||
669 | enter(unit, "char", program.stTypes.tCHAR); |
||
670 | enter(unit, "set", program.stTypes.tSET); |
||
671 | enter(unit, "boolean", program.stTypes.tBOOLEAN); |
||
7597 | akron1 | 672 | |
7983 | leency | 673 | IF TARGETS.RealSize # 0 THEN |
8097 | maxcodehac | 674 | enter(unit, "real", program.stTypes.tREAL) |
7983 | leency | 675 | END; |
7597 | akron1 | 676 | |
7983 | leency | 677 | IF TARGETS.BitDepth >= 32 THEN |
8097 | maxcodehac | 678 | enter(unit, "wchar", program.stTypes.tWCHAR) |
7693 | akron1 | 679 | END |
7597 | akron1 | 680 | END enterStTypes; |
681 | |||
682 | |||
683 | PROCEDURE enterStProcs (unit: UNIT); |
||
684 | |||
685 | |||
8859 | leency | 686 | PROCEDURE Enter (unit: UNIT; nameStr: SCAN.IDSTR; nfunc, tfunc: INTEGER); |
7597 | akron1 | 687 | VAR |
688 | ident: IDENT; |
||
8859 | leency | 689 | upper: SCAN.IDSTR; |
690 | name: SCAN.IDENT; |
||
8097 | maxcodehac | 691 | |
7597 | akron1 | 692 | BEGIN |
8097 | maxcodehac | 693 | IF LowerCase THEN |
8859 | leency | 694 | SCAN.setIdent(name, nameStr); |
695 | ident := addIdent(unit, name, tfunc); |
||
696 | ident.stproc := nfunc; |
||
8097 | maxcodehac | 697 | ident._type := program.stTypes.tNONE |
698 | END; |
||
8859 | leency | 699 | upper := nameStr; |
8097 | maxcodehac | 700 | STRINGS.UpCase(upper); |
8859 | leency | 701 | SCAN.setIdent(name, upper); |
702 | ident := addIdent(unit, name, tfunc); |
||
703 | ident.stproc := nfunc; |
||
8097 | maxcodehac | 704 | ident._type := program.stTypes.tNONE |
8859 | leency | 705 | END Enter; |
7597 | akron1 | 706 | |
707 | |||
708 | BEGIN |
||
8859 | leency | 709 | Enter(unit, "assert", stASSERT, idSTPROC); |
710 | Enter(unit, "dec", stDEC, idSTPROC); |
||
711 | Enter(unit, "excl", stEXCL, idSTPROC); |
||
712 | Enter(unit, "inc", stINC, idSTPROC); |
||
713 | Enter(unit, "incl", stINCL, idSTPROC); |
||
714 | Enter(unit, "new", stNEW, idSTPROC); |
||
715 | Enter(unit, "copy", stCOPY, idSTPROC); |
||
7597 | akron1 | 716 | |
8859 | leency | 717 | Enter(unit, "abs", stABS, idSTFUNC); |
718 | Enter(unit, "asr", stASR, idSTFUNC); |
||
719 | Enter(unit, "chr", stCHR, idSTFUNC); |
||
720 | Enter(unit, "len", stLEN, idSTFUNC); |
||
721 | Enter(unit, "lsl", stLSL, idSTFUNC); |
||
722 | Enter(unit, "odd", stODD, idSTFUNC); |
||
723 | Enter(unit, "ord", stORD, idSTFUNC); |
||
724 | Enter(unit, "ror", stROR, idSTFUNC); |
||
725 | Enter(unit, "bits", stBITS, idSTFUNC); |
||
726 | Enter(unit, "lsr", stLSR, idSTFUNC); |
||
727 | Enter(unit, "length", stLENGTH, idSTFUNC); |
||
728 | Enter(unit, "min", stMIN, idSTFUNC); |
||
729 | Enter(unit, "max", stMAX, idSTFUNC); |
||
7693 | akron1 | 730 | |
7983 | leency | 731 | IF TARGETS.RealSize # 0 THEN |
8859 | leency | 732 | Enter(unit, "pack", stPACK, idSTPROC); |
733 | Enter(unit, "unpk", stUNPK, idSTPROC); |
||
734 | Enter(unit, "floor", stFLOOR, idSTFUNC); |
||
735 | Enter(unit, "flt", stFLT, idSTFUNC) |
||
7983 | leency | 736 | END; |
7693 | akron1 | 737 | |
7983 | leency | 738 | IF TARGETS.BitDepth >= 32 THEN |
8859 | leency | 739 | Enter(unit, "wchr", stWCHR, idSTFUNC) |
7983 | leency | 740 | END; |
741 | |||
742 | IF TARGETS.Dispose THEN |
||
8859 | leency | 743 | Enter(unit, "dispose", stDISPOSE, idSTPROC) |
7693 | akron1 | 744 | END |
745 | |||
7597 | akron1 | 746 | END enterStProcs; |
747 | |||
748 | |||
8097 | maxcodehac | 749 | PROCEDURE newUnit* (name: SCAN.IDENT): UNIT; |
7597 | akron1 | 750 | VAR |
7693 | akron1 | 751 | unit: UNIT; |
7597 | akron1 | 752 | |
753 | BEGIN |
||
754 | NEW(unit); |
||
755 | |||
756 | unit.name := name; |
||
757 | unit.closed := FALSE; |
||
7693 | akron1 | 758 | unit.idents := LISTS.create(NIL); |
7597 | akron1 | 759 | unit.frwPointers := LISTS.create(NIL); |
760 | |||
7693 | akron1 | 761 | ASSERT(openScope(unit, NIL)); |
7597 | akron1 | 762 | |
8097 | maxcodehac | 763 | enterStTypes(unit); |
7597 | akron1 | 764 | enterStProcs(unit); |
765 | |||
7693 | akron1 | 766 | ASSERT(openScope(unit, NIL)); |
7597 | akron1 | 767 | |
768 | unit.gscope := unit.idents.last(IDENT); |
||
769 | |||
7693 | akron1 | 770 | LISTS.push(program.units, unit); |
7597 | akron1 | 771 | |
772 | unit.scopeLvl := 0; |
||
773 | unit.scopes[0] := NIL; |
||
774 | |||
775 | unit.sysimport := FALSE; |
||
776 | |||
7983 | leency | 777 | IF unit.name.s = UTILS.RTL_NAME THEN |
7693 | akron1 | 778 | program.rtl := unit |
7597 | akron1 | 779 | END |
780 | |||
781 | RETURN unit |
||
7693 | akron1 | 782 | END newUnit; |
7597 | akron1 | 783 | |
784 | |||
8097 | maxcodehac | 785 | PROCEDURE getField* (self: _TYPE; name: SCAN.IDENT; unit: UNIT): FIELD; |
7597 | akron1 | 786 | VAR |
7693 | akron1 | 787 | field: FIELD; |
7597 | akron1 | 788 | |
789 | BEGIN |
||
790 | ASSERT(self # NIL); |
||
791 | ASSERT(unit # NIL); |
||
792 | |||
793 | field := NIL; |
||
794 | WHILE (self # NIL) & (field = NIL) DO |
||
795 | |||
796 | field := self.fields.first(FIELD); |
||
797 | |||
8859 | leency | 798 | WHILE (field # NIL) & ~IdEq(field.name, name) DO |
7597 | akron1 | 799 | field := field.next(FIELD) |
800 | END; |
||
801 | |||
802 | IF field = NIL THEN |
||
803 | self := self.base |
||
804 | END |
||
805 | |||
806 | END; |
||
807 | |||
808 | IF (field # NIL) & (self.unit # unit) & ~field.export THEN |
||
809 | field := NIL |
||
810 | END |
||
811 | |||
812 | RETURN field |
||
813 | END getField; |
||
814 | |||
815 | |||
8097 | maxcodehac | 816 | PROCEDURE addField* (self: _TYPE; name: SCAN.IDENT; export: BOOLEAN): BOOLEAN; |
7597 | akron1 | 817 | VAR |
7693 | akron1 | 818 | field: FIELD; |
819 | res: BOOLEAN; |
||
7597 | akron1 | 820 | |
821 | BEGIN |
||
822 | res := getField(self, name, self.unit) = NIL; |
||
823 | |||
824 | IF res THEN |
||
825 | NEW(field); |
||
826 | |||
827 | field.name := name; |
||
828 | field.export := export; |
||
8097 | maxcodehac | 829 | field._type := NIL; |
7597 | akron1 | 830 | field.offset := self.size; |
831 | |||
832 | LISTS.push(self.fields, field) |
||
833 | END |
||
834 | |||
835 | RETURN res |
||
836 | END addField; |
||
837 | |||
838 | |||
8097 | maxcodehac | 839 | PROCEDURE setFields* (self: _TYPE; _type: _TYPE): BOOLEAN; |
7597 | akron1 | 840 | VAR |
841 | item: FIELD; |
||
842 | res: BOOLEAN; |
||
843 | |||
844 | BEGIN |
||
8097 | maxcodehac | 845 | ASSERT(_type # NIL); |
7597 | akron1 | 846 | |
847 | item := self.fields.first(FIELD); |
||
848 | |||
8097 | maxcodehac | 849 | WHILE (item # NIL) & (item._type # NIL) DO |
7597 | akron1 | 850 | item := item.next(FIELD) |
851 | END; |
||
852 | |||
853 | res := TRUE; |
||
854 | |||
8097 | maxcodehac | 855 | WHILE res & (item # NIL) & (item._type = NIL) DO |
856 | item._type := _type; |
||
7597 | akron1 | 857 | IF ~self.noalign THEN |
8097 | maxcodehac | 858 | res := UTILS.Align(self.size, _type.align) |
7597 | akron1 | 859 | ELSE |
860 | res := TRUE |
||
861 | END; |
||
862 | item.offset := self.size; |
||
8097 | maxcodehac | 863 | res := res & (UTILS.maxint - self.size >= _type.size); |
7597 | akron1 | 864 | IF res THEN |
8097 | maxcodehac | 865 | INC(self.size, _type.size) |
7597 | akron1 | 866 | END; |
867 | item := item.next(FIELD) |
||
868 | END |
||
869 | |||
870 | RETURN res |
||
871 | END setFields; |
||
872 | |||
873 | |||
8097 | maxcodehac | 874 | PROCEDURE getParam* (self: _TYPE; name: SCAN.IDENT): PARAM; |
7597 | akron1 | 875 | VAR |
7693 | akron1 | 876 | item: PARAM; |
7597 | akron1 | 877 | |
878 | BEGIN |
||
879 | item := self.params.first(PARAM); |
||
880 | |||
8859 | leency | 881 | WHILE (item # NIL) & ~IdEq(item.name, name) DO |
7597 | akron1 | 882 | item := item.next(PARAM) |
883 | END |
||
884 | |||
885 | RETURN item |
||
886 | END getParam; |
||
887 | |||
888 | |||
8097 | maxcodehac | 889 | PROCEDURE addParam* (self: _TYPE; name: SCAN.IDENT; vPar: BOOLEAN): BOOLEAN; |
7597 | akron1 | 890 | VAR |
7693 | akron1 | 891 | param: PARAM; |
892 | res: BOOLEAN; |
||
7597 | akron1 | 893 | |
894 | BEGIN |
||
7693 | akron1 | 895 | res := getParam(self, name) = NIL; |
7597 | akron1 | 896 | |
897 | IF res THEN |
||
898 | NEW(param); |
||
899 | |||
8097 | maxcodehac | 900 | param.name := name; |
901 | param._type := NIL; |
||
902 | param.vPar := vPar; |
||
7597 | akron1 | 903 | |
904 | LISTS.push(self.params, param) |
||
905 | END |
||
906 | |||
907 | RETURN res |
||
908 | END addParam; |
||
909 | |||
910 | |||
8097 | maxcodehac | 911 | PROCEDURE Dim* (t: _TYPE): INTEGER; |
7597 | akron1 | 912 | VAR |
913 | res: INTEGER; |
||
914 | |||
915 | BEGIN |
||
916 | res := 0; |
||
917 | WHILE isOpenArray(t) DO |
||
918 | t := t.base; |
||
919 | INC(res) |
||
920 | END |
||
921 | RETURN res |
||
922 | END Dim; |
||
923 | |||
924 | |||
8097 | maxcodehac | 925 | PROCEDURE OpenBase* (t: _TYPE): _TYPE; |
7597 | akron1 | 926 | BEGIN |
927 | WHILE isOpenArray(t) DO t := t.base END |
||
928 | RETURN t |
||
929 | END OpenBase; |
||
930 | |||
931 | |||
8097 | maxcodehac | 932 | PROCEDURE getFloatParamsPos* (self: _TYPE; maxoffs: INTEGER; VAR int, flt: INTEGER): SET; |
7597 | akron1 | 933 | VAR |
934 | res: SET; |
||
935 | param: PARAM; |
||
936 | |||
937 | BEGIN |
||
938 | res := {}; |
||
939 | int := 0; |
||
940 | flt := 0; |
||
941 | param := self.params.first(PARAM); |
||
942 | WHILE (param # NIL) & (param.offset <= maxoffs + STACK_FRAME) DO |
||
8097 | maxcodehac | 943 | IF ~param.vPar & (param._type.typ = tREAL) THEN |
7597 | akron1 | 944 | INCL(res, param.offset - STACK_FRAME); |
945 | INC(flt) |
||
946 | END; |
||
947 | param := param.next(PARAM) |
||
948 | END; |
||
949 | |||
7693 | akron1 | 950 | int := self.parSize - flt |
7597 | akron1 | 951 | |
952 | RETURN res |
||
953 | END getFloatParamsPos; |
||
954 | |||
955 | |||
8097 | maxcodehac | 956 | PROCEDURE setParams* (self: _TYPE; _type: _TYPE); |
7597 | akron1 | 957 | VAR |
958 | item: LISTS.ITEM; |
||
959 | param: PARAM; |
||
960 | word, size: INTEGER; |
||
961 | |||
962 | BEGIN |
||
8097 | maxcodehac | 963 | ASSERT(_type # NIL); |
7597 | akron1 | 964 | |
7693 | akron1 | 965 | word := UTILS.target.bit_depth DIV 8; |
7597 | akron1 | 966 | |
967 | item := self.params.first; |
||
968 | |||
8097 | maxcodehac | 969 | WHILE (item # NIL) & (item(PARAM)._type # NIL) DO |
7597 | akron1 | 970 | item := item.next |
971 | END; |
||
972 | |||
8097 | maxcodehac | 973 | WHILE (item # NIL) & (item(PARAM)._type = NIL) DO |
7597 | akron1 | 974 | param := item(PARAM); |
8097 | maxcodehac | 975 | param._type := _type; |
7597 | akron1 | 976 | IF param.vPar THEN |
8097 | maxcodehac | 977 | IF _type.typ = tRECORD THEN |
7597 | akron1 | 978 | size := 2 |
8097 | maxcodehac | 979 | ELSIF isOpenArray(_type) THEN |
980 | size := Dim(_type) + 1 |
||
7597 | akron1 | 981 | ELSE |
982 | size := 1 |
||
983 | END; |
||
8097 | maxcodehac | 984 | param.offset := self.parSize + ORD(_type.typ = tRECORD) + Dim(_type) + STACK_FRAME; |
7693 | akron1 | 985 | INC(self.parSize, size) |
7597 | akron1 | 986 | ELSE |
8097 | maxcodehac | 987 | IF _type.typ IN {tRECORD, tARRAY} THEN |
988 | IF isOpenArray(_type) THEN |
||
989 | size := Dim(_type) + 1 |
||
7597 | akron1 | 990 | ELSE |
991 | size := 1 |
||
992 | END |
||
993 | ELSE |
||
8097 | maxcodehac | 994 | size := _type.size; |
7693 | akron1 | 995 | ASSERT(UTILS.Align(size, word)); |
7597 | akron1 | 996 | size := size DIV word |
997 | END; |
||
8097 | maxcodehac | 998 | param.offset := self.parSize + Dim(_type) + STACK_FRAME; |
7693 | akron1 | 999 | INC(self.parSize, size) |
7597 | akron1 | 1000 | END; |
1001 | |||
1002 | item := item.next |
||
1003 | END |
||
1004 | |||
1005 | END setParams; |
||
1006 | |||
1007 | |||
8097 | maxcodehac | 1008 | PROCEDURE enterType* (typ, size, length: INTEGER; unit: UNIT): _TYPE; |
7597 | akron1 | 1009 | VAR |
8097 | maxcodehac | 1010 | t: _TYPE; |
7597 | akron1 | 1011 | |
1012 | BEGIN |
||
1013 | NEW(t); |
||
1014 | |||
1015 | t.typ := typ; |
||
1016 | t.size := size; |
||
1017 | t.length := length; |
||
1018 | t.align := 0; |
||
1019 | t.base := NIL; |
||
7693 | akron1 | 1020 | t.fields := LISTS.create(NIL); |
1021 | t.params := LISTS.create(NIL); |
||
7597 | akron1 | 1022 | t.unit := unit; |
1023 | t.num := 0; |
||
7693 | akron1 | 1024 | |
7983 | leency | 1025 | CASE TARGETS.BitDepth OF |
7693 | akron1 | 1026 | |16: t.call := default16 |
1027 | |32: t.call := default32 |
||
1028 | |64: t.call := default64 |
||
7597 | akron1 | 1029 | END; |
7693 | akron1 | 1030 | |
8097 | maxcodehac | 1031 | t._import := FALSE; |
7597 | akron1 | 1032 | t.noalign := FALSE; |
7693 | akron1 | 1033 | t.parSize := 0; |
7597 | akron1 | 1034 | |
1035 | IF typ IN {tARRAY, tRECORD} THEN |
||
1036 | t.closed := FALSE; |
||
1037 | IF typ = tRECORD THEN |
||
1038 | INC(program.recCount); |
||
1039 | t.num := program.recCount |
||
1040 | END |
||
1041 | ELSE |
||
1042 | t.closed := TRUE |
||
1043 | END; |
||
1044 | |||
1045 | LISTS.push(program.types, t) |
||
1046 | |||
1047 | RETURN t |
||
1048 | END enterType; |
||
1049 | |||
1050 | |||
8097 | maxcodehac | 1051 | PROCEDURE getType* (typ: INTEGER): _TYPE; |
7597 | akron1 | 1052 | VAR |
8097 | maxcodehac | 1053 | res: _TYPE; |
7597 | akron1 | 1054 | |
1055 | BEGIN |
||
1056 | |||
7696 | akron1 | 1057 | CASE typ OF |
1058 | |ARITH.tINTEGER: res := program.stTypes.tINTEGER |
||
1059 | |ARITH.tREAL: res := program.stTypes.tREAL |
||
1060 | |ARITH.tSET: res := program.stTypes.tSET |
||
1061 | |ARITH.tBOOLEAN: res := program.stTypes.tBOOLEAN |
||
1062 | |ARITH.tCHAR: res := program.stTypes.tCHAR |
||
1063 | |ARITH.tWCHAR: res := program.stTypes.tWCHAR |
||
1064 | |ARITH.tSTRING: res := program.stTypes.tSTRING |
||
1065 | END |
||
7597 | akron1 | 1066 | |
1067 | RETURN res |
||
1068 | END getType; |
||
1069 | |||
1070 | |||
8097 | maxcodehac | 1071 | PROCEDURE createSysUnit; |
7597 | akron1 | 1072 | VAR |
1073 | ident: IDENT; |
||
1074 | unit: UNIT; |
||
8859 | leency | 1075 | name: SCAN.IDENT; |
7597 | akron1 | 1076 | |
1077 | |||
8859 | leency | 1078 | PROCEDURE EnterProc (sys: UNIT; nameStr: SCAN.IDSTR; idtyp, proc: INTEGER); |
7597 | akron1 | 1079 | VAR |
1080 | ident: IDENT; |
||
8859 | leency | 1081 | upper: SCAN.IDSTR; |
1082 | name: SCAN.IDENT; |
||
8097 | maxcodehac | 1083 | |
7597 | akron1 | 1084 | BEGIN |
8097 | maxcodehac | 1085 | IF LowerCase THEN |
8859 | leency | 1086 | SCAN.setIdent(name, nameStr); |
1087 | ident := addIdent(sys, name, idtyp); |
||
8097 | maxcodehac | 1088 | ident.stproc := proc; |
1089 | ident._type := program.stTypes.tNONE; |
||
1090 | ident.export := TRUE |
||
1091 | END; |
||
8859 | leency | 1092 | upper := nameStr; |
8097 | maxcodehac | 1093 | STRINGS.UpCase(upper); |
8859 | leency | 1094 | SCAN.setIdent(name, upper); |
1095 | ident := addIdent(sys, name, idtyp); |
||
7597 | akron1 | 1096 | ident.stproc := proc; |
8097 | maxcodehac | 1097 | ident._type := program.stTypes.tNONE; |
7597 | akron1 | 1098 | ident.export := TRUE |
1099 | END EnterProc; |
||
1100 | |||
1101 | |||
1102 | BEGIN |
||
8859 | leency | 1103 | SCAN.setIdent(name, "$SYSTEM"); |
1104 | unit := newUnit(name); |
||
1105 | unit.fname := "SYSTEM"; |
||
7597 | akron1 | 1106 | |
8097 | maxcodehac | 1107 | EnterProc(unit, "adr", idSYSFUNC, sysADR); |
1108 | EnterProc(unit, "size", idSYSFUNC, sysSIZE); |
||
1109 | EnterProc(unit, "sadr", idSYSFUNC, sysSADR); |
||
1110 | EnterProc(unit, "typeid", idSYSFUNC, sysTYPEID); |
||
7597 | akron1 | 1111 | |
8097 | maxcodehac | 1112 | EnterProc(unit, "get", idSYSPROC, sysGET); |
1113 | EnterProc(unit, "get8", idSYSPROC, sysGET8); |
||
1114 | EnterProc(unit, "put", idSYSPROC, sysPUT); |
||
1115 | EnterProc(unit, "put8", idSYSPROC, sysPUT8); |
||
1116 | EnterProc(unit, "code", idSYSPROC, sysCODE); |
||
1117 | EnterProc(unit, "move", idSYSPROC, sysMOVE); |
||
9893 | akron1 | 1118 | EnterProc(unit, "val", idSYSPROC, sysVAL); |
7693 | akron1 | 1119 | (* |
1120 | IF program.target.sys = mConst.Target_iMSP430 THEN |
||
8097 | maxcodehac | 1121 | EnterProc(unit, "nop", idSYSPROC, sysNOP); |
1122 | EnterProc(unit, "eint", idSYSPROC, sysEINT); |
||
1123 | EnterProc(unit, "dint", idSYSPROC, sysDINT) |
||
7693 | akron1 | 1124 | END; |
1125 | *) |
||
7983 | leency | 1126 | IF TARGETS.RealSize # 0 THEN |
8097 | maxcodehac | 1127 | EnterProc(unit, "inf", idSYSFUNC, sysINF); |
7983 | leency | 1128 | END; |
1129 | |||
1130 | IF TARGETS.CPU IN {TARGETS.cpuX86, TARGETS.cpuAMD64} THEN |
||
8097 | maxcodehac | 1131 | EnterProc(unit, "copy", idSYSPROC, sysCOPY) |
7983 | leency | 1132 | END; |
1133 | |||
1134 | IF TARGETS.BitDepth >= 32 THEN |
||
8097 | maxcodehac | 1135 | EnterProc(unit, "wsadr", idSYSFUNC, sysWSADR); |
1136 | EnterProc(unit, "put16", idSYSPROC, sysPUT16); |
||
1137 | EnterProc(unit, "put32", idSYSPROC, sysPUT32); |
||
1138 | EnterProc(unit, "get16", idSYSPROC, sysGET16); |
||
1139 | EnterProc(unit, "get32", idSYSPROC, sysGET32); |
||
7597 | akron1 | 1140 | |
8097 | maxcodehac | 1141 | IF LowerCase THEN |
8859 | leency | 1142 | SCAN.setIdent(name, "card32"); |
1143 | ident := addIdent(unit, name, idTYPE); |
||
8097 | maxcodehac | 1144 | ident._type := program.stTypes.tCARD32; |
1145 | ident.export := TRUE |
||
1146 | END; |
||
8859 | leency | 1147 | SCAN.setIdent(name, "CARD32"); |
1148 | ident := addIdent(unit, name, idTYPE); |
||
8097 | maxcodehac | 1149 | ident._type := program.stTypes.tCARD32; |
1150 | ident.export := TRUE; |
||
7693 | akron1 | 1151 | END; |
7597 | akron1 | 1152 | |
7693 | akron1 | 1153 | closeUnit(unit); |
7597 | akron1 | 1154 | |
1155 | program.sysunit := unit |
||
1156 | END createSysUnit; |
||
1157 | |||
1158 | |||
8097 | maxcodehac | 1159 | PROCEDURE DelUnused* (DelImport: DELIMPORT); |
7597 | akron1 | 1160 | VAR |
7693 | akron1 | 1161 | proc: PROC; |
1162 | flag: BOOLEAN; |
||
7597 | akron1 | 1163 | |
1164 | |||
1165 | PROCEDURE process (proc: PROC); |
||
1166 | VAR |
||
1167 | used_proc: LISTS.ITEM; |
||
1168 | |||
1169 | BEGIN |
||
1170 | proc.processed := TRUE; |
||
1171 | |||
1172 | used_proc := proc.using.first; |
||
1173 | WHILE used_proc # NIL DO |
||
1174 | used_proc(USED_PROC).proc.used := TRUE; |
||
1175 | used_proc := used_proc.next |
||
1176 | END |
||
1177 | |||
1178 | END process; |
||
1179 | |||
1180 | |||
1181 | BEGIN |
||
1182 | |||
1183 | REPEAT |
||
1184 | flag := FALSE; |
||
1185 | proc := program.procs.first(PROC); |
||
1186 | |||
1187 | WHILE proc # NIL DO |
||
1188 | IF proc.used & ~proc.processed THEN |
||
1189 | process(proc); |
||
1190 | flag := TRUE |
||
1191 | END; |
||
1192 | proc := proc.next(PROC) |
||
1193 | END |
||
1194 | |||
1195 | UNTIL ~flag; |
||
1196 | |||
1197 | proc := program.procs.first(PROC); |
||
1198 | |||
1199 | WHILE proc # NIL DO |
||
1200 | IF ~proc.used THEN |
||
8097 | maxcodehac | 1201 | IF proc._import = NIL THEN |
7693 | akron1 | 1202 | IL.delete2(proc.enter, proc.leave) |
7597 | akron1 | 1203 | ELSE |
8097 | maxcodehac | 1204 | DelImport(proc._import) |
7597 | akron1 | 1205 | END |
1206 | END; |
||
1207 | proc := proc.next(PROC) |
||
1208 | END |
||
1209 | |||
1210 | END DelUnused; |
||
1211 | |||
1212 | |||
8097 | maxcodehac | 1213 | PROCEDURE ResetLocSize*; |
1214 | BEGIN |
||
1215 | program.locsize := 0 |
||
1216 | END ResetLocSize; |
||
7597 | akron1 | 1217 | |
8097 | maxcodehac | 1218 | |
1219 | PROCEDURE create* (options: OPTIONS); |
||
7597 | akron1 | 1220 | BEGIN |
8097 | maxcodehac | 1221 | LowerCase := options.lower; |
1222 | SCAN.init(options.lower); |
||
7597 | akron1 | 1223 | idents := C.create(); |
1224 | |||
7983 | leency | 1225 | UTILS.SetBitDepth(TARGETS.BitDepth, TARGETS.RealSize = 8); |
7597 | akron1 | 1226 | |
7983 | leency | 1227 | program.options := options; |
7597 | akron1 | 1228 | |
7983 | leency | 1229 | CASE TARGETS.OS OF |
9847 | akron1 | 1230 | |TARGETS.osWIN32: program.sysflags := {sf_oberon, sf_windows, sf_stdcall, sf_cdecl, sf_ccall, sf_fastcall, sf_noalign} |
1231 | |TARGETS.osLINUX32: program.sysflags := {sf_oberon, sf_linux, sf_stdcall, sf_cdecl, sf_ccall, sf_fastcall, sf_noalign} |
||
1232 | |TARGETS.osKOS: program.sysflags := {sf_oberon, sf_stdcall, sf_cdecl, sf_ccall, sf_fastcall, sf_noalign} |
||
8859 | leency | 1233 | |TARGETS.osWIN64: program.sysflags := {sf_oberon, sf_windows, sf_win64, sf_systemv, sf_ccall, sf_noalign} |
1234 | |TARGETS.osLINUX64: program.sysflags := {sf_oberon, sf_linux, sf_win64, sf_systemv, sf_ccall, sf_noalign} |
||
7983 | leency | 1235 | |TARGETS.osNONE: program.sysflags := {sf_code} |
7693 | akron1 | 1236 | END; |
1237 | |||
7597 | akron1 | 1238 | program.recCount := -1; |
1239 | program.bss := 0; |
||
1240 | |||
7693 | akron1 | 1241 | program.units := LISTS.create(NIL); |
7597 | akron1 | 1242 | program.types := LISTS.create(NIL); |
1243 | program.procs := LISTS.create(NIL); |
||
1244 | |||
8097 | maxcodehac | 1245 | program.stTypes.tINTEGER := enterType(tINTEGER, TARGETS.WordSize, 0, NIL); |
1246 | program.stTypes.tBYTE := enterType(tBYTE, 1, 0, NIL); |
||
1247 | program.stTypes.tCHAR := enterType(tCHAR, 1, 0, NIL); |
||
1248 | program.stTypes.tSET := enterType(tSET, TARGETS.WordSize, 0, NIL); |
||
1249 | program.stTypes.tBOOLEAN := enterType(tBOOLEAN, 1, 0, NIL); |
||
7693 | akron1 | 1250 | |
7983 | leency | 1251 | program.stTypes.tINTEGER.align := TARGETS.WordSize; |
1252 | program.stTypes.tBYTE.align := 1; |
||
1253 | program.stTypes.tCHAR.align := 1; |
||
1254 | program.stTypes.tSET.align := TARGETS.WordSize; |
||
1255 | program.stTypes.tBOOLEAN.align := 1; |
||
1256 | |||
1257 | IF TARGETS.BitDepth >= 32 THEN |
||
8097 | maxcodehac | 1258 | program.stTypes.tWCHAR := enterType(tWCHAR, 2, 0, NIL); |
1259 | program.stTypes.tCARD32 := enterType(tCARD32, 4, 0, NIL); |
||
7983 | leency | 1260 | program.stTypes.tWCHAR.align := 2; |
1261 | program.stTypes.tCARD32.align := 4 |
||
7693 | akron1 | 1262 | END; |
1263 | |||
7983 | leency | 1264 | IF TARGETS.RealSize # 0 THEN |
8097 | maxcodehac | 1265 | program.stTypes.tREAL := enterType(tREAL, TARGETS.RealSize, 0, NIL); |
9893 | akron1 | 1266 | IF TARGETS.OS = TARGETS.osLINUX32 THEN |
1267 | program.stTypes.tREAL.align := 4 |
||
1268 | ELSE |
||
1269 | program.stTypes.tREAL.align := TARGETS.RealSize |
||
1270 | END |
||
7983 | leency | 1271 | END; |
7693 | akron1 | 1272 | |
8097 | maxcodehac | 1273 | program.stTypes.tSTRING := enterType(tSTRING, TARGETS.WordSize, 0, NIL); |
1274 | program.stTypes.tNIL := enterType(tNIL, TARGETS.WordSize, 0, NIL); |
||
1275 | program.stTypes.tNONE := enterType(tNONE, 0, 0, NIL); |
||
1276 | program.stTypes.tANYREC := enterType(tRECORD, 0, 0, NIL); |
||
7597 | akron1 | 1277 | program.stTypes.tANYREC.closed := TRUE; |
1278 | |||
8097 | maxcodehac | 1279 | createSysUnit |
7597 | akron1 | 1280 | END create; |
1281 | |||
1282 | |||
7983 | leency | 1283 | END PROG.=>> |