9df3961d6c067c22ccc57a3672d525ed4631c20b
3 IMPORT Kernel, Files, Log, Strings, DswOpts, DswProcs, DswDocuments, DevCPM, DevCPT, DevCPR, DevCPS;
5 CONST
11 (* symbol values *)
28 (* module state flags *)
31 (* procesor types *)
34 (* operation system types *)
37 (* compiler types *)
40 (* internal linker types *)
48 TYPE
55 next: Selector
69 VAR
81 (* --------- options --------- *)
85 BEGIN
90 RETURN i
95 BEGIN
109 ELSE
111 END
116 BEGIN
122 ELSE
124 END
129 BEGIN
137 RETURN t
142 BEGIN
154 END
155 ELSE
157 END
162 BEGIN
166 x := def
168 RETURN x
173 BEGIN
175 RETURN p
183 BEGIN
186 ELSE
195 END
200 BEGIN
203 ELSE
209 pars := p
214 BEGIN
220 term := ch; ch := s[i]; INC(i);
221 WHILE (ch # term) & (ch # 0X) DO
222 AddChar(ch); ch := s[i]; INC(i)
223 END;
224 IF ch # 0X THEN ch := s[i]; INC(i)
226 END
229 IF ch # 0X THEN AddLine END
230 ELSE
231 AddChar(ch); ch := s[i]; INC(i)
232 END
233 END;
234 RETURN pars
235 END ToStringList;
237 PROCEDURE Help;
238 BEGIN
252 (*
255 *)
260 (*
262 *)
266 Log.String(' -U ident Remove preprocessor selector'); Log.Ln;
269 Kernel.Quit(1)
270 END Help;
272 PROCEDURE Version;
273 BEGIN
274 Log.String(version); Log.Ln;
275 Kernel.Quit(0)
276 END Version;
278 PROCEDURE ParseTargetOpts;
279 VAR s: DswOpts.String;
280 BEGIN
283 s := DswOpts.str;
284 Strings.ToLower(s, s);
289 END
291 s := DswOpts.str;
292 Strings.ToLower(s, s);
301 END
303 s := DswOpts.str;
304 Strings.ToLower(s, s);
308 END
310 s := DswOpts.str;
311 Strings.ToLower(s, s);
314 END
318 END
319 END ParseTargetOpts;
321 PROCEDURE ParseCommandOpts;
322 BEGIN
329 END
330 END ParseCommandOpts;
332 PROCEDURE ParseExternalOpts;
333 BEGIN
340 END
341 END ParseExternalOpts;
343 PROCEDURE ParseArgs;
344 BEGIN
345 exe := NIL; auto := FALSE; jobs := 1; def.next := NIL; mno := 0; rno := 0;
346 processor := anymach; os := anyos; compiler := anycp;
347 LOOP
362 | 0X: EXIT
363 END
364 END;
365 END ParseArgs;
367 PROCEDURE CheckParams;
368 BEGIN
369 IF compiler = anycp THEN
371 ELSIF compiler = cpnative THEN
372 IF processor = anymach THEN
374 ELSIF processor # mach386 THEN
376 END
377 END;
378 IF (compiler = cpfront) & (linker # anyint) THEN
380 END;
381 IF (compiler = cpfront) & (exe # NIL) THEN
383 END;
384 IF (exe # NIL) & (compiler = cpnative) & (linker = anyint) THEN
386 END;
387 IF (linker = dev2) & (os = anyos) THEN
389 END;
392 END;
393 IF cpcExe = NIL THEN
396 END
397 END;
398 IF cplExe = NIL THEN
400 END
401 END CheckParams;
403 (* --------- loader --------- *)
405 PROCEDURE Import (m: Module; IN name: DevCPT.Name);
406 VAR i, j: INTEGER; imp: Module;
407 BEGIN
408 ASSERT(m # NIL, 20);
414 ELSE
416 i := 0; (* find module in local list *)
417 WHILE (i < m.mno) & (m.imp[i].name$ # name$) DO INC(i) END;
418 IF i >= m.mno THEN
419 j := 0; (* find module in global list *)
420 WHILE (j < mno) & (modList[j].name$ # name$) DO INC(j) END;
421 IF j >= mno THEN
422 NEW(imp); imp.name := name$; imp.selectors := CopySelectorList(m.selectors);
423 modList[mno] := imp; INC(mno)
424 ELSE
425 imp := modList[j]
426 END;
427 m.imp[m.mno] := imp; INC(m.mno)
428 ELSE DevCPM.err(1)
429 END
430 END;
431 IF debugImport THEN Log.Ln END;
432 END Import;
434 PROCEDURE ParseModule (m: Module);
435 VAR sym: BYTE; SelfName, impName, aliasName: DevCPT.Name;
437 PROCEDURE err (n: SHORTINT);
438 BEGIN DevCPM.err(n)
439 END err;
441 PROCEDURE CheckSym(s: SHORTINT);
442 BEGIN
443 IF sym = s THEN DevCPS.Get(sym) ELSE DevCPM.err(s) END
444 END CheckSym;
446 BEGIN
448 DevCPS.Init; DevCPS.Get(sym);
449 IF sym = module THEN DevCPS.Get(sym) ELSE err(16) END;
450 IF sym = ident THEN
451 SelfName := DevCPS.name$; DevCPS.Get(sym);
452 IF sym = lbrak THEN
453 INCL(DevCPM.options, DevCPM.interface); DevCPS.Get(sym);
454 IF sym = eql THEN DevCPS.Get(sym)
455 ELSE INCL(DevCPM.options, DevCPM.noCode)
456 END;
457 IF sym = string THEN INCL(m.flags, library); DevCPS.Get(sym)
458 ELSE err(string)
459 END;
460 CheckSym(rbrak)
461 END;
462 CheckSym(semicolon);
463 IF sym = import THEN DevCPS.Get(sym);
464 LOOP
465 IF sym = ident THEN
466 aliasName := DevCPS.name$; impName := aliasName$; DevCPS.Get(sym);
467 IF sym = becomes THEN DevCPS.Get(sym);
468 IF sym = ident THEN impName := DevCPS.name$; DevCPS.Get(sym) ELSE err(ident) END
469 END;
470 Import(m, impName)
471 ELSE err(ident)
472 END;
473 IF sym = comma THEN DevCPS.Get(sym)
474 ELSIF sym = ident THEN err(comma)
475 ELSE EXIT
476 END
477 END;
478 CheckSym(semicolon)
479 END
480 ELSE err(ident)
481 END;
482 DevCPS.str := NIL
483 END ParseModule;
485 PROCEDURE CheckModule (m: Module; source: String; OUT ok: BOOLEAN);
486 VAR s: Selector;
487 BEGIN
488 DevCPM.Init(source);
489 (*
490 DevCPM.symList := m.insym;
491 DevCPM.codePath := m.outcode;
492 DevCPM.symPath := m.outsym;
493 *)
494 DevCPM.name := m.name$;
495 (*
496 IF m.found THEN INCL(DevCPM.options, DevCPM.comAware) END;
497 IF errorTrap IN m.opts THEN INCL(DevCPM.options, DevCPM.trap) END;
498 IF oberon IN m.opts THEN INCL(DevCPM.options, DevCPM.oberon) END;
499 *)
500 DevCPR.Init;
501 s := m.selectors.next;
502 WHILE s # NIL DO
503 DevCPR.Set(s.name, s.value);
504 s := s.next
505 END;
506 ParseModule(m);
507 DevCPR.Check;
508 ok := DevCPM.noerr;
509 DevCPR.Close;
510 DevCPM.InsertMarks;
511 DevCPM.Close;
512 Kernel.FastCollect
513 END CheckModule;
515 PROCEDURE GetSource (IN modName: ARRAY OF CHAR; OUT path: Files.Name; OUT s: String);
517 VAR dir, name: Files.Name; loc: Files.Locator;
518 text: DswDocuments.Model; r: DswDocuments.Reader; i, res: INTEGER;
520 PROCEDURE MakePath (dir, name: Files.Name; type: Files.Type; OUT path: Files.Name);
521 BEGIN
525 END;
526 Kernel.MakeFileName(path, type)
527 END MakePath;
529 BEGIN
531 Kernel.SplitName(modName, dir, name);
532 loc := Files.dir.This(dir).This(modDir);
533 (* --> Kernel.MakeFileName(name, Kernel.docType); <-- *)
536 IF text = NIL THEN
541 loc := Files.dir.This(sysDir).This(modDir);
543 IF text = NIL THEN
546 IF text = NIL THEN
548 END
549 END
550 END
551 END;
552 IF text # NIL THEN
553 NEW(s, text.Length() + 1);
554 IF s # NIL THEN
555 r := text.NewReader(NIL);
556 FOR i := 0 TO text.Length() - 1 DO
557 r.Read; s[i] := r.char
558 END
559 END
560 END
561 END GetSource;
563 PROCEDURE Trace (m, parent: Module; VAR lno: INTEGER);
564 VAR i: INTEGER;
565 BEGIN
566 IF ~(trace IN m.flags) THEN
567 INCL(m.flags, trace);
568 FOR i := 0 TO m.mno - 1 DO
569 Trace(m.imp[i], m, lno);
570 m.depth := MAX(m.depth, m.imp[i].depth + 1)
571 END;
572 IF ~(imported IN m.flags) THEN
573 INCL(m.flags, imported);
574 lnkList[lno] := m;
575 INC(lno)
576 END;
577 EXCL(m.flags, trace)
578 ELSE
580 END
581 END Trace;
583 PROCEDURE Sort;
584 VAR i, j: INTEGER; m: Module;
585 BEGIN
586 ASSERT((mno = 0) OR (lnkList[0] # NIL), 20);
587 cmpList := lnkList;
588 i := 1;
589 WHILE i < mno DO
590 m := cmpList[i];
591 j := i - 1;
592 WHILE (j >= 0) & (cmpList[j].depth > m.depth) DO
593 cmpList[j + 1] := cmpList[j];
594 DEC(j)
595 END;
596 cmpList[j + 1] := m;
597 INC(i)
598 END
599 END Sort;
601 PROCEDURE CheckDeps;
602 VAR i, j, num: INTEGER; m: Module; s: String; ok: BOOLEAN;
603 BEGIN
604 i := 0; rno := mno;
605 WHILE (err = 0) & (i < mno) DO
606 m := modList[i];
607 GetSource(m.name$, m.path, s);
608 IF s # NIL THEN
609 CheckModule(m, s, ok);
610 IF ~ok THEN INC(err) END
611 ELSE
613 END;
614 INC(i)
615 END;
616 num := 0;
617 FOR i := 0 TO rno - 1 DO
618 Trace(modList[i], modList[i], num)
619 END;
620 ASSERT((err # 0) OR (num = mno), 100);
621 Sort;
622 IF debugOrder THEN
624 FOR i := 0 TO mno - 1 DO
626 END
627 END
628 END CheckDeps;
630 PROCEDURE IsCompiled (m: Module): BOOLEAN;
631 CONST target = {hasSym, hasObj};
632 VAR i: INTEGER; ready: BOOLEAN;
633 BEGIN
634 ASSERT(m # NIL, 20);
635 i := 0;
636 ready := ~(hasErrors IN m.flags) & (m.flags * target = target);
637 WHILE ready & (i < m.mno) DO
638 ready := IsCompiled(m.imp[i]);
639 INC(i)
640 END;
641 RETURN ready
642 END IsCompiled;
644 PROCEDURE Ready (m: Module): BOOLEAN;
645 CONST target = {hasSym, hasObj};
646 VAR i: INTEGER; ready: BOOLEAN;
647 BEGIN
648 i := 0;
649 ready := ~(hasErrors IN m.flags) & (m.flags * target # target) & (m.worker = NIL);
650 WHILE ready & (i < m.mno) DO
651 ready := IsCompiled(m.imp[i]);
652 INC(i)
653 END;
654 RETURN ready
655 END Ready;
657 PROCEDURE PutParams (w: DswProcs.Process; p: StringList);
658 VAR i: INTEGER;
659 BEGIN
660 ASSERT(w # NIL, 20);
662 IF p # NIL THEN
664 w.PutParam(p[0]);
665 FOR i := 1 TO LEN(p) - 1 DO
667 w.PutParam(p[i])
668 END;
670 END;
671 IF debugArgs THEN Log.Ln END
672 END PutParams;
674 PROCEDURE ExecuteCompiler (m: Module): DswProcs.Process;
675 VAR w: DswProcs.Process; ok: BOOLEAN;
676 BEGIN
677 ASSERT(m # NIL, 20);
679 ASSERT(m.worker = NIL, 22);
680 w := DswProcs.dir.New();
681 w.Program(cpcExe);
683 PutParams(w, cpcArgs);
684 CASE compiler OF
685 | cpfront:
688 | cpnative:
691 END;
692 CASE processor OF
693 | mach386:
696 | mach68k:
699 ELSE
702 END;
703 CASE os OF
704 | anyos:
711 | linux:
718 | freebsd:
726 | openbsd:
734 | win32:
742 | cygwin:
750 | darwin:
758 END;
759 CASE linker OF
760 | dev2:
762 ELSE
764 END;
765 w.PutParam(m.path);
766 w.Execute(ok);
767 IF ok THEN
769 ELSE
770 w := NIL
771 END;
772 RETURN w
773 END ExecuteCompiler;
775 PROCEDURE Compile;
776 VAR i, j, num: INTEGER; ok: BOOLEAN; m: Module; w: DswProcs.Process;
777 BEGIN
778 IF mno = 0 THEN RETURN END;
779 num := 0; j := 0;
780 WHILE (err = 0) & (num < mno) OR (j > 0) DO
781 i := 0;
782 WHILE (err = 0) & (i < mno) & (j < jobs) DO
783 m := cmpList[i];
784 IF Ready(m) THEN
785 w := ExecuteCompiler(m);
787 IF w # NIL THEN
789 m.worker := w;
790 INC(j)
791 ELSE
793 INCL(m.flags, hasErrors);
794 INC(err)
795 END;
796 IF debugJobs THEN Log.Ln END
797 END;
798 INC(i)
799 END;
800 WHILE (err = 0) & (j >= jobs) OR (j > 0) DO
801 i := 0;
802 WHILE (j > 0) & (i < mno) DO
803 m := cmpList[i];
804 w := m.worker;
805 IF (w # NIL) & w.IsTerminated() THEN
807 IF w.Result() = 0 THEN
808 INCL(m.flags, hasObj);
809 INCL(m.flags, hasSym);
810 INC(num)
811 ELSE
812 INCL(m.flags, hasErrors);
813 INC(err)
814 END;
815 m.worker := NIL;
816 DEC(j)
817 END;
818 INC(i)
819 END
820 END
821 END
822 END Compile;
824 PROCEDURE LinkDev2;
825 VAR p: DswProcs.Process; i, res: INTEGER; ok: BOOLEAN;
826 BEGIN
828 ASSERT(processor = mach386, 21);
829 ASSERT(compiler = cpnative, 22);
830 p := DswProcs.dir.New();
831 p.Program(cplExe);
832 IF os # anyos THEN
834 CASE os OF
840 END
841 END;
849 p.PutParam(exe);
850 PutParams(p, cplArgs);
851 i := 0;
852 WHILE i < mno DO
853 IF ~(library IN lnkList[i].flags) THEN
854 p.PutParam(lnkList[i].name$)
855 END;
856 INC(i)
857 END;
858 p.Execute(ok);
859 IF ok THEN
861 res := p.Result();
862 IF res # 0 THEN
864 INC(err)
865 END
866 ELSE
868 INC(err)
869 END
870 END LinkDev2;
872 PROCEDURE Link;
873 BEGIN
874 IF exe # NIL THEN
875 CASE linker OF
876 | anyint: (* do not link *)
877 | dev2: LinkDev2
878 END
879 END
880 END Link;
882 PROCEDURE Main;
883 VAR m: Module; s: Selector; p: DswProcs.Process; ok: BOOLEAN; i, res: INTEGER;
884 BEGIN
885 IF Kernel.trapCount = 0 THEN
886 ParseArgs;
887 IF err = 0 THEN
888 CheckParams;
889 IF err = 0 THEN
890 CheckDeps;
891 IF err = 0 THEN
892 Compile;
893 IF err = 0 THEN
894 Link
895 END
896 END
897 END
898 END
899 ELSE INC(err)
900 END;
901 IF err = 0 THEN Kernel.Quit(0)
902 ELSE Kernel.Quit(1)
903 END;
904 END Main;
906 BEGIN
907 NEW(def);
908 Kernel.Start(Main)
909 END DswMakeMain.